Skip to content

Commit 4eb7da0

Browse files
author
tpilli
committed
support to run on other repos
1 parent ec72f2c commit 4eb7da0

4 files changed

Lines changed: 169 additions & 4 deletions

File tree

.github/workflows/ai-sast.yml

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Run AI-SAST in YOUR repo on YOUR runners. Your code never runs on ai-sast infrastructure.
2+
#
3+
# Required: copy this file as .github/workflows/ai-sast.yml, add secrets:
4+
# GOOGLE_CLOUD_PROJECT, GOOGLE_CREDENTIALS
5+
# Default: checks out rivian/ai-sast. Optional: set AI_SAST_REPO (e.g. for a fork);
6+
# AI_SAST_BASE_BRANCH (default: main); AI_SAST_REF (default: main); runs-on for self-hosted.
7+
8+
name: AI-SAST
9+
10+
on:
11+
pull_request:
12+
workflow_dispatch:
13+
14+
permissions:
15+
contents: read
16+
pull-requests: write
17+
18+
jobs:
19+
ai-sast:
20+
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && (github.base_ref == vars.AI_SAST_BASE_BRANCH || (vars.AI_SAST_BASE_BRANCH == '' && github.base_ref == 'main')))
21+
runs-on: ubuntu-latest
22+
continue-on-error: true
23+
24+
env:
25+
GOOGLE_CLOUD_PROJECT: ${{ secrets.GOOGLE_CLOUD_PROJECT }}
26+
GOOGLE_LOCATION: us-central1
27+
GEMINI_MODEL: ${{ vars.GEMINI_MODEL || 'gemini-2.0-flash-exp' }}
28+
AI_SAST_SEVERITY: ${{ vars.AI_SAST_SEVERITY || 'critical,high' }}
29+
30+
steps:
31+
- name: Checkout repository
32+
uses: actions/checkout@v4
33+
with:
34+
fetch-depth: 0
35+
36+
- name: Checkout AI-SAST
37+
uses: actions/checkout@v4
38+
with:
39+
repository: ${{ vars.AI_SAST_REPO || 'rivian/ai-sast' }}
40+
path: ai-sast
41+
ref: ${{ vars.AI_SAST_REF || 'main' }}
42+
43+
- name: Set up Python 3.12
44+
uses: actions/setup-python@v5
45+
with:
46+
python-version: '3.12'
47+
48+
- name: Install dependencies
49+
run: pip install --upgrade pip && pip install -r ai-sast/requirements.txt
50+
51+
- name: Authenticate to Google Cloud
52+
uses: google-github-actions/auth@v2
53+
with:
54+
credentials_json: ${{ secrets.GOOGLE_CREDENTIALS }}
55+
56+
- name: Run AI-SAST PR Scan
57+
if: github.event_name == 'pull_request'
58+
id: scan
59+
run: PYTHONPATH=${{ github.workspace }}/ai-sast python -m src.main.pr_scan
60+
env:
61+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
62+
63+
- name: Run AI-SAST Full Scan
64+
if: github.event_name == 'workflow_dispatch'
65+
id: scan
66+
run: PYTHONPATH=${{ github.workspace }}/ai-sast python -m src.main.full_scan --max-workers 1
67+
env:
68+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
69+
70+
- name: Post PR Comment with Results
71+
if: always() && github.event_name == 'pull_request' && steps.scan.outcome != 'skipped'
72+
uses: actions/github-script@v7
73+
with:
74+
github-token: ${{ secrets.GITHUB_TOKEN }}
75+
script: |
76+
const fs = require('fs');
77+
if (!fs.existsSync('pr_comment.md')) {
78+
console.log('No pr_comment.md found');
79+
return;
80+
}
81+
const report = fs.readFileSync('pr_comment.md', 'utf8');
82+
if (!report || !report.trim()) {
83+
console.log('pr_comment.md is empty');
84+
return;
85+
}
86+
await github.rest.issues.createComment({
87+
owner: context.repo.owner,
88+
repo: context.repo.repo,
89+
issue_number: context.issue.number,
90+
body: report
91+
});
92+
console.log('PR comment posted');
93+
94+
- name: Upload PR scan reports
95+
if: always() && github.event_name == 'pull_request'
96+
uses: actions/upload-artifact@v4
97+
with:
98+
name: ai-sast-pr-scan-reports
99+
path: |
100+
ai_sast_pr_scan_report_*.html
101+
pr_comment.md
102+
retention-days: 30
103+
104+
- name: Upload full scan reports
105+
if: always() && github.event_name == 'workflow_dispatch'
106+
uses: actions/upload-artifact@v4
107+
with:
108+
name: ai-sast-full-scan-report
109+
path: |
110+
ai_sast_full_scan_report_*.html
111+
ai_sast_full_scan_report_*.txt
112+
retention-days: 30

README.md

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ python -m src.main.pr_scan
6060

6161
**For GitHub Actions:** Add these as repository secrets:
6262
- `GOOGLE_CLOUD_PROJECT`: Your GCP project ID
63-
- `GOOGLE_TOKEN`: Service account JSON
63+
- `GOOGLE_CREDENTIALS`: Service account JSON (used by the workflow’s Google auth step)
6464

6565
That's it! Workflows in `.github/workflows/` will run automatically.
6666

@@ -110,7 +110,7 @@ python -m src.core.scanner --repo https://github.com/user/repo.git --branch main
110110

