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.

FormatWhat it carriesTypical consumer
CycloneDX 1.5Every direct and transitive component, with licenses and package URLsDependency-Track, ASPM tools, customers who ask for an SBOM
SPDXThe same inventory in SPDXProcurement, federal and regulatory requests
OpenVEX 0.2.0A status per CVE: affected, not affected, or under investigation, with the reachability reasonASPM 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-id

SBOM

# 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.json

The CycloneDX check prints:

{ "bomFormat": "CycloneDX", "specVersion": "1.5", "components": <count> }
📘

The SBOM is an inventory, not a risk report

Neither 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.json

Each statement names the CVE (with its GHSA alias), the package URL, and a status:

StatusMeaning
affectedReachable or potentially reachable. status_notes gives the call path
not_affectedUnreachable. justification is vulnerable_code_not_in_execute_path
under_investigationNo 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
  • specVersion is 1.5 in the CycloneDX export
  • The OpenVEX export has statements, including at least one not_affected with vulnerable_code_not_in_execute_path
  • affected statements include a call path in status_notes
  • The receiving tool imports both files and suppresses the not-affected CVEs

Troubleshooting

SymptomCauseFix
404Wrong pathOnly export/cdx, export/spdx and export/openvex exist. There is no export/vex
No not_affected statementsThe scan has no Unreachable results yetExport a full application scan, or rescan if results were pending
SBOM is missing packagesThe scan was made without a lockfileSee the troubleshooting table in Connect your repositories

Reference


Did this page help you?