Add --uri-prefix flag for fleet SARIF aggregation
Problem
nboot audit --format sarif emits SARIF results whose
artifactLocation.uri is a path relative to --target:
"artifactLocation": { "uri": ".github/workflows/codeql.yml" }
This is correct for a single-repo audit, but breaks down when
auditing multiple repos and aggregating findings centrally — every
repo's README.md finding has the same URI, making it impossible
to tell which repo owns which finding from the SARIF alone.
This blocks the fleet conformance workflow that nboot audit
is positioned for (the headline use case in docs/reference/audit.md):
Fleet surveys — "which of our 100 repos still conform to the
security-scanning pack?"
Proposed fix
Add --uri-prefix STRING to audit_cmd. When set, every SARIF
artifactLocation.uri is prefixed (with / separator) so findings
disambiguate cleanly:
# In a fleet-runner script:
for repo in $(gh repo list myorg --json name -q '.[].name'); do
gh repo clone myorg/$repo /tmp/$repo
nboot audit --spec spec.json --pack security \
--target /tmp/$repo \
--format sarif \
--uri-prefix "$repo/" \
--output /tmp/aggregate.sarif.d/$repo.sarif
done
The aggregated dashboard now distinguishes
repo-a/.github/workflows/codeql.yml from
repo-b/.github/workflows/codeql.yml.
Implementation sketch
- Add CLI flag in
audit_cmd (default empty string → no prefix).
- Plumb through to
findings_to_sarif() as a kwarg.
- Apply the prefix to
artifact_uri BEFORE the SarifResult is
constructed, so the fingerprint hash naturally distinguishes
findings across repos. Don't apply it only in to_dict(), or
partialFingerprints.primaryLocationLineHash will collide
across repos and GitHub will dedupe legitimately-different
findings into one.
- Scope: SARIF only. No effect on
--format text, no effect
on nboot diff's unified-diff text output, no effect on
AuditFinding.message (which is for humans, not URIs).
Acceptance criteria
Effort
~1 hour including tests and doc.
Source
Bot review on PR #51 (Grippy audit.py:127 MEDIUM).
Add
--uri-prefixflag for fleet SARIF aggregationProblem
nboot audit --format sarifemits SARIF results whoseartifactLocation.uriis a path relative to--target:This is correct for a single-repo audit, but breaks down when
auditing multiple repos and aggregating findings centrally — every
repo's
README.mdfinding has the same URI, making it impossibleto tell which repo owns which finding from the SARIF alone.
This blocks the fleet conformance workflow that
nboot auditis positioned for (the headline use case in
docs/reference/audit.md):Proposed fix
Add
--uri-prefix STRINGtoaudit_cmd. When set, every SARIFartifactLocation.uriis prefixed (with/separator) so findingsdisambiguate cleanly:
The aggregated dashboard now distinguishes
repo-a/.github/workflows/codeql.ymlfromrepo-b/.github/workflows/codeql.yml.Implementation sketch
audit_cmd(default empty string → no prefix).findings_to_sarif()as a kwarg.artifact_uriBEFORE theSarifResultisconstructed, so the fingerprint hash naturally distinguishes
findings across repos. Don't apply it only in
to_dict(), orpartialFingerprints.primaryLocationLineHashwill collideacross repos and GitHub will dedupe legitimately-different
findings into one.
--format text, no effecton
nboot diff's unified-diff text output, no effect onAuditFinding.message(which is for humans, not URIs).Acceptance criteria
--uri-prefix myorg/foo/appears in every SARIF result'sartifactLocation.uri.are collapsed.
--uri-prefixmatches today's behaviour exactly(no prefix in artifact_uri, fingerprint identical to today).
partialFingerprints.primaryLocationLineHashdiffers forsame-rule-and-relative-path findings under different prefixes —
i.e., the prefix is incorporated into the fingerprint hash, not
added only in the rendered output.
--format textoutput is unchanged regardless of--uri-prefix.nboot diffis untouched (no new flag, no behaviour change).tests/test_audit.pyandtests/test_sarif.py,including a fingerprint-collision test (same rule + same
relative path + different prefix → different fingerprint).
docs/reference/audit.mdshowing the fleetfor repo in …; do …; donepattern.Effort
~1 hour including tests and doc.
Source
Bot review on PR #51 (Grippy
audit.py:127MEDIUM).