skip to content

VEX Statuses & Justifications

OpenVEX and the CSAF VEX profile carry four statuses, and not_affected is only credible when a justification says why. Interviewers use it to see if you can cut a CVE list honestly.

on this pageshow

questions

4

In VEX, what are the four product statuses a statement can assign, and what does each claim?

level: juniorimportance: must knowfreq 58%

answer

  1. scoped to a product-vulnerability pair
  2. exactly four values are allowed
  3. one status is explicitly non-terminal
  4. yes, no, already remediated, still checking

basics

~10 s

VEX defines four statuses for a product-and-vulnerability pair: not_affected, affected, fixed, and under_investigation. They state whether a known vulnerability is actually exploitable in that product, not whether the flawed component is present.

solid answer

~50 s

A VEX (Vulnerability Exploitability eXchange) statement binds one product to one vulnerability and assigns one of four statuses. `not_affected` says the product is not exploitable through that vulnerability, and it must be backed by a justification or a written impact statement. `affected` says it is, and the statement is expected to carry remediation advice — in OpenVEX, an action statement. `fixed` says the named release already contains the remediation. `under_investigation` says the author has not decided yet; it is explicitly a temporary state, not an answer. The key framing: an SBOM tells you what is inside an artifact, a vulnerability feed tells you which of those components have known flaws, and VEX is the supplier's answer to the gap between the two — most feed matches are not exploitable as shipped, and VEX is how that gets said in a machine-readable way instead of in a PDF.

go deeper

for a junior

Be ready to name all four statuses without prompting and say in one line what each claims. Know that not_affected is the one that needs a reason attached, and that under_investigation is temporary.

for a middle

Explain what a statement must carry besides the status — author, timestamp and version, a product identifier you can actually match, and the vulnerability identifier — and why statements supersede each other over time rather than accumulating.

for a senior

Show how you consume these in practice: normalising statuses from suppliers who publish in different formats, deciding which authors you honour, and what your team does when a supplier leaves a pair under_investigation indefinitely.

for a principal

Own the question of what your organisation publishes. Committing to a status per disclosed pair is a standing obligation with headcount attached, and choosing to say nothing rather than say under_investigation is a policy decision, not an engineering one.

