Container vulnerability management¶
ZapTrace scans the exact Docker image built from each relevant pull request,
main update, and release tag. The scan is one control in a defense-in-depth
release process; it does not prove that a deployed service is secure.
Evidence chain¶
The Container Security workflow records the local content-addressed image
digest and uses the same zaptrace:scan image for the CLI smoke check,
CycloneDX SBOM, Trivy JSON, and Trivy SARIF. Before scanning, it regenerates the
committed Python runtime manifest from uv.lock, verifies exact Alpine package
pins, and rejects drift. The image contains build provenance bound to the source
commit, pinned base-image digest, built wheel digest, Python dependency-manifest
digest, Alpine package-manifest digest, and recorded build toolchain. CI extracts
that file from the exact image and verifies it before the vulnerability scan.
The policy report binds the image digest to the SBOM SHA-256 and includes package type, package name, installed version, advisory, severity, fixed version, primary URL, and policy decision. Lock, provenance, JSON, SARIF, SBOM, digest, and Markdown summary artifacts are retained for 30 days. SARIF is also uploaded to GitHub code scanning.
Severity policy¶
- Critical findings block every scan immediately. Repository exceptions do not waive Critical findings.
- High findings are advisory on pull requests so maintainers can establish and triage the initial baseline without hiding results.
- Main-branch and release scans automatically enforce High findings beginning on 2026-08-14. Before that date, they remain visible as baseline findings.
- Medium and lower severities are not part of this release gate, but may still be reviewed through scanner output and dependency tooling.
A finding's nominal severity is not the entire triage decision. Maintainers must consider exploitability, runtime reachability, whether the vulnerable code is present in the final image, available mitigations, and the fixed version.
Temporary High exceptions¶
Only High findings can receive a temporary repository exception. Each entry in
security/container-scan-exceptions.json requires an exact advisory/package
match plus:
- a technical rationale, including reachability or false-positive evidence;
- an accountable owner;
- an ISO expiry date.
Expired, incomplete, duplicate, or mismatched entries fail policy validation. Exceptions must be removed when the package is upgraded or the finding no longer appears. An exception is not a permanent risk acceptance and cannot be used to waive a Critical finding.
Release behavior¶
The release workflow calls the reusable container scan in release mode and
cannot create the GitHub Release until it passes. The gate installs Python
runtime dependencies only from the committed hash-complete manifest, installs
the locally built ZapTrace wheel with --no-deps, and verifies provenance from
the exact scanned image. Release evidence therefore identifies the source
commit, base digest, wheel digest, dependency-manifest digest, image digest, and
SBOM alongside the Python/Rust release artifacts.
This boundary is reproducibility of dependency selection and recorded build inputs within the supported GitHub Actions/Docker environment. It does not claim bit-for-bit image identity across different container engines, kernels, architectures, timestamps, or package mirrors.