What is VEX?

Vulnerability Exploitability eXchange. One small, machine-readable statement per vulnerability per product that answers: does this CVE actually affect it, and if not, why not.

The four statuses

fixed

The version contains the fix. Nothing to do, unless persisted state needs repair, and the statement says so.

affected

It applies. An action statement says what to do: upgrade, backport, or mitigate.

not affected

Vulnerable code not present, not reachable, or already mitigated. A justification says which, from a list of five.

under investigation

Nobody has confirmed yet. Saying so beats guessing, and the statement is updated later.

One addition on the human pages: no fix on this line, for version lines upstream stopped releasing for. In VEX terms that is still "affected", with an action statement that says backport.

How is VEX different from an SBOM?many findings in, few decisions out

A software bill of materials lists components. Scanners match it against vulnerability databases and produce long lists of findings, most of them not exploitable in context. VEX turns that list of findings into a list of decisions, each with a reason.

From SBOM to VEX: a list of components becomes a long list of findings, which VEX turns into a short list of decisions with reasons SBOM212 componentswhat is inside scanner Findings40 CVEs matchedno contextno priorityno decision VEX Decisions 3 affected, with an action 37 not affected, with a reason signed, dated, machine-readable Illustrative counts. The shape is the point.
What does a statement look like?two instances, one advisory, two answers
{
  "vulnerability": { "name": "CVE-XXXX-XXXXX" },
  "products": [{ "@id": "pkg:generic/example-tool@1.6.9",
                 "identifiers": { "instance": "app-eu-1" } }],
  "status": "affected",
  "action_statement": "Upgrade to 1.7.5, or apply the 1.6 backport.",
  "timestamp": "2026-09-07T09:05:40Z"
}
  • affected below the fix, feature reachable
  • the action statement is mandatory for "affected"
{
  "vulnerability": { "name": "CVE-XXXX-XXXXX" },
  "products": [{ "@id": "pkg:generic/example-tool@1.6.9",
                 "identifiers": { "instance": "app-internal" } }],
  "status": "not_affected",
  "justification": "vulnerable_code_not_in_execute_path",
  "impact_statement": "The vulnerable feature is disabled on this instance.",
  "timestamp": "2026-09-07T09:05:40Z"
}
  • not affected same version, different configuration
  • the justification is from a fixed list; the impact statement says why in words

Every advisory will have an OpenVEX twin at the same address with a .vex.json extension, one statement per version line. The runner produces the per-instance statements above from your own configuration.

Why will buyers ask for it?the Cyber Resilience Act, and the questionnaire

The EU Cyber Resilience Act requires manufacturers of products with digital elements to handle vulnerabilities throughout the support period and to document how. Buyers in regulated sectors already ask suppliers for patch timelines in security questionnaires. A VEX statement per advisory, per instance, answers those questions without a meeting, and the record is where they live.