[scanner-registry] Emit trivy JSON + mount workdir for relationship stamping - #270
Closed
Dyc0de wants to merge 4 commits into
Closed
[scanner-registry] Emit trivy JSON + mount workdir for relationship stamping#270Dyc0de wants to merge 4 commits into
Dyc0de wants to merge 4 commits into
Conversation
The trivy SBOM modules piped CycloneDX straight to stdout, which drops trivy's native dependency graph -- the post-processor had no way to tell a direct dependency from a transitive one. Run trivy once to `trivy-report.json`, then `trivy convert --format cyclonedx` that report to stdout, so the CycloneDX the post-processor consumes is unchanged while the JSON graph stays behind in the scan dir. `workdir: /app` makes the executor mount that dir into the post-processor container, and the bumped image is the build that reads the report and stamps `boost:relationship`. Relates to boostsecurityio/workspace#194 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The executor bind-mounts the scan dir AT the workdir
(boostsec-scanner-cli executor.py:273, `mounts = {str(srcdir): definition.workdir}`),
and the post-processor image installs itself under /app -- so `workdir: /app`
mounted the scan dir over the image's own entrypoint and the container died with
`exec: "boost-convert-trivy-sbom": executable file not found in $PATH`.
/scan collides with nothing and the post-processor reads trivy-report.json
relative to cwd, so the mount still does its job.
Relates to boostsecurityio/workspace#194
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`trivy image --format cyclonedx` defaults to SBOM-only, but `--format json` defaults to the vuln,secret scanners -- and `trivy convert` carries those findings into the CycloneDX. The rewrite therefore made trivy-sbom-image start reporting image vulnerabilities it never reported before (4 on alpine:3.19). `--scanners ""` restores SBOM-only; `--list-all-pkgs` keeps every package in the JSON report. Relationship data is independent of the scanner set, so language packages in an image still get stamped. Verified on alpine:3.19 with the pinned trivy 0.69.2: old and new both give 16 components / 0 vulnerabilities and are identical modulo trivy's per-run UUIDs; without `--scanners ""` the new pipeline yields 4 vulnerabilities. Relates to boostsecurityio/workspace#194 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The convert narration restated what the code plainly does. What's left is the two gotchas that guard silent, CI-invisible regressions: why workdir can't be /app, and why --scanners "" has to stay. Relates to boostsecurityio/workspace#194 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
Author
|
Superseded by #271 — moved to a same-repo branch on |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The trivy SBOM modules piped CycloneDX straight to stdout. CycloneDX drops trivy's native dependency graph, so the post-processor had no way to tell a direct dependency from a transitive one — the root cause of the "direct deps reported as transitive" bug.
What
boost-sca,trivy-sbomandtrivy-sbom-imagenow run trivy once totrivy-report.json, thentrivy convert --format cyclonedxthat report to stdout. The CycloneDX the post-processor consumes is unchanged; the JSON graph stays behind in the scan dir, whereworkdir: /appmakes the executor mount it into the post-processor container. The bumped post-processor image is the build that reads that report and stampsboost:relationship.Per module:
scanners/boostsecurityio/boost-sca/module.yaml— scan becomestrivy fs … --format=json --output=trivy-report.json; every other flag is untouched (cache dir,--license-full,--no-progress,--scanners vuln,--skip-version-check, the2>"$LOG"handling with bothcat "$LOG"lines andexit "$ec"). On success it runstrivy convert --quiet --format cyclonedx trivy-report.json. Post-processor gainsworkdir: /app, image →…boost-scanner-trivy-sbom:68831d5@sha256:2b7878a7….scanners/boostsecurityio/trivy-sbom/module.yaml— same three changes, keeping its${TRIVY_ADDITIONAL_ARGS}position.scanners/boostsecurityio/trivy-sbom-image/module.yaml—trivy image … --format json --output trivy-report.json … && trivy convert --quiet --format cyclonedx trivy-report.json, still one folded scalar. Sameworkdir: /app+ image bump.Two deliberate choices:
convertruns only when the scan succeeded (ec == 0for the fs modules,&&for the image module) — otherwise a failed scan surfaces as a confusing "trivy-report.json not found" instead of trivy's real error.--quietonconvertso its INFO lines don't land in$LOGand from there onto stdout, where the post-processor greps the "no language files" signal.Output equivalence
Verified with the module's own pinned trivy 0.69.2 (binary sha256-checked against the module's
MACOS_ARM64_SHA) against a realpoetry.lock: old command and new--format=json+convertboth emit 177627 bytes, and the documents are identical after dropping trivy's per-runserialNumber/timestampand normalizing its random non-purlbom-refUUIDs.Worth knowing: two runs of the old command are not byte-identical to each other either — those random UUIDs also reorder the
dependenciesarray. So the accurate invariant is "unchanged modulo trivy's own per-run randomness", not literal byte-equality.convertproduced no stderr and needed no network or DB pull.Relates to boostsecurityio/workspace#194
🤖 Generated with Claude Code