Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

VEX & vulnerability scanning

The component scans the SBOM with Grype, applies OpenVEX exceptions so a known-not-affected CVE doesn’t block your release, and gates on Critical findings. This page explains the scan, the VEX layer, and why scanning and gating are split.

The scan

hardened:scan runs when scan = true. It scans the CycloneDX SBOM produced by hardened:sbom — not a re-derived inventory — so the crates, modules, gems, and wheels folded into the SBOM (see SBOMs) are all in scope:

$ grype "sbom:sbom-<artifact-name>.cdx.json" -o json > grype.json

Scanning the SBOM (rather than the image) is what makes ecosystem-dependency CVEs matchable at all — a closure-only scan would miss them.

OpenVEX exceptions

Not every reported CVE actually affects your build. A vulnerability might be in a code path you don’t compile, or already mitigated. OpenVEX (Vulnerability Exploitability eXchange) lets you record, as signed data, that a specific CVE is not_affected for this artifact — so the gate doesn’t block on it (ADR-0014).

You ship your exceptions in your own .openvex/ directory, the same way this repo does. Each exception is a deliberate, reviewed statement, not a blanket mute — it names the CVE and the justification. A CVE with no exception is treated as live.

The scan → gate split

Scanning and gating are deliberately two concerns (ADR-0033):

  • Scan produces the full Grype report (grype.json, kept as an artifact when: always) — the complete picture, exceptions and all.
  • Gate is the pass/fail decision: after VEX exceptions are applied, if any Critical finding remains, the job exits non-zero and the pipeline fails.

Keeping them separate means you always have the full report to triage from, even on a failed pipeline, and the gate’s yes/no is a clean, auditable step rather than buried in scan output.

CRIT=$(jq '[.matches[] | select(.vulnerability.severity=="Critical")] | length' grype.json)
# CRIT > 0  ⇒  gate FAILS

Adding an exception

When the gate flags a Critical you’ve determined is not applicable, add an OpenVEX statement to your .openvex/ directory with the CVE ID and a justification, and re-run. The scan still reports it; the gate no longer blocks on it. Treat this as a reviewed decision — an exception is an assertion you’re standing behind, per this project’s allowlisting discipline.

Reference

OpenVEX-for-Nix-backported-CVEs is ADR-0014; the scan/gate split (and the provenance/dashboard split alongside it) is ADR-0033.