Emit SARIF
AIROM’s SARIF results are inventory, not alerts. A
hosted-llm result says
“this file references gpt-4.1,” not “this is a vulnerability.” That is why the
default level is note — see Levels.Document shape
scan.sarif (abridged)
tool.driver.semanticVersion and airom:tool.commit are the
same ToolInfo that airom version prints and that every AIBOM carries.
Rules: one per detector
Each distinct detector that produced an occurrence becomes one rule. TheruleId is the detector ID itself — stable, so a rule keeps its identity across
runs and releases.
a rule
name is the detector ID in UpperCamelCase — every non-alphanumeric character is
a word boundary, so rules/openai/model-literal becomes
RulesOpenaiModelLiteral. airom:method carries the detection method
(source-code-analysis, binary-analysis, manifest-analysis, …).
Rules are sorted by ID. Only detectors that actually fired appear — the rule list
describes the run, not the catalog. Use airom detectors list for the catalog.
Results: one per occurrence
A component seen at twelve call sites produces twelve results, each anchored to its own location. The component is the unit of inventory; the occurrence is the unit of a SARIF result.a result
airom:componentId (the graph anchor, shared by every
result for one component), airom:kind, airom:confidence and
airom:occurrence.confidence as JSON numbers, plus airom:provider,
airom:purl and airom:pickle.risk when known.
The scan-root application component produces no results — it is metadata, not a
finding. A whole-file sighting emits a physicalLocation with no region
rather than claiming line 0.
Results are ordered by component ID, then path, then line, then detector, so the
file is deterministic across runs.
Levels: note vs informational
- Default
- Strict
kind: "informational" results — they never appear
in the UI. level: "note" renders. The default is chosen so the output is
useful where it is actually consumed.level and omits kind; the
strict flag sets kind and omits level.
defaultConfiguration.level on each rule stays "note" in both modes.
--sarif-strict-kinds changes the encoding of results only.Risk results
Inventory results are informational, but artifact risks are not — they are the one thing in a SARIF projection meant to fail a review. Each risk becomes a dedicatedrisk/<slug> rule (e.g. risk/pickle-import) whose result carries a real
severity level — error for high, warning for medium — and a security-severity
property so GitHub Code Scanning files it under Security, not a note. A poisoned
checkpoint then surfaces as a security alert on the pull request that introduced it,
anchored at the artifact’s file:line.
These carry a severity
level regardless of --sarif-strict-kinds: a risk is a finding,
not an inventory fact, so it is never downgraded to kind: "informational".partialFingerprints
sha256(detectorID | componentID | path), lowercase hex.
Roots and provenance
originalUriBaseIds.SRCROOT anchors artifact URIs to a filesystem root. It is
emitted only when the target is a real path: always for a directory scan, and for
a repo scan only when the target is a local worktree.
For a remote repo there is no local root to anchor to, so SRCROOT is omitted.
Independently of that, whenever the scan knows a git remote — a local worktree
with a remote configured, or a remote URL — provenance travels as:
Unknowns are not results
A file AIROM could not fully process is not a finding — it is a gap in the scan, and it surfaces as a notification rather than being silently dropped or misfiled as a result.executionSuccessful is true for any completed scan, unknowns included. A scan
that finished is a scan that succeeded.
Upload to GitHub Code Scanning
1
Grant the workflow permission
security-events: write is required to upload SARIF.2
Scan and emit SARIF
Findings are not failures —
airom scan exits 0 no matter how much it finds,
so the upload step always runs.3
Upload the file
Use
github/codeql-action/upload-sarif..github/workflows/aibom.yml
--min-confidence 0.8 is worth setting for Code Scanning. Extension-only dataset
detection and keyword-only ai-config detection emit low-confidence (0.5–0.6)
results on general-purpose repositories; without the filter, that noise lands in
your security tab. See /concepts/confidence.Adding a gate
Uploading SARIF does not fail a build. To make a build fail on a policy, use--fail-on in the same run:
if: always() if you want the results even on a failing gate. See
/reference/cli for the --fail-on grammar and exit codes.