Skip to content

Commit 1d082a6

Browse files
committed
feat: Cedar policy gate, GitLab CI template, telemetry, VS Code extension build, interceptor SDK docs
- OSS-3: Add opt-in CLI telemetry (AI_BOM_TELEMETRY=true) - OSS-4: Cedar policy gate script (scripts/cedar-gate.py) - OSS-14: Enhanced action.yml with cedar-policy-file and policy-gate inputs - OSS-15: GitLab CI template (templates/gitlab-ci-ai-bom.yml) - OSS-1: VS Code extension built and packaged (ai-bom-scanner-0.1.0.vsix) - OSS-13: Universal interceptor SDK documentation (docs/interceptor-sdks.md) - Updated CI integration docs with full GitLab + Cedar sections
1 parent ce55398 commit 1d082a6

24 files changed

+7254
-21
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Publish VS Code Extension
2+
on:
3+
push:
4+
tags: ['vscode-v*']
5+
jobs:
6+
publish:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v4
10+
- uses: actions/setup-node@v4
11+
with:
12+
node-version: 20
13+
- run: cd vscode-extension && npm ci
14+
- run: cd vscode-extension && npm run compile
15+
- run: cd vscode-extension && npx @vscode/vsce package
16+
- run: cd vscode-extension && npx @vscode/vsce publish
17+
env:
18+
VSCE_PAT: ${{ secrets.VSCE_PAT }}

action.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ inputs:
3232
description: "Scanning depth: quick (pattern-matching only), standard (all scanners), deep (standard + AST analysis)"
3333
required: false
3434
default: "standard"
35+
cedar-policy-file:
36+
description: "Path to a Cedar policy file for policy evaluation (optional)"
37+
required: false
38+
default: ""
39+
cedar-entities-file:
40+
description: "Path to a Cedar entities file for additional entity context (optional)"
41+
required: false
42+
default: ""
43+
policy-gate:
44+
description: "Enable Cedar policy gate evaluation (requires cedar-policy-file)"
45+
required: false
46+
default: "false"
3547

3648
runs:
3749
using: "composite"
@@ -80,3 +92,34 @@ runs:
8092
uses: github/codeql-action/upload-sarif@v3
8193
with:
8294
sarif_file: ${{ steps.scan.outputs.sarif_file || inputs.output }}
95+
96+
# ── Cedar Policy Gate ───────────────────────────
97+
- name: Generate JSON for policy evaluation
98+
id: policy-scan
99+
if: ${{ inputs.policy-gate == 'true' && inputs.cedar-policy-file != '' }}
100+
shell: bash
101+
run: |
102+
echo "Running supplementary JSON scan for Cedar policy evaluation..."
103+
ARGS="scan ${{ inputs.path }} --format json --quiet -o ai-bom-policy-results.json"
104+
105+
if [ "${{ inputs.scan-level }}" = "deep" ]; then
106+
ARGS="$ARGS --deep"
107+
fi
108+
109+
ai-bom $ARGS
110+
echo "policy_results=ai-bom-policy-results.json" >> "$GITHUB_OUTPUT"
111+
112+
- name: Evaluate Cedar policy gate
113+
if: ${{ inputs.policy-gate == 'true' && inputs.cedar-policy-file != '' }}
114+
shell: bash
115+
run: |
116+
echo "Evaluating Cedar policy: ${{ inputs.cedar-policy-file }}"
117+
118+
GATE_ARGS="${{ steps.policy-scan.outputs.policy_results }} ${{ inputs.cedar-policy-file }}"
119+
120+
# Write violations to GitHub Actions job summary
121+
if [ -n "$GITHUB_STEP_SUMMARY" ]; then
122+
GATE_ARGS="$GATE_ARGS --summary $GITHUB_STEP_SUMMARY"
123+
fi
124+
125+
python3 "${{ github.action_path }}/scripts/cedar-gate.py" $GATE_ARGS

docs/ci-integration.md

Lines changed: 239 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
# CI/CD Integration
22

3+
AI-BOM integrates into your CI/CD pipeline to continuously discover and inventory AI/LLM components in your codebase. Supported platforms include GitHub Actions (native action) and GitLab CI (reusable template).
4+
5+
---
6+
37
## GitHub Actions
48

