ReviewOS

also looking at this

craft-native/craft

Gate SBOM findings on whether they ship

#321
Merged glennmichael123 wants to merge fix/sbom-shipping-scope into main
5 files +230 -1

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

.github/workflows/ci.ymlmodified+1-1
Changes to .github/workflows/ci.yml
@@ -283,7 +283,7 @@ jobs:
283283 run: zig fmt --check src/ build.zig
284284
285285 - name: Test failure-safe vulnerability scanning
286 run: bun test scripts/scan-sbom.test.ts scripts/scan-release-artifacts.test.ts
286 run: bun test scripts/scan-sbom.test.ts scripts/scan-release-artifacts.test.ts scripts/sbom-scope.test.ts
287287
288288 - name: Audit Zig C imports
289289 run: bun run verify:cimports
.github/workflows/sbom.ymlmodified+6-0
Changes to .github/workflows/sbom.yml
@@ -129,6 +129,12 @@ jobs:
129129 env:
130130 CRAFT_FAIL_HIGH: ${{ inputs.enforce_high || false }}
131131
132 # Always on, unlike enforce_high. Fails when a High or Critical finding is
133 # not confined to paths that publish nothing, and prints the tooling
134 # inventory otherwise so the count stays visible rather than silent.
135 - name: Require High findings to be tooling-only
136 run: bun scripts/sbom-scope.ts scan-results/vulnerabilities.json
137
132138 - name: Upload scan results
133139 if: ${{ always() }}
134140 uses: actions/upload-artifact@v4
docs/VULNERABILITY_SCANNING.mdmodified+26-0
Changes to docs/VULNERABILITY_SCANNING.md
@@ -25,6 +25,32 @@ advisories. Native binary scanning records exact hashes and detected components,
2525but static Zig code may not be identifiable from the binary alone; retain the
2626full-source review.
2727
28## Shipping scope for SBOM findings
29
30The full-repository scan inventories the whole checkout, which includes the benchmark
31comparison apps and the development install. Every High finding in it today originates
32there: the Electron and Electrobun benchmark lockfiles, and the Go runtime compiled
33into the TypeScript compiler binary under `node_modules`.
34
35`scripts/sbom-scope.ts` decides by location. A High or Critical finding whose every
36recorded path lies under a prefix that publishes nothing — `/benchmarks/`,
37`/node_modules/`, `/examples/`, `/artifacts/`, `/.github/` — is tooling inventory, and
38is reported with its package list. Anything else fails the scan, including a finding
39with no recorded location, since an unlocatable High deserves review rather than a
40pass. A package appearing both in a benchmark and in Craft counts as Craft's.
41
42This runs unconditionally, unlike the `enforce_high` input, which remains available as
43a stricter opt-in that fails on any High regardless of where it sits.
44
45A path rule rather than a list of retained findings is deliberate: benchmark lockfiles
46and `node_modules` versions change constantly, so entries pinned to a package and
47version would go stale within days and the check guarding them would fire on every
48benchmark bump. Lockfile advisories are different — they are few and slow-moving — and
49they do use reviewed retentions, below.
50
51The shipped half of the division is `scripts/scan-release-artifacts.ts`, which scans
52the exact release archives with their resolved production dependencies.
53
2854## Reviewed advisory retention
2955
3056Lockfile advisories are decided rather than counted. `scripts/advisory-policy.ts`