CycloneDX VEX output¶
vexcalibur generate writes CycloneDX 1.6 JSON by default. Pass --format cyclonedx when an explicit selector helps automation. The renderer consumes normalized component identities and provider-neutral findings.
Document fields¶
Field |
Value |
|---|---|
|
|
|
|
|
|
|
A |
|
|
|
|
|
Only components referenced by at least one finding |
|
Reference-only dependency records for emitted components |
|
Findings grouped into CycloneDX vulnerability entries |
JSON keys are sorted. Indentation is two spaces. The file ends with a newline.
Vulnerability grouping¶
One output entry represents findings that share all five values:
vulnerability ID.
source name.
source URL.
analysis state.
analysis detail.
The entry’s affects array contains the sorted, unique component references from that group. The same vulnerability ID produces separate entries when its source, state, or detail differs.
Each entry contains id, bom-ref, source, references, analysis, and affects. It includes updated when the source supplied a modified time.
The references array repeats the vulnerability ID and source. bom-ref is derived from the five grouping values.
Referenced components¶
The components array contains components referenced by at least one finding. Each item carries its normalized identity fields when available. These include bom-ref, type, name, version, and package URL.
Every finding must refer to a component from the parsed SBOM.
An explicit empty local findings array produces empty components and vulnerabilities arrays. An unknown component reference stops rendering with VexRenderError.
Analysis fields¶
Official public OSV findings use:
{
"analysis": {
"detail": "Detected by OSV; manual exploitability analysis required.",
"state": "in_triage"
}
}
Local findings accept these states:
resolvedexploitablein_triagefalse_positivenot_affected
The local default state is in_triage. Its default detail is Provided by local findings file; manual exploitability analysis required.
CycloneDX ignores the format-specific action_statement, impact_statement,
fixed_version, and remediation_category evidence fields. They do not change
grouping, serialized content, or the document serial number. OpenVEX, CSAF, and
SPDX 3 use selected fields under their stricter state mappings.
Findings from the canonical public endpoint use source name OSV, URL
https://osv.dev/, and the detail shown above. A custom compatible endpoint
uses source name OSV-compatible mirror, its canonicalized base URL, and the
detail Detected by an OSV-compatible source; manual exploitability analysis required. The paired --osv-source-name and --osv-source-url options replace
the mirror name and URL with an explicit public provenance alias. The OSV
name and every HTTPS URL on the official osv.dev origin are reserved for the
canonical public service.
Local findings default to source name Local and URL
https://vexcalibur.dev/sources/local.
Updated time¶
When a group contains modified timestamps, updated is the latest one. The field is omitted when none of the group’s findings has a timestamp.
Naive local timestamps are interpreted as UTC. A trailing Z is normalized to a +00:00 offset.
Deterministic output¶
Pass --timestamp and control the finding input when repeatable output matters:
vexcalibur generate \
sbom.json \
--offline \
--findings-file findings.json \
--timestamp 2026-06-23T00:00:00Z \
--output /tmp/vexcalibur-vex.json
The same SBOM, findings, and timestamp produce the same serialized JSON. The document UUID is stable for those inputs. The vulnerability references are stable for those inputs.
A fixed timestamp does not make live OSV data stable. The responses must also be controlled.