Best Practices

FAQ: CycloneDX vs SPDX — Which to Use?

Practical answers to the most common CycloneDX vs SPDX questions: differences, tooling, regulatory preference, VEX support, and when to emit both.

Shadab Khan
Security Engineer
6 min read

The SBOM format debate is a recurring conversation on every supply chain security team I have worked with. People arrive with opinions formed by whichever vendor's tool they first used, and those opinions calcify. The actual differences between CycloneDX and SPDX matter, but not in the way the marketing pages suggest. This FAQ answers the questions I keep getting from engineering leads, program managers, and federal contracting teams trying to make the call.

What is the fundamental difference between CycloneDX and SPDX?

CycloneDX is a security-first SBOM format maintained by OWASP. SPDX is a license-first SBOM format maintained by the Linux Foundation and ratified as an ISO standard (ISO/IEC 5962). Both describe the components of a piece of software, but they come from different origin stories, and those origins still shape the ergonomics.

CycloneDX was designed around vulnerability management, attack surface description, and VEX workflows. Its schema prioritizes properties useful for defenders: hash integrity, service descriptions, dependency graphs, and tight VEX integration. SPDX was designed around license compliance, redistribution, and open-source program offices. Its schema prioritizes license expressions, copyright text, and relationships useful for legal review.

If you ask "can SPDX do security" the answer is yes, and vice versa for licensing in CycloneDX. Both formats have grown to cover both domains. But if you look at what each format makes easy versus hard, the origin stories still win.

Which format does the US federal government prefer?

Neither, officially. NTIA's minimum elements for SBOMs are format-agnostic, and CISA has explicitly endorsed both CycloneDX and SPDX as acceptable. Executive Order 14028 and the subsequent OMB memoranda require SBOMs without mandating a format.

In practice, what I see in federal procurement as of 2026 is that SPDX shows up more often in legal-heavy contexts (FedRAMP package submissions, OSS license review) and CycloneDX shows up more often in security-heavy contexts (CISA secure-by-design attestations, vulnerability response workflows). If you sell to the federal government and do not know which your customers want, emit both. It is not that much extra work.

What about the European Union — Cyber Resilience Act, DORA, and NIS2?

The CRA's implementing guidance as of early 2026 does not mandate a specific format either, but ENISA's reference documentation leans toward CycloneDX, particularly for the VEX-adjacent obligations in the exploit notification workflow. DORA operational resilience guidance is format-agnostic but tends to reference SPDX in financial-sector reference architectures.

If you ship into the EU, the safer bet for 2026 is CycloneDX because of its stronger VEX integration, which matters when the CRA's known-exploited-vulnerability notification obligations come into full effect. SPDX 3.0 has closed a lot of the gap here, but tooling maturity in the security space still favors CycloneDX.

Which format has better tooling?

Both are well-supported by the major open-source SBOM generators — Syft, CycloneDX CLI, spdx-tools, Trivy, and cdxgen all emit one or both natively. The differentiation is in downstream tooling.

CycloneDX has better security-tooling adoption: OWASP Dependency-Track, most commercial SCA platforms, and most VEX-aware triage systems speak it fluently. SPDX has better license-compliance tooling: FOSSology, ClearlyDefined, and most legal-review workflows treat it as the primary format.

A concrete example — a minimal CycloneDX component entry:

{
  "type": "library",
  "bom-ref": "pkg:npm/lodash@4.17.21",
  "name": "lodash",
  "version": "4.17.21",
  "purl": "pkg:npm/lodash@4.17.21",
  "hashes": [{"alg": "SHA-256", "content": "a1b2c3..."}],
  "licenses": [{"license": {"id": "MIT"}}]
}

The equivalent in SPDX 2.3:

{
  "SPDXID": "SPDXRef-Package-lodash-4.17.21",
  "name": "lodash",
  "versionInfo": "4.17.21",
  "downloadLocation": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
  "licenseConcluded": "MIT",
  "licenseDeclared": "MIT",
  "checksums": [{"algorithm": "SHA256", "checksumValue": "a1b2c3..."}],
  "externalRefs": [{
    "referenceCategory": "PACKAGE-MANAGER",
    "referenceType": "purl",
    "referenceLocator": "pkg:npm/lodash@4.17.21"
  }]
}

Both describe the same package. CycloneDX is denser and faster to parse programmatically. SPDX is more verbose but carries more license-semantic context natively.

How does VEX support compare?

CycloneDX has first-class VEX support. A CycloneDX document can embed VEX statements directly, reference an external VEX file, or act as a VEX document itself via the vulnerabilities field. This is the dominant workflow in security tooling today.

SPDX 3.0 added a security profile with VEX support, but adoption is still early. Most SCA and vulnerability-management platforms in 2026 speak CycloneDX VEX natively and either ignore or awkwardly translate SPDX security extensions.

If VEX is central to your program — and for most mature supply chain security teams it should be, because VEX is how you suppress unreachable CVE noise at scale — CycloneDX is the pragmatic choice.

When should I emit both formats?

Three scenarios. First, if you ship to both federal and commercial customers and do not control which your procurement counterparties ask for. Second, if your OSPO and security organizations have different tooling and you want neither to become a bottleneck. Third, if you are a software vendor and your sales cycle includes legal review by customer counsel that prefers SPDX — the cost of emitting both is trivial compared to losing a deal on format.

The build-time cost of generating both is usually a single extra command in CI. Disk and transfer cost is negligible. The only real cost is deciding which is canonical for your own internal systems. Pick one as source of truth, generate the other as a derived artifact, and do not try to keep both in sync as equal citizens.

Does format choice affect signing and attestation?

Slightly. Both formats can be wrapped in in-toto attestations and signed with Sigstore/cosign. The signing workflow is format-agnostic.

However, if you are using SLSA provenance with embedded SBOMs, CycloneDX is more common in the reference implementations and examples. SPDX works equally well, but you may spend an hour or two more figuring out the attestation payload shape.

What is my actual recommendation?

Default to CycloneDX for security and vulnerability-management workflows. Emit SPDX alongside it if you have meaningful OSPO or federal legal-review use cases. Generate both at build time as a boring CI step. Do not have a religious debate about it — the format argument has burned more engineering hours than the actual quality differences justify.

If you are at a startup, pick CycloneDX and move on. If you are at a large enterprise with existing OSPO investment in SPDX, keep SPDX there and add CycloneDX to security. Dual-format is a solved problem; the solved part is that it is cheap.

How Safeguard.sh Helps

Safeguard.sh emits both CycloneDX and SPDX as first-class artifacts from every build, without requiring separate pipelines. The generator produces bit-for-bit reproducible output in either format, signs each with cosign, attaches SLSA provenance, and stores the canonical version in a reachability-aware inventory. Security teams query against the CycloneDX view, OSPO and legal query against the SPDX view, and the two stay in sync because they are derived from a single build graph. If you currently emit only one format and need to add the other for a customer, procurement event, or regulatory obligation, the Safeguard CLI can backfill historical builds in a single command.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.