An OpenVEX document is a small JSON file with six required top-level fields and a list of statements. Each statement needs a vulnerability and a status, plus a justification or impact statement when the status is not_affected. Here is a minimal example, followed by what every field does.
A minimal document
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://example.com/vex/2026-001",
"author": "Example Security Team",
"timestamp": "2026-10-19T09:00:00Z",
"version": 1,
"statements": [
{
"vulnerability": { "name": "CVE-2026-0001" },
"products": [
{ "@id": "pkg:generic/example-app@2.4.1" }
],
"status": "not_affected",
"justification": "component_not_present"
}
]
}
The CVE ID and the company in the example are placeholders. The context URL shown follows the pattern of the spec at the time of writing, so check the current spec for the exact value.
Required document fields
The OpenVEX spec lists these as required: @context, @id, author, timestamp, version and statements. Optional fields include role, last_updated and tooling.
- @id identifies the document. It is an IRI, so a URL you control works well.
- author is an individual or organization. The spec prefers a machine-readable identifier.
- timestamp is when the document was issued.
- version must be incremented whenever any content changes, including statements.
Required statement fields
Each statement needs a vulnerability with a name, and a status. The four statuses are not_affected, affected, fixed and under_investigation.
For not_affected, the statement must include a justification, an impact statement, or both. For affected, the spec requires an action statement describing remediation or mitigation.
Products and subcomponents
A product has an @id, which may be a package URL, and an optional identifiers map keyed by purl, cpe22 or cpe23. It may also carry hashes. Subcomponents sit under a product and use the same fields. They should be software identifiers listed in the product's SBOM.
Optional but useful fields
- status_notes explains how the status was reached.
- supplier names who supplies the product.
- action_statement_timestamp records when the action was issued.
- version and timestamp on a statement let you update one statement without rewriting the others.
Timestamps inherit downward. A statement timestamp overrides the document's.
Common mistakes
- Omitting justification and impact statement on a not_affected statement, which makes the document invalid.
- Using a product name instead of an identifier a scanner can match.
- Forgetting to bump the document version after editing one statement.
- Leaving out the action statement on an affected status.
Before you publish
- Validate the JSON against the spec's required fields.
- Check each product identifier against your SBOM.
- Sign the document, or publish over HTTPS from a domain you control.
Quick check
Do I need a statement for every CVE in my product?
No. Authors are not required to cover everything, and a missing statement means no answer, not safe.
Is the author field free text?
It must name an individual or organization. A machine-readable identifier is preferred.
Sources
Last reviewed: 19 October 2026.