SBOM

SBOM Interoperability: Bridging CycloneDX and SPDX

Your suppliers send SPDX. Your tools expect CycloneDX. Interoperability between SBOM formats is a real operational challenge. Here is how to solve it.

Alex
Open Source Community Lead
6 min read

The SBOM format question has settled into a pragmatic reality: both CycloneDX and SPDX are here to stay. Government mandates reference both. Tools generate both. Suppliers deliver both. And if your organization consumes SBOMs from more than a handful of sources, you are dealing with both whether you planned to or not.

This is not a problem that needs solving through format wars. It is an interoperability challenge that needs practical engineering solutions. We handle SBOM format conversion and normalization daily at Safeguard, and this post shares what we have learned.

The Format Landscape in 2025

Let me set the stage. As of mid-2025:

CycloneDX is at version 1.6, with strong adoption in application security tooling, DevSecOps pipelines, and commercial SCA products. Its strengths are a clean JSON schema, first-class vulnerability correlation (VEX), and a well-defined component taxonomy. Most modern SBOM generators default to CycloneDX.

SPDX is at version 2.3 (with 3.0 finalized but not yet widely adopted). It has strong adoption in legal/compliance contexts, the Linux Foundation ecosystem, and government procurement. Its strengths are comprehensive license modeling, established legal precedent, and ISO standardization (ISO/IEC 5962:2021).

In practice, we see roughly this split among SBOMs processed by Safeguard:

  • 58% CycloneDX (predominantly 1.5 and 1.6)
  • 34% SPDX (predominantly 2.3)
  • 8% other or non-standard formats

Where Interoperability Breaks Down

If you could losslessly convert between CycloneDX and SPDX, there would be no interoperability problem. Unfortunately, you cannot. The formats model software composition differently, and some data is lost or transformed during conversion.

Conceptual Mismatches

Component vs. Package model. CycloneDX uses a hierarchical component model where components can be nested. SPDX uses a flat package model with explicit relationship declarations. Converting from CycloneDX's nested structure to SPDX's relationship model is straightforward. Going the other direction requires inferring hierarchy from relationships, which is not always unambiguous.

License modeling. SPDX has a significantly richer license model, including declared vs. concluded licenses, license exceptions, and complex license expressions. CycloneDX supports license expressions but lacks the declared/concluded distinction. Converting from CycloneDX to SPDX means you cannot populate the concluded license field. Converting from SPDX to CycloneDX may lose the nuance of the concluded license analysis.

Vulnerability information. CycloneDX has first-class VEX support integrated into the SBOM format. SPDX handles vulnerability information through external security advisories linked via relationships. There is no clean mapping between CycloneDX's inline VEX and SPDX's external reference model.

Service and dependency modeling. CycloneDX 1.5+ models services and their dependencies. SPDX does not have a native service concept. Service information is simply lost in conversion.

Data Field Mismatches

Beyond conceptual differences, there are dozens of smaller field-level mapping issues:

  • CycloneDX's purl field maps cleanly to SPDX's externalRef with category PACKAGE-MANAGER, but SPDX's broader external reference categories have no CycloneDX equivalent
  • CycloneDX's component scope (required/optional/excluded) has no SPDX equivalent
  • SPDX's FilesAnalyzed flag has no CycloneDX equivalent
  • CycloneDX's evidence section (how a component was identified) has no SPDX mapping
  • Supplier vs. originator semantics differ between the formats

Conversion Strategies

Strategy 1: Canonical Internal Format

Pick one format as your internal standard and convert everything to it on ingestion. This is the approach most organizations take, and it is what we recommend for most use cases.

Pros: Simplifies all downstream tooling. One schema to validate, one format for queries, one export path.

Cons: Some data loss during conversion. Need to maintain the original SBOM alongside the converted version for compliance purposes.

Our recommendation: use CycloneDX as your internal format if your primary concern is security and vulnerability management. Use SPDX if your primary concern is license compliance and legal analysis.

Strategy 2: Format-Agnostic Internal Model

Build an internal data model that is a superset of both formats. Store all data natively, regardless of source format, and render to either format on demand.

Pros: No data loss. Can export to either format with full fidelity (for data that exists in the target format).

Cons: Significantly more complex to implement. The internal model must evolve as both formats evolve.

This is what Safeguard does internally. It is the right approach if you are building SBOM tooling, but it is overengineering for most organizations that just need to consume and manage SBOMs.

Strategy 3: Multi-Format Storage

Store SBOMs in their original format and handle format differences at query time.

Pros: Zero data loss. No conversion overhead.

Cons: Every tool and query must handle both formats. Complexity spreads across the entire system instead of being contained at the conversion boundary.

We do not recommend this approach for most organizations. It trades simplicity at ingestion for complexity everywhere else.

Practical Conversion Tips

If you are implementing SBOM conversion, here are things we learned the hard way:

Always preserve the original. Store the original SBOM as received, in its original format. Conversions are lossy, and you may need the original for audit, compliance, or reconversion with improved tools later.

Validate before converting. Many conversion failures are caused by invalid input, not conversion bugs. Validate the source SBOM against its format's schema before attempting conversion.

Map PURLs first. Package URLs (PURLs) are the most reliable cross-format identifier. If a component has a PURL, use it as the anchor for conversion. If it does not, the conversion is inherently less reliable.

Handle license expressions carefully. SPDX license expressions are not always valid CycloneDX license expressions, and vice versa. Use a proper SPDX expression parser rather than string manipulation.

Test conversion roundtrips. Convert A to B, then B back to A. Compare with the original. The differences are your data loss -- make sure you understand and accept them.

Version-specific conversion. CycloneDX 1.4 to 1.5 and 1.5 to 1.6 introduce new fields that older conversion tools may not handle. Make sure your conversion tooling is current with the latest format versions.

SPDX 3.0: A New Chapter

SPDX 3.0 changes the conversion landscape significantly. The new version introduces a profile-based architecture (Core, Software, Security, AI, Dataset, Licensing) that is conceptually closer to CycloneDX's modular approach. Security profiles in SPDX 3.0 include VEX-like vulnerability assertions, which closes one of the biggest interoperability gaps.

However, SPDX 3.0 adoption is still in early stages. Most tools still generate SPDX 2.3, and many organizations have existing SPDX 2.3 archives. The transition will take time, and during that transition you will need to handle three formats: CycloneDX, SPDX 2.3, and SPDX 3.0.

How Safeguard.sh Helps

Safeguard.sh handles SBOM interoperability natively. Upload an SBOM in any supported format -- CycloneDX 1.4-1.6, SPDX 2.2-2.3, or SPDX 3.0 -- and our platform normalizes it into our format-agnostic internal model. You can query, correlate vulnerabilities, run policy gates, and export in any format without worrying about conversion. We preserve the original SBOM alongside the normalized version, so you always have a compliance-ready artifact. Stop fighting format wars and start managing your supply chain.

Never miss an update

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