Skip to content

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.