9+
### Quick Start
10+
511
```yaml
612
name: AI-BOM Scan
713
on: [push, pull_request]
@@ -21,24 +27,246 @@ jobs:
2127
fail-on: high
2228
```
2329
30+
### Action Inputs
31+
32+
| Input | Description | Default |
33+
|-------|-------------|---------|
34+
| `path` | Directory to scan | `.` |
35+
| `format` | Output format (`sarif`, `cyclonedx`, `spdx`, `table`, `html`, `markdown`, `csv`) | `table` |
36+
| `output` | Output file path (prints to stdout if not set) | |
37+
| `fail-on` | Fail if any component meets this severity (`critical`, `high`, `medium`, `low`) | |
38+
| `scan-level` | Scanning depth: `quick`, `standard`, or `deep` | `standard` |
39+
| `cedar-policy-file` | Path to a Cedar policy file for policy evaluation | |
40+
| `cedar-entities-file` | Path to a Cedar entities file for additional context | |
41+
| `policy-gate` | Enable Cedar policy gate evaluation (`true`/`false`) | `false` |
42+
43+
### SARIF Upload to GitHub Security
44+
45+
When `format: sarif`, scan results are automatically uploaded to GitHub Code Scanning (requires `security-events: write` permission):
46+
47+
```yaml
48+
- uses: trusera/ai-bom@v2
49+
with:
50+
format: sarif
51+
output: ai-bom-results.sarif
52+
scan-level: deep
53+
```
54+
55+
### Cedar Policy Gate
56+
57+
The Cedar policy gate evaluates scan results against a Cedar-like policy file, enabling fine-grained control over which AI components are permitted in your codebase. See the [Policy Enforcement](#cedar-policy-format) section below for the policy file format.
58+
59+
```yaml
60+
- uses: trusera/ai-bom@v2
61+
with:
62+
format: table
63+
scan-level: deep
64+
policy-gate: "true"
65+
cedar-policy-file: ".cedar/ai-policy.cedar"
66+
```
67+
68+
When a policy violation is detected, the action:
69+
1. Exits with a non-zero code (fails the pipeline)
70+
2. Prints a detailed violation table to the console
71+
3. Writes a formatted violation report to the GitHub Actions job summary
72+
73+
---
74+
2475
## GitLab CI
2576

77+
### Quick Start
78+
79+
Include the AI-BOM template in your `.gitlab-ci.yml`:
80+
81+
```yaml
82+
include:
83+
- remote: 'https://raw.githubusercontent.com/Trusera/ai-bom/main/templates/gitlab-ci-ai-bom.yml'
84+
```
85+
86+
This adds an `ai-bom-scan` job to the `security` stage that runs on merge requests and pushes to the default branch.
87+
88+
### Local Include
89+
90+
To pin the template to a specific version, copy it into your repository:
91+
92+
```yaml
93+
include:
94+
- local: '.gitlab/ci/ai-bom.yml'
95+
```
96+
97+
### Variable Reference
98+
99+
| Variable | Description | Default |
100+
|----------|-------------|---------|
101+
| `AI_BOM_VERSION` | AI-BOM package version to install | `latest` |
102+
| `AI_BOM_SCAN_PATH` | Directory to scan | `.` |
103+
| `AI_BOM_FORMAT` | Output format (`sarif`, `cyclonedx`, `spdx`, `json`, `csv`, `html`, `markdown`, `table`) | `sarif` |
104+
| `AI_BOM_FAIL_ON` | Fail if any component meets this severity (`critical`, `high`, `medium`, `low`) | _(empty = no threshold)_ |
105+
| `AI_BOM_DEEP_SCAN` | Enable deep scanning with AST analysis (`true`/`false`) | `false` |
106+
| `AI_BOM_POLICY_FILE` | Path to a Cedar policy file (enables the policy gate job) | _(empty = disabled)_ |
107+
| `AI_BOM_CEDAR_GATE_URL` | URL to the cedar-gate.py script | GitHub raw URL |
108+
109+
### Example: Basic SARIF Scan
110+
111+
The default configuration generates a SARIF report that integrates with GitLab's SAST results view:
112+
113+
```yaml
114+
include:
115+
- remote: 'https://raw.githubusercontent.com/Trusera/ai-bom/main/templates/gitlab-ci-ai-bom.yml'
116+
```
117+
118+
No additional configuration needed. Results appear in the GitLab Security Dashboard.
119+
120+
### Example: Fail on High Severity
121+
122+
```yaml
123+
include:
124+
- remote: 'https://raw.githubusercontent.com/Trusera/ai-bom/main/templates/gitlab-ci-ai-bom.yml'
125+
126+
variables:
127+
AI_BOM_FAIL_ON: "high"
128+
AI_BOM_DEEP_SCAN: "true"
129+
```
130+
131+
### Example: Cedar Policy Gate
132+
133+
```yaml
134+
include:
135+
- remote: 'https://raw.githubusercontent.com/Trusera/ai-bom/main/templates/gitlab-ci-ai-bom.yml'
136+
137+
variables:
138+
AI_BOM_POLICY_FILE: ".cedar/ai-policy.cedar"
139+
AI_BOM_DEEP_SCAN: "true"
140+
```
141+
142+
When `AI_BOM_POLICY_FILE` is set, the template automatically enables a second job (`ai-bom-policy-gate`) that runs after the scan.
143+
144+
### Example: CycloneDX SBOM Output
145+
26146
```yaml
27-
ai-bom-scan:
28-
image: ghcr.io/trusera/ai-bom:latest
29-
script:
30-
- ai-bom scan . --format sarif -o ai-bom.sarif --quiet
31-
artifacts:
32-
reports:
33-
sast: ai-bom.sarif
147+
include:
148+
- remote: 'https://raw.githubusercontent.com/Trusera/ai-bom/main/templates/gitlab-ci-ai-bom.yml'
149+
150+
variables:
151+
AI_BOM_FORMAT: "cyclonedx"
152+
```
153+
154+
The report artifact (`ai-bom-report.cdx.json`) is available for download for 30 days.
155+
156+
### Pipeline Badge
157+
158+
Add a badge to your README to show scan status:
159+
160+
```markdown
161+
[![AI-BOM Scan](https://gitlab.com/<namespace>/<project>/badges/<branch>/pipeline.svg)](https://gitlab.com/<namespace>/<project>/-/pipelines)
34162
```
35163

36-
## Policy Enforcement
164+
---
165+
166+
## Cedar Policy Format
167+
168+
The Cedar policy gate uses a simplified Cedar-like syntax. Each rule is a `forbid` statement that blocks deployment when conditions match.
169+
170+
### Supported Conditions
171+
172+
| Field | Type | Description |
173+
|-------|------|-------------|
174+
| `resource.severity` | string | Component severity: `critical`, `high`, `medium`, `low`, `info` |
175+
| `resource.provider` | string | AI provider name (e.g., `DeepSeek`, `OpenAI`) |
176+
| `resource.component_type` | string | Component type (e.g., `llm-api`, `embedding`, `agent-framework`) |
177+
| `resource.risk_score` | number | Risk score from 0 to 100 |
178+
| `resource.name` | string | Component name |
179+
180+
### Supported Operators
181+
182+
`==`, `!=`, `>`, `>=`, `<`, `<=`
183+
184+
Severity comparisons use ordinal ranking: `critical(4) > high(3) > medium(2) > low(1) > info(0)`.
185+
186+
### Example Policy File
187+
188+
```cedar
189+
// .cedar/ai-policy.cedar
190+
// Block all critical-severity components from deployment
191+
forbid (
192+
principal,
193+
action == Action::"deploy",
194+
resource
195+
) when {
196+
resource.severity == "critical"
197+
};
198+
199+
// Block a specific provider
200+
forbid (
201+
principal,
202+
action == Action::"deploy",
203+
resource
204+
) when {
205+
resource.provider == "DeepSeek"
206+
};
207+
208+
// Block components with risk score above threshold
209+
forbid (
210+
principal,
211+
action == Action::"deploy",
212+
resource
213+
) when {
214+
resource.risk_score > 75
215+
};
216+
217+
// Block high-severity LLM API integrations
218+
forbid (
219+
principal,
220+
action == Action::"deploy",
221+
resource
222+
) when {
223+
resource.component_type == "llm-api"
224+
resource.severity == "high"
225+
};
226+
```
227+
228+
### Violation Report
229+
230+
When a policy violation is detected, the gate produces a table like:
231+
232+
```
233+
## Cedar Policy Gate - FAILED
234+
235+
**2 violation(s) found**
236+
237+
| # | Component | Type | Rule | Actual Value |
238+
|---|-----------|------|------|--------------|
239+
| 1 | openai-chat | llm-api | `resource.severity == "critical"` | critical |
240+
| 2 | deepseek-v3 | llm-api | `resource.provider == "DeepSeek"` | DeepSeek |
241+
```
242+
243+
---
244+
245+
## Policy Enforcement (Legacy)
246+
247+
### Severity Threshold
248+
249+
Fail CI if findings meet a severity threshold:
37250

38251
```bash
39-
# Fail if any critical findings
40252
ai-bom scan . --fail-on critical --quiet
253+
```
254+
255+
### YAML Policy File
256+
257+
Create a YAML policy file for basic threshold control:
41258

42-
# Use a policy file
43-
ai-bom scan . --policy policy.yml --quiet
259+
```yaml
260+
# policy.yml
261+
max_risk_score: 75
262+
blocked_providers:
263+
- "DeepSeek"
264+
require_declared: true
265+
max_components: 50
44266
```
267+
268+
```bash
269+
ai-bom scan . --policy policy.yml
270+
```
271+
272+
For more advanced rule-based policies, use the Cedar policy gate described above.

0 commit comments

Comments
 (0)