Export SBOM and VEX
Hand your dependency inventory and reachability results to the tools that already track them.
Every scan can be exported in three standard formats. Use an SBOM for the inventory procurement and compliance ask for, and OpenVEX to tell a vulnerability tool which CVEs don't affect you.
| Format | What it carries | Typical consumer |
|---|---|---|
| CycloneDX 1.5 | Every direct and transitive component, with licenses and package URLs | Dependency-Track, ASPM tools, customers who ask for an SBOM |
| SPDX | The same inventory in SPDX | Procurement, federal and regulatory requests |
| OpenVEX 0.2.0 | A status per CVE: affected, not affected, or under investigation, with the reachability reason | ASPM and vulnerability management tools that import VEX |
Before you start: a completed scan, and its ID. The scan ID is the last part of the scan's report URL, after /sbom/. For VEX, use a scan from full application reachability where you can. A precomputed scan exports every direct-dependency CVE as under_investigation, so it carries far fewer not-affected statements; in one test app, 37 of 49 statements were under_investigation on the precomputed scan.
export SOCKET_CLI_API_TOKEN=...
SCAN_ID=your-scan-idSBOM
# CycloneDX
curl -s -H "Authorization: Bearer $SOCKET_CLI_API_TOKEN" \
"https://api.socket.dev/v0/orgs/your-org/export/cdx/$SCAN_ID" > sbom.cdx.json
jq '{bomFormat, specVersion, components: (.components | length)}' sbom.cdx.json
# SPDX
curl -s -H "Authorization: Bearer $SOCKET_CLI_API_TOKEN" \
"https://api.socket.dev/v0/orgs/your-org/export/spdx/$SCAN_ID" > sbom.spdx.json
jq '{spdxVersion, name, packages: (.packages | length)}' sbom.spdx.jsonThe CycloneDX check prints:
{ "bomFormat": "CycloneDX", "specVersion": "1.5", "components": <count> }
The SBOM is an inventory, not a risk reportNeither SBOM carries vulnerabilities or Socket's behavioral findings such as malware or install scripts. CVEs and their reachability travel in the OpenVEX export. Behavioral findings stay in the dashboard and API. For a full picture in Dependency-Track or an ASPM tool, import the CycloneDX SBOM and apply the OpenVEX document to it.
OpenVEX
curl -s -H "Authorization: Bearer $SOCKET_CLI_API_TOKEN" \
"https://api.socket.dev/v0/orgs/your-org/export/openvex/$SCAN_ID" > socket.vex.json
jq '.statements | group_by(.status) | map({status: .[0].status, count: length})' socket.vex.json
jq '[.statements[] | select(.status == "not_affected")][0]
| {cve: .vulnerability.name, product: .products[0], justification}' socket.vex.jsonEach statement names the CVE (with its GHSA alias), the package URL, and a status:
| Status | Meaning |
|---|---|
affected | Reachable or potentially reachable. status_notes gives the call path |
not_affected | Unreachable. justification is vulnerable_code_not_in_execute_path |
under_investigation | No conclusion: pending, not yet supported, or a direct dependency on a precomputed scan. status_notes says which |
Import socket.vex.json with your tool's VEX or OpenVEX import. The not_affected statements are what let it suppress unreachable findings. Spot-check a few of them against the same scan in the dashboard before you rely on the import.
Verify
- Both SBOM exports return valid JSON, with direct and transitive dependencies listed
-
specVersionis1.5in the CycloneDX export - The OpenVEX export has
statements, including at least onenot_affectedwithvulnerable_code_not_in_execute_path -
affectedstatements include a call path instatus_notes - The receiving tool imports both files and suppresses the not-affected CVEs
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| 404 | Wrong path | Only export/cdx, export/spdx and export/openvex exist. There is no export/vex |
No not_affected statements | The scan has no Unreachable results yet | Export a full application scan, or rescan if results were pending |
| SBOM is missing packages | The scan was made without a lockfile | See the troubleshooting table in Connect your repositories |
Reference
Updated 8 days ago