Add opt-in Trivy container CVE scan to build-docker#112
Merged
Conversation
When scan_container is set, the build job exports the linux/amd64 image as a tarball artifact and a separate least-privilege scan-image job (contents: read, no secrets) scans it with a digest-pinned Trivy image, uploads a JSON report artifact, and fails on scan_fail_severity (default CRITICAL). Trivy runs from a pinned digest, not the aquasecurity/trivy-action which was supply-chain compromised in March 2026; the scanner is sandboxed to the image tarball so it never sees the build job's registry credentials. No GHAS/SARIF upload for the Trivy scan - report artifact only. Defaults to off so enabling it does not break existing consumers' CI. ENG-314
This was referenced Jul 11, 2026
The report was filtered to CRITICAL,HIGH + fixed-only, so on clean images it showed ~0 vulnerabilities and hid MEDIUM/LOW and unfixed findings. Now run one comprehensive scan (all severities, fixed and unfixed) to the JSON report artifact and the log, and compute the gate from that report with jq (fail on scan_fail_severity, respecting scan_ignore_unfixed). Drops the scan_report_severity input; the report is always complete. ENG-314
ehaldane-digicatapult
approved these changes
Jul 13, 2026
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.
Pull Request
Checklist
PR Type
Linked tickets
ENG-314
High level description
Adds an opt-in container image CVE scan to
build-docker.yml. Whenscan_container: true, the builtlinux/amd64image is scanned with Trivy and the build fails on CRITICAL findings — closing the gap that private repos get no container CVE scanning and no repo gets it on a PR (the existing Docker Scout step is release-only, public-only, and report-only).Detailed description
buildjob exports thelinux/amd64image as a tarball artifact (reusing the buildx cache and the registry logins already performed there for private base images).scan-imagejob runs least-privilege (permissions: contents: read, no secrets), downloads that artifact, and scans it with Trivy. It uploads a JSON report artifact and fails onscan_fail_severity(defaultCRITICAL,--ignore-unfixedso the gate stays actionable).build-dockerruns.Security / supply-chain:
aquasec/trivy:0.72.0@sha256:cffe3f…), deliberately not theaquasecurity/trivy-actionor a mutable tag — that action was supply-chain compromised in March 2026 (tags force-pushed to malicious commits, credential exfiltration).GITHUB_TOKEN/DockerHub/DHI credentials.Rollout safety:
scan_containerdefaults to false, so merging this does not change behaviour for existing consumers or fail their CI on pre-existing CRITICALs. Repos opt in explicitly; once the fleet is triaged the default can be flipped totruefor org-wide coverage.Validated locally with the exact digest-pinned image and invocations: report step produces a valid JSON artifact; the gate passes on a clean image (
node:24-alpine) and fails (exit 1) on a vulnerable one (python:3.9.1-slim-buster, CRITICALs listed). Wired into testbed-portal, veritable-cloudagent and hello-world via branch-pinned PRs.Describe alternatives you've considered
A standalone
scan-container.ymlthat builds its own image (decoupled, opt-in, covers bespoke-build repos) — viable, but folding intobuild-dockeravoids a duplicate build and applies everywherebuild-dockeris used. spec-rag-api uses a bespoke inline build on PRs so it is not covered until it migrates onto the sharedbuild-docker.Operational impact
Additive and off by default. When enabled, adds an amd64 image export to the build job and one
scan-imagejob. No change to the push/release paths or the existing Docker Scout step.Additional context
Container scanner selection and the digest-pinned/least-privilege delivery are documented on ENG-314. SHA-pinning all third-party actions org-wide is tracked separately (overlaps ENG-312 / ENG-309).