VEX (Vulnerability Exploitability eXchange) is a machine-readable assertion format that answers the question an SBOM alone cannot: given that a product contains a component affected by a known CVE, is that vulnerability actually exploitable in this specific product? An SBOM identifies components and versions; a CVE database maps those versions to known vulnerabilities; but the intersection of the two systematically overstates actual risk. A container image built on a minimal base may include a library with a known buffer overflow in a network-parsing function — but if that function is never called by anything in the image, or the affected code path requires a configuration flag that is hardcoded off, the CVE is present but not exploitable. Without VEX, every scanner that ingests the SBOM raises an alert; with VEX, the supplier asserts the non-exploitability with a machine-readable justification that automated tooling can consume to suppress the alert without human triage. VEX originated in the same NTIA multistakeholder process that produced the SBOM minimum elements framework, and was formalised by CISA in 2021–2022.
A VEX document (or VEX statement embedded in a CycloneDX SBOM) asserts one of four statuses per vulnerability-per-product pair. Not affected means the product contains the vulnerable component but the vulnerability is not exploitable in this product; this is the most common and most useful status, and it requires a mandatory justification from a defined set — including: the vulnerable code is not present (dead code, excluded at compile time), the vulnerable code cannot be reached by the attack vector (requires a code path that doesn’t exist in the product), the product has an inline mitigation (input validation upstream of the vulnerable function), or the component is protected by the product’s environment (sandboxing, SELinux, seccomp). Affected means the product is impacted and remediation is needed; this may include an action statement (update to version X, apply workaround Y). Fixed means a prior “affected” status has been resolved in the current product version. Under investigation is a time-bounded transitional status indicating the supplier is actively assessing exploitability. The combination of status and justification is what makes VEX machine-actionable: a scanner can automatically close an alert if it receives a signed not_affected VEX statement with a valid justification from the product’s supplier, without requiring a human to read a prose advisory.
Three formats implement VEX, reflecting the still-evolving standardisation landscape. CSAF VEX (Common Security Advisory Framework, OASIS standard, used by Red Hat, Microsoft, and major enterprise vendors) is a profile of the CSAF 2.0 advisory format and the most widely adopted format for large software suppliers publishing product security advisories. CycloneDX VEX embeds VEX statements directly inside a CycloneDX SBOM using the vulnerabilities section, making the SBOM itself the carrier of exploitability status — convenient for toolchains that already produce CycloneDX SBOMs and want a single document. OpenVEX (originally from Chainguard, now an independent specification) is a minimal, format-agnostic JSON-LD schema designed to be attached to OCI container images as a signed referrer via the OCI Referrers API, with vexctl as its tooling layer. All three share the same four status values and the same justification categories; the differences are in schema, tooling ecosystem, and distribution model. In practice, consumers must handle all three formats, as different suppliers use different ones. VEX documents are most useful when signed — a signed VEX statement attached to a container image as an ORAS-managed referrer, with the signature rooted in Sigstore or a private PKI, allows automated policy engines (Kyverno, OPA Gatekeeper) to verify that the exploitability assessment comes from the software supplier and has not been tampered with, making VEX part of the verifiable supply chain alongside the SBOM and cosign signature.