111111
1. Add repository secrets (Settings → Secrets → Actions):
112112
- `GOOGLE_CLOUD_PROJECT`: Your GCP project ID
113-
- `GOOGLE_TOKEN`: Service account JSON
113+
- `GOOGLE_CREDENTIALS`: Service account JSON (required by the workflow’s Google Cloud auth step)
114114

115115
2. Workflows run automatically:
116116
- **PR Scan**: Scans changed files on pull requests
@@ -119,6 +119,20 @@ python -m src.core.scanner --repo https://github.com/user/repo.git --branch main
119119

120120
**That's it!** Results appear as PR comments and artifacts.
121121

122+
#### Using AI-SAST in another repository (runs in your repo, on your runners)
123+
124+
**Your code never runs on ai-sast infrastructure.** The workflow runs in your repo on your runners and checks out the ai-sast scanner at runtime—no submodule or copy required.
125+
126+
1. **Copy the workflow file** into your repo as `.github/workflows/ai-sast.yml`:
127+
[`.github/workflows/ai-sast.yml`](.github/workflows/ai-sast.yml)
128+
129+
2. **Add repository secrets** (Settings → Secrets and variables → Actions):
130+
`GOOGLE_CLOUD_PROJECT`, `GOOGLE_CREDENTIALS`
131+
132+
The workflow checks out **`rivian/ai-sast`** by default. **Optional:** set `AI_SAST_REPO` (e.g. for a fork); `AI_SAST_BASE_BRANCH` (default `main`); `runs-on: self-hosted` for your own runners. **Full scan:** Actions → “AI-SAST” → “Run workflow”.
133+
134+
📚 **Full integration guide:** [docs/INTEGRATION.md](docs/INTEGRATION.md)
135+
122136
### Optional: Feedback Loop
123137

124138
Developers can mark findings as true/false positives to improve accuracy over time. Feedback is automatically stored in SQLite.
@@ -166,7 +180,7 @@ export AI_SAST_CUSTOM_PROMPT="Focus on authentication vulnerabilities"
166180
| Variable | Description |
167181
|----------|-------------|
168182
| `GOOGLE_CLOUD_PROJECT` | Your GCP project ID |
169-
| `GOOGLE_TOKEN` | Service account JSON (for GitHub Actions) |
183+
| `GOOGLE_CREDENTIALS` | Repository secret: service account JSON (for GitHub Actions auth) |
170184

171185
### Optional Environment Variables
172186

docs/ARCHITECTURE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ Developer reviews PR comment
245245

246246
### Authentication
247247
- **Local Development:** `gcloud auth application-default login`
248-
- **GitHub Actions:** Service account JSON via `GOOGLE_TOKEN` secret
248+
- **GitHub Actions:** Service account JSON via `GOOGLE_CREDENTIALS` repository secret (workflow auth step)
249249
- **Ollama:** No authentication (local only)
250250

251251
### Secrets Management

docs/INTEGRATION.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Integrating AI-SAST into Your Repository
2+
3+
Run AI-SAST (PR scan + full scan) **in your repo on your runners**. The workflow checks out the ai-sast scanner at runtime—no submodule or manual copy. Your code never runs on ai-sast infrastructure.
4+
5+
## Required (2 steps)
6+
7+
### 1. Copy the workflow file
8+
9+
- **From this repo:** [`.github/workflows/ai-sast.yml`](../.github/workflows/ai-sast.yml)
10+
- **Save as:** `.github/workflows/ai-sast.yml` in **your** repository.
11+
12+
### 2. Add Google secrets
13+
14+
In your repository: **Settings → Secrets and variables → Actions → Secrets**
15+
16+
| Secret | Description |
17+
|--------|-------------|
18+
| `GOOGLE_CLOUD_PROJECT` | Your GCP project ID |
19+
| `GOOGLE_CREDENTIALS` | Service account JSON (full contents of the key file) |
20+
21+
The workflow checks out **`rivian/ai-sast`** by default. That’s it—PR scan runs on pull requests (when base branch matches); full scan runs when you click “Run workflow” in the Actions tab.
22+
23+
## Optional
24+
25+
- **Using a fork:** Set repository variable **`AI_SAST_REPO`** (e.g. `your-org/ai-sast`) to checkout your fork instead of `rivian/ai-sast`.
26+
- **Default branch for PR scan:** Add variable **`AI_SAST_BASE_BRANCH`** (e.g. `main`, `master`, `develop`). Default is `main` if unset.
27+
- **Scanner ref:** Add variable **`AI_SAST_REF`** (e.g. `main`, `v1.0`) to pin the ai-sast version. Default is `main`.
28+
- **Self-hosted runners:** In the workflow file, set `runs-on: self-hosted` (or your runner label).
29+
30+
## Running scans
31+
32+
- **PR scan**: Open a pull request that targets the branch set by `AI_SAST_BASE_BRANCH` (or `main`). The workflow runs and posts a comment with findings.
33+
- **Full scan**: Actions → **“AI-SAST”****“Run workflow”**.
34+
35+
## Troubleshooting
36+
37+
- **“repository not found” or checkout fails:** You may be using a fork; set `AI_SAST_REPO` to your `org/ai-sast`.
38+
- **No PR comment:** Check that the PR targets the branch set by `AI_SAST_BASE_BRANCH` (or `main`). Check the “Run AI-SAST PR Scan” step logs.
39+
- **Auth errors:** Ensure the service account has the “Vertex AI User” role and that `GOOGLE_CREDENTIALS` is the **full** JSON key (not a path).

0 commit comments

Comments
 (0)