Safeguard
Supply Chain•

How do exception reasons map to OpenVEX justifications?

Map internal exception reasons to the five OpenVEX justifications and see which reasons are risk decisions, not exploitability facts. A reference table.

Safeguard Security Team
3 min read

Only exploitability facts map to OpenVEX justifications, such as vulnerable code not present or not in the execute path. Risk decisions, like "no fix yet" or "business deferral", are not VEX facts and belong in your exception register, not in a not affected statement.

Two different questions

An exception answers: "do we allow this risk for now?" A VEX statement answers: "is this product affected by this vulnerability?" They overlap only when the reason for the exception is a fact about exploitability. For the wider comparison, see risk acceptance vs VEX not affected.

The OpenVEX specification says a statement with a not affected status must include either a status justification or a free form impact statement. It defines a fixed set of justification labels:

  • component_not_present
  • vulnerable_code_not_present
  • vulnerable_code_cannot_be_controlled_by_adversary
  • vulnerable_code_not_in_execute_path
  • inline_mitigations_already_exist

Mapping table

Internal exception reasonVEX statusJustification label
Package is not in the shipped artefactnot_affectedcomponent_not_present
Affected function removed or patched in a forknot_affectedvulnerable_code_not_present
Input never attacker controllednot_affectedvulnerable_code_cannot_be_controlled_by_adversary
Reachability analysis shows no call pathnot_affectedvulnerable_code_not_in_execute_path
Built in mitigation prevents exploitationnot_affectedinline_mitigations_already_exist
No upstream fix yetaffected, with action statementnone
Business deferralnot a VEX factkeep in the register
Compensating control outside the productnot a VEX fact in most caseskeep in the register

The last two matter. A network control around a product does not change whether the product itself is affected. Calling it not affected misleads the reader.

Where each record lives

Keep the full approval, owner and expiry in the exception register. Publish only the facts others need in a VEX statement. The register may also point to the statement as evidence.

Keep the two in sync

When a not affected statement is published because of reachability, the exception record should reference it. When code changes and the claim is no longer true, both must change. A VEX statement that outlives its evidence is worse than none.

Use timestamps and versions on both, so a consumer can tell which build the claim applies to. The related guide on how to build a VEX document for consumers covers construction.

Pitfalls

  • Mapping "accepted risk" to not affected
  • Using the free form impact statement when a fixed label fits, which hinders automation
  • Leaving a VEX statement in place after upgrading
  • Publishing claims for products you have not analysed

Safeguard's reachability analysis produces the kind of evidence behind a not in execute path claim, and its SBOM tooling gives you the component inventory to publish alongside.

Try it yourself

Click through it at your own pace, or open it full screen.

Look at how the check arrives at a verdict, since a VEX justification should rest on the same kind of reasoning.

Quick check

Can I publish a not affected statement for an accepted risk?

No. Accepting a risk means the product is affected and you tolerate it. Keep that in the register.

Is the impact statement a substitute for a label?

It is allowed, but the specification notes it is free form, not machine readable. Prefer a label when one fits.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.