* ci: hard-fail PR and release scans on unacknowledged HIGH/CRITICAL CVEs
Make Trivy a real gate instead of an advisory signal:
- PR CI (docker-validate) no longer uses `continue-on-error: true` on the
Trivy step, so any HIGH/CRITICAL finding not in `.trivyignore` fails the PR.
- The release pipeline (docker-publish.yml) now builds an amd64-only scan
image into the local daemon before the multi-arch push-build, re-runs
Trivy against that exact artifact, and only proceeds to the push if the
scan passes. This closes the gap where a CVE landed between PR merge and
release-time rebuild.
- New `.trivyignore` at repo root is the single source of truth for
acknowledged CVEs across both workflows; it starts empty so the first CI
run surfaces the full list, which we then populate with justifications.
* ci: populate .trivyignore with initial HIGH/CRITICAL acknowledgements
First CI run on the hard-fail Trivy policy surfaced 7 unacknowledged
findings. Each has been reviewed and justified inline:
- 6 CVEs in the statically-linked Go modules inside docker-compose v5.1.1
(github.com/docker/docker, buildkit, otel/sdk x2, grpc). These are
transitively bundled and cannot be bumped without an upstream Compose
rebuild. The grpc CVE is already explicitly acknowledged in the
Dockerfile rationale block at Dockerfile:108-111.
- 1 CVE in picomatch 4.0.3 bundled inside the npm CLI that ships with
node:22-alpine. npm is only invoked at build time against our own
package.json, so the ReDoS vector is not reachable.
Every entry has a revisit trigger (next Compose release or next Alpine
node bump).