Hand a customer an SBOM and you have told them what your software contains. You have also handed them a list of every vulnerability anyone has ever published against those components — most of which do not affect you. A VEX is how you say so, in a form a machine can read.
This is the unintended consequence of bills of materials that nobody warns you about. Publishing an inventory is the easy part. What follows is a customer running that inventory through a scanner, getting forty hits, and emailing you about all forty.
Why most vulnerabilities in your SBOM do not affect you
A vulnerability is a property of a component and the way it is used. The component being present is necessary but rarely sufficient. Common reasons a published flaw does not apply to your product:
- The vulnerable code path is never reached. The flaw is in a feature of the library your application does not call.
- It requires a configuration you do not use. Plenty of advisories apply only when a particular option is enabled.
- It is a development-only dependency. A vulnerable build tool does not ship to production, though it is worth being careful here — build tooling runs on developer machines and CI runners, which are targets in their own right.
- You already mitigated it without upgrading, by disabling the affected feature or blocking the input that reaches it.
Every one of those is a real, defensible answer. Until recently there was no standard way to record any of them, so the answer lived in an email thread, and the next customer asked again.
What a VEX actually is
A Vulnerability Exploitability eXchange document is a statement, per vulnerability, about whether it affects your product. If the SBOM is the inventory, the VEX is the analysis.
Each entry pairs a vulnerability with a status, and the statuses are the whole point:
- Not affected — the flaw is present in a component but cannot be triggered in this product. This is the one that saves everyone time, and it requires a justification from a fixed list rather than free text: the component is not present, the vulnerable code is not present, it is present but never in an execution path, it cannot be reached by an adversary, or a mitigation is already in place.
- Affected — it does apply, and here is what to do about it in the meantime.
- Fixed — already remediated in this version.
- Under investigation — we have seen it and have not finished deciding.
That last status is more important than it looks, and it is where most VEX documents go wrong.
The temptation to publish only the flattering entries
A VEX that lists only the vulnerabilities you have cleared is worse than no VEX. It reads as a clean bill of health while being a filtered one, and the moment a customer discovers a known advisory that your document simply omits, every other entry becomes suspect.
An advisory nobody has assessed yet should be stated as under investigation. It is an honest status, it is far better than silence, and it tells the reader something true: we know about this, and we have not finished. The alternative — omission — tells them nothing while implying everything.
Where the content should come from
Not from a separate document-writing exercise. If producing a VEX is its own project, it will be done once and never updated.
The useful observation is that most teams are already generating this data and throwing it away. Every time someone triages a finding in a security tool and marks it "won't fix — not exploitable in our setup, we don't use that codec", that is a VEX statement with a justification attached. It is just trapped in a ticketing system.
So the practical approach is to make the triage workflow the source: when a developer acknowledges a finding with a reason, that reason becomes the analysis detail in the exported document. The work has already been done; the export is a formatting problem.
Which format to use
Three are in real use. CycloneDX carries VEX data natively alongside its inventory. OpenVEX is a deliberately minimal standalone format. CSAF — an OASIS standard with a dedicated VEX profile — is the heavyweight of the three and the one large enterprises and public-sector buyers are most likely to name, because it is what government advisory publishers use. CycloneDX is the pragmatic default if you are already producing CycloneDX SBOMs, because the two documents then share identifiers and cannot drift apart; expect to be asked for CSAF if you sell into regulated procurement — NIS2 is usually the reason a customer starts asking.
Whichever you pick, the same rule applies as with the SBOM itself: it describes a moment. Regenerate it when the code changes, and date it.
What is a VEX document?
A Vulnerability Exploitability eXchange document is a machine-readable statement, per vulnerability, about whether it actually affects your product. Where an SBOM says what your software contains, a VEX says what you have decided about each known flaw in those components — typically that it is not affected, affected, fixed, or still under investigation. Its purpose is to stop customers and scanners raising vulnerabilities that are present in a component but cannot be triggered in your product.
What is the difference between an SBOM and a VEX?
An SBOM is the inventory: every package your software contains, with version and licence. A VEX is the analysis: for each known vulnerability affecting those packages, whether it actually applies to your product and why. Publishing an SBOM without a VEX tends to create work, because the recipient runs your inventory through a scanner and asks you about every hit — including the majority that do not affect you.
Why would a vulnerability not affect my product?
Because a vulnerability is a property of a component and the way it is used, not of the component alone. The vulnerable code path may never be reached by your application, the flaw may require a configuration option you do not enable, the dependency may only be used at build time, or you may have already mitigated it without upgrading. All of these are defensible answers — a VEX is simply the standard way to record them so you are not re-explaining in email.
Should a VEX list vulnerabilities I have not assessed yet?
Yes. A VEX should list vulnerabilities you have not assessed yet, marked as under investigation. A VEX that lists only the entries you have cleared reads as a clean bill of health while actually being a filtered one, and the moment a reader finds a known advisory your document omits, every other entry becomes suspect. Under investigation is an honest status that tells the reader something true: we know about this and have not finished deciding.
Where CodeControl fits
CodeControl exports VEX as CycloneDX 1.5 from the triage you have already done: acknowledging a finding with a reason maps to an analysis state with your own note attached as the detail. An advisory nobody has judged yet is stated as in triage rather than omitted. It is generated from the same scan as your SPDX and CycloneDX SBOMs, so the two documents share identifiers and cannot drift apart.