VEX SBOM Reference Normalizer
Problem
A VEX record identified only by a CVE can be applied to the wrong component when the same vulnerability affects multiple components. An externally updated VEX can also retain references that no longer exist in its SBOM.
This local VS Code extension provides one workflow: run one command to validate every (vulnerability ID, component reference) relationship and normalize affected-reference ordering without replacing an existing scanner.
Install it from the Visual Studio Marketplace.
Open a JSON document with this minimal envelope:
{
"sbom": {
"components": [
{ "bom-ref": "pkg:npm/example-a@1.0.0" },
{ "bom-ref": "pkg:npm/example-b@2.0.0" }
]
},
"vex": {
"vulnerabilities": [
{
"id": "CVE-2026-0001",
"affects": [
{ "ref": "pkg:npm/example-b@2.0.0" },
{ "ref": "pkg:npm/example-a@1.0.0" }
]
}
]
}
}
The MVP intentionally accepts this documented envelope rather than every CycloneDX document shape. Existing fields are preserved. Each vulnerability entry remains separate, so component-specific analysis fields are not merged merely because CVE IDs match.
Primary workflow
- Install the Marketplace extension and open the envelope as JSON in VS Code.
- Run
VEX: Validate and Normalize SBOM References from the Command Palette.
- If all references resolve uniquely, the active document is replaced with formatted JSON whose
affects entries are deduplicated and sorted by ref.
- If JSON is invalid, an SBOM
bom-ref is duplicated, or a VEX reference is missing from the SBOM, the document is unchanged and an error is shown.
The command reads only the active editor. It has no network access, telemetry, file-system traversal, account requirement, or background activation.
One-minute first run
Copy the JSON input above into a new VS Code document, select JSON language mode, and run VEX: Validate and Normalize SBOM References. The affects entries should be sorted by ref. No file is uploaded or saved automatically.
For source-development verification, open this directory in an Extension Development Host, use tests/fixtures/success.json, and repeat with tests/fixtures/unknown-reference.json to confirm the failure path leaves the document unchanged.
Local verification
From the project root, using an already available Node.js runtime:
node tests/success.test.js
node tests/failure.test.js
node tests/extension.test.js
node scripts/package.js --check
The tests use only Node.js standard-library modules. The packaging script performs a read-only readiness check and prints the deterministic package file list when run without arguments; it does not publish or create an archive.
Scope and limitations
- Only top-level
sbom.components are indexed.
- Every component must have a unique, non-empty
bom-ref.
- Every vulnerability must have a non-empty
id and an affects array.
- Empty
affects arrays are permitted because they do not claim a component relationship.
- The extension validates reference integrity; it does not determine exploitability, vulnerability status, or scanner correctness.
- Future Marketplace versions require separate publication approval and tooling.
See DECISIONS.md, SOURCE_RIGHTS.md, PRIVACY.md, and PUBLICATION_CHECKLIST.md before considering distribution.