Provetry opens in November 2026. The free CRA check, the tools and the guides are available now.

What is VEX? Saying a vulnerability does not affect you

8 min read

On this page
  1. Why it matters
  2. The four statuses
  3. The five justifications for “not affected”
  4. The formats
  5. An example
  6. Good practice
  7. VEX and the reporting clock
  8. How Provetry helps
  9. Sources

Run any scanner over an SBOM and it will report dozens of known vulnerabilities. Most of them do not matter for that product: the vulnerable function is never called, the feature is switched off, the component is only used at build time. VEX, the Vulnerability Exploitability eXchange, is the standard way to say so, in a form that tools and customers can read.

A VEX statement is a simple assertion: this product, this vulnerability, this status, with the reason or the action that goes with it.

Why it matters

Without VEX, every customer who scans your product gets the same long list and asks you the same questions, one by one. With VEX, you answer once, in a file their tools apply automatically: findings you have assessed as not affecting the product disappear from their reports, with your justification attached.

For a manufacturer under the Cyber Resilience Act, VEX is also evidence. Annex I asks you to identify and handle the vulnerabilities of your products and to ship without known exploitable ones. A dated record of why each remaining vulnerability cannot be exploited is exactly what an auditor or a market surveillance authority will want to see. It also saves your team from redoing the same analysis at the next release.

The four statuses

The VEX working group convened by the US CISA defined four statuses, which every format uses:

Status Meaning What must come with it
Not affected The product is not affected by the vulnerability A justification, or an impact statement explaining why
Affected The product is affected An action statement: what users should do
Fixed These versions contain the fix Nothing more
Under investigation The status is not known yet Nothing more; update it when you know

A VEX document never implies a status: a vulnerability it does not mention is simply not covered.

The five justifications for “not affected”

CISA’s status justification document lists five:

  1. Component not present: the vulnerable component is not in the product at all (the scanner matched the wrong package, or it is only a build tool).
  2. Vulnerable code not present: the component is there, but the vulnerable code was not included, for example a module compiled out.
  3. Vulnerable code cannot be controlled by adversary: the code runs, but an attacker cannot reach it with the input needed.
  4. Vulnerable code not in execute path: the code is present but the product never runs it.
  5. Inline mitigations already exist: the product contains protections that prevent exploitation.

The first two, and “not in execute path”, are usually the easiest to prove: a dependency graph or a reachability analysis can show that the vulnerable code is absent or never called. The other two need a careful argument and an explanation in your own words; CISA warns that an attacker may be able to divert execution towards code you thought unreachable.

The formats

VEX is a concept with several implementations. All of them meet CISA’s minimum requirements:

  • CSAF VEX: a profile of the OASIS Common Security Advisory Framework 2.0, also an ISO standard (ISO/IEC 20153:2025). It is the format of choice for publishing security advisories with product trees and remediations; many large vendors and national CERTs use it.
  • CycloneDX VEX: the vulnerabilities section of a CycloneDX document, with an analysis block per vulnerability. It can live inside the SBOM or in a separate file that references it. CycloneDX uses its own, finer-grained names for states and justifications, which map roughly onto CISA’s.
  • OpenVEX: a minimal JSON-LD format maintained by the OpenSSF, independent of any SBOM format, with tools such as vexctl to create and apply documents. Distributions such as Ubuntu publish their VEX data in it.
  • SPDX 3.0 expresses VEX through relationships in its security profile.

An example

Here is an OpenVEX document saying that release 4.2.0 of a gateway is not affected by a vulnerability in a library it ships, because the vulnerable code is never generated:

{
  "@context": "https://openvex.dev/ns/v0.2.0",
  "@id": "https://acme.example/vex/gateway-4.2.0-2026-11-08",
  "author": "Acme Devices Security <security@acme.example>",
  "timestamp": "2026-11-08T09:00:00Z",
  "version": 1,
  "statements": [
    {
      "vulnerability": { "name": "CVE-2024-45296" },
      "products": [
        {
          "@id": "pkg:generic/acme/gateway@4.2.0",
          "subcomponents": [{ "@id": "pkg:npm/path-to-regexp@0.1.7" }]
        }
      ],
      "status": "not_affected",
      "justification": "vulnerable_code_not_present",
      "impact_statement": "No route of the gateway has two parameters in one path segment (such as /:a-:b), so the backtracking regular expression is never generated."
    }
  ]
}

The document has an author, a timestamp and a version number that increases whenever a statement changes. Each statement names the vulnerability, the product (and the component inside it), the status and the reason.

Good practice

  • Be precise about the product: a VEX statement covers the versions it names, nothing else. Use package URLs.
  • Explain, do not just label: a justification code alone convinces nobody. Add a short impact statement a customer can understand.
  • Keep it current: a new release can change the answer. Re-assess when the code calling a component changes, and publish a new version of the document.
  • Do not hide real risk: “not affected” is a claim you may have to defend. When in doubt, say “under investigation” or “affected” with a mitigation.
  • Publish it next to your advisories, and point to it from your security page. Machine-readable advisories (CSAF) and VEX together help meet the CRA’s duty to inform users about fixed vulnerabilities.

VEX and the reporting clock

A VEX statement is not a report to the authorities. If a vulnerability in your product is actively exploited, the CRA’s 24-hour clock applies whatever your VEX says about other versions. But VEX helps you decide fast: if you already know that a component’s vulnerable code is not in your execute path, you know in minutes that the product is not affected. See the reporting clock.

How Provetry helps

For every vulnerability found in a release, you record a VEX assessment (status, justification and explanation); it carries over to later releases that contain the same component, and Provetry flags it when your CI later finds a call to the vulnerable function. Its CI step suggests “not affected” when a vulnerable package is never loaded or a vulnerable function never called, with the evidence (function level for npm, PyPI and Java on the Pro and Consultant plans). Each release can be downloaded with an OpenVEX document and, on paid plans, a public page publishes your CSAF advisories and a VEX feed of the vulnerabilities you closed (not affected or fixed) in supported releases.

Sources