## Why VEX exists Run any component inventory against a vulnerability database and you get a list of *potential* matches: this artifact contains a library, that library has a published flaw in the version range you shipped. Most of those matches do not mean the product is exploitable. The vulnerable function may never be called, the vulnerable feature may be compiled out, the flawed code may be there but unreachable by anything an attacker can touch. Historically the answer to "does this one matter for your product?" lived in a vendor PDF, a support ticket, or nowhere at all. VEX — Vulnerability Exploitability eXchange — is the machine-readable form of that answer. A VEX statement is an assertion by a named author that a specific vulnerability has a specific *status* with respect to a specific product. It is a negative-security-advisory channel as much as a positive one: its most valuable output is a documented, auditable "this one does not apply to us, and here is why." Keep the three artifacts of this domain straight, because mixing them up is the canonical wrong answer: - An **inventory (SBOM)** says **what is inside** an artifact. - **Provenance** says **how the artifact came to be**. - A **signature** says **who vouches for it**. - **VEX** says **whether a known flaw in what is inside actually matters** for that product. VEX does not replace any of the others. It annotates the intersection of an inventory and a vulnerability feed. ## The four statuses **not_affected** — the vulnerability does not make this product exploitable. This is the status the whole format was built for, and it is the only one that carries a mandatory evidence obligation: it must be accompanied by a machine-readable justification label, or by a written impact statement explaining the reasoning. A bare `not_affected` with no reason is not a usable assertion; a consumer cannot audit it and cannot decide whether it survives their own deployment. **affected** — the product is exploitable through this vulnerability. A status alone is not much use to a consumer here either, so the formats expect remediation guidance alongside it: OpenVEX requires an action statement (what the consumer should do — upgrade, disable a feature, apply a configuration change) on an `affected` statement. **fixed** — the product release named in the statement contains a remediation for that vulnerability. Note the scoping: `fixed` is asserted about a *release*, so the same document can say the 4.2 line is fixed while 4.1 is still affected. `fixed` is not a claim that the vulnerability never applied; that is what a `not_affected` with `component_not_present` or `vulnerable_code_not_present` says. **under_investigation** — the author knows about the pair and has not yet determined the status. It is a deliberately non-terminal state, and its whole value is honesty at speed: publishing it the hour an advisory drops tells every downstream consumer that you have seen it and are working, which is materially better than silence. It is also the status that ages worst. An `under_investigation` that is still standing months later reads as an abandoned obligation, not as a suppression, and consumers are right to treat it as unanswered. ## What a statement has to carry besides the status The published minimum data elements for a VEX document are, in substance: **VEX metadata** (who the author is, a document identifier, a timestamp and a version), **product identity** (which artifact and which release — ideally a package URL or a digest, not a marketing name), **vulnerability identity** (the advisory or CVE identifier), and the **product status** itself with its justification where one is required. Anything less and a consumer cannot match the statement to something they actually run. Every statement is therefore scoped three ways: to a product, to a vulnerability, and to a moment in time. That is why VEX documents are versioned streams rather than a single truth — a later statement about the same pair supersedes an earlier one, which is how `under_investigation` resolves into `affected` or `not_affected`, and how `affected` later becomes `fixed`. ## Where the statuses live OpenVEX writes the status directly as a `status` field on each statement in a standalone JSON document. The CSAF VEX profile expresses the same information through product-status groupings — `known_not_affected`, `known_affected`, `fixed`, `under_investigation` — with the justification carried as a flag. A CycloneDX BOM can also carry vulnerability analysis inline, using its own analysis vocabulary (states such as `in_triage`, `exploitable`, `not_affected`, `false_positive`), which does not map one-for-one onto the four; when you consume documents from several suppliers you normalise into the four before you can compare anything. There is a practical argument for keeping VEX *beside* the inventory rather than inside it: the inventory of a released artifact does not change, while your exploitability answers about it change every time a new advisory lands. Embedding the analysis in the BOM means re-issuing (and re-signing) the inventory to say something that was never about the inventory. ## What VEX is not It is not a claim that the CVE is invalid — disputing the vulnerability itself is a different conversation with a different party. It is not a suppression rule in your own scanner; a suppression is a local decision, while a VEX statement is a published claim with your name on it. And it carries no authority model of its own: the format lets anyone author a statement, so the consumer always decides whose statements they will honour.

  • Does under_investigation ever count as a final answer for a consumer?
    No. It is a non-terminal status whose only job is to say the author has seen the advisory and is working. It has to resolve later into not_affected, affected, or fixed. A consumer treating a months-old under_investigation as reassurance has misread it; the correct reading is that the question is still open and their own risk decision is still theirs to make.
  • What should an affected statement carry beyond the status itself?
    Remediation guidance. OpenVEX requires an action statement on an affected statement — upgrade to a named release, disable a feature, change a configuration. Without it the consumer learns only that they have a problem, which they could already infer from matching the advisory against the inventory. The value the supplier adds is telling them what to do about it.
  • Why is 'that component is not in our SBOM' not the same as issuing not_affected?
    They answer different questions. An inventory says what is inside an artifact; a VEX statement says whether a known flaw matters for a product. Absence from an inventory could equally mean the inventory is incomplete or shallow on transitive depth. A not_affected statement is a positive, signed, attributable claim by an author who is standing behind it — silence in an inventory is not.

A recall notice names a faulty part. VEX is the manufacturer's reply saying whether that part is in your model at all, and whether it is even wired up.

saying these in an interview costs you the question

  • Says VEX replaces the SBOM rather than annotating it
  • Lists only affected and not_affected as the options
  • Treats under_investigation as a permanent answer
  • Claims VEX asserts the vulnerability itself is invalid
  • Assigns a status to a component rather than to a product
  • Thinks a status alone, with no justification, is a valid not_affected

context

open as a page

Which justification labels can back a VEX not_affected status, and why is one required?

level: middleimportance: must knowfreq 51%

basics

~10 s

Five labels: component_not_present, vulnerable_code_not_present, vulnerable_code_not_in_execute_path, vulnerable_code_cannot_be_controlled_by_adversary, and inline_mitigations_already_exist. One is required because a bare not_affected is an unauditable assertion nobody downstream can re-check.

open as a page

Which VEX justification fits an appliance whose vulnerable XML parser ships only inside an offline migration tool?

level: seniorimportance: should knowfreq 41%

basics

~10 s

vulnerable_code_not_in_execute_path, scoped to the appliance firmware. The parser is inside the image you shipped, so component_not_present is false and your own inventory for that image would disprove it in public.

open as a page

Should you republish a supplier's VEX not_affected claims under your own name for a composed product?

level: principalimportance: nice to knowfreq 27%

basics

~10 s

Not verbatim. Authoring a statement makes you the accountable party, and a supplier's justification was evaluated against the supplier's build, not your composition. Pass through only structural claims; re-evaluate every configuration-dependent one.

open as a page