STP
SBOM Observer/

Format Interoperability

Working with multiple SBOM formats and converting between CycloneDX and SPDX

Two dominant SBOM formats exist: CycloneDX (operational focus, strong vulnerability management) and SPDX (license focus, established history). Both are open standards with active communities, broad tool support, and regulatory recognition. Organizations must choose primary format while understanding interoperability—suppliers may provide different formats, tools may require specific formats, regulations may allow choice. Format diversity is reality requiring practical accommodation strategies rather than theoretical format wars.

Perfect format interoperability remains elusive. CycloneDX and SPDX have overlapping but non-identical capabilities. Conversion between formats risks data loss—information expressible in one format may lack equivalent in another. Organizations need strategies for working across formats: when to convert, when to maintain multiple formats, how to minimize data loss, which tools support multi-format workflows. Pragmatic format management accepts imperfection while maximizing operational utility.

Format Comparison

CycloneDX

Design philosophy: Operational security focus, designed for vulnerability management and continuous monitoring.

Strengths:

  • Rich VEX integration (vulnerability status communication)
  • Service and hardware components beyond software
  • Evidence and attestation support
  • Operational metadata (deployment context, criticality)
  • Strong tooling ecosystem for vulnerability scanning

Format specifics:

  • JSON and XML representations
  • Versions 1.0 through 1.6 (active evolution)
  • Component-centric with flexible properties
  • Dependency graph representation
  • External references for tooling integration

Primary use cases:

  • Vulnerability management
  • Continuous component monitoring
  • DevSecOps integration
  • VEX-based risk communication
  • Supply chain security

SPDX

Design philosophy: License compliance focus, established standard with long history and legal precision.

Strengths:

  • Mature license expression language
  • Legal precision and established case law
  • Broad tool and vendor adoption
  • ISO/IEC standard (5962:2021)
  • Strong in compliance and legal domains

Format specifics:

  • Multiple representations (JSON, YAML, XML, RDF, Tag-Value)
  • Version 2.3 current (3.0 in development)
  • Package-centric model
  • Relationship-based linking
  • Extensive license database

Primary use cases:

  • License compliance
  • Legal review and auditing
  • Government and defense applications
  • M&A due diligence
  • Open source governance

Capability Matrix

CapabilityCycloneDXSPDXNotes
Component enumerationExcellentExcellentBoth comprehensive
License informationGoodExcellentSPDX more nuanced
Vulnerability dataExcellentBasicCycloneDX VEX superior
Dependency relationshipsExcellentGoodDifferent models
Provenance/pedigreeGoodGoodComparable
Services (APIs, microservices)ExcellentLimitedCycloneDX specialty
Hardware componentsExcellentLimitedCycloneDX specialty
Cryptographic signaturesBothBothImplementation differs
File-level detailBasicExcellentSPDX specialty

Conversion Strategies

When to Convert

Conversion appropriate:

  • Receiving format doesn't match your tooling requirements
  • Supplier provides SPDX but vulnerability scanner requires CycloneDX
  • Compliance requires SPDX but development uses CycloneDX tools
  • Customer requests specific format you don't natively generate

Avoid conversion:

  • Source format adequate for your needs (don't convert just for format preference)
  • Conversion would lose critical information
  • Maintaining converted formats creates operational burden
  • Original format already meets customer/regulatory requirements

Conversion Tools

SBOM Utility (official conversion tool):

# SPDX to CycloneDX
sbom-utility convert --input-file sbom.spdx --output-file sbom.json --output-format CycloneDX

# CycloneDX to SPDX
sbom-utility convert --input-file sbom.json --output-file sbom.spdx --output-format SPDX

CycloneDX CLI:

# Convert between CycloneDX formats (JSON/XML)
cyclonedx-cli convert --input-file sbom.xml --output-file sbom.json --output-format json

bomctl (multi-format tool):

# Fetch and convert
bomctl fetch https://example.com/sbom.spdx.json
bomctl convert sbom.spdx.json --format cyclonedx

Custom conversion scripts:

# Example: SPDX to CycloneDX basic conversion
def spdx_to_cyclonedx(spdx_doc):
    """Convert SPDX to CycloneDX (simplified)"""

    cdx = {
        'bomFormat': 'CycloneDX',
        'specVersion': '1.6',
        'version': 1,
        'components': []
    }

    for package in spdx_doc.get('packages', []):
        component = {
            'name': package['name'],
            'version': package.get('versionInfo', 'unknown'),
            'type': 'library'
        }

        # Convert PURL if present
        for external_ref in package.get('externalRefs', []):
            if external_ref['referenceType'] == 'purl':
                component['purl'] = external_ref['referenceLocator']

        # Convert license
        if 'licenseConcluded' in package:
            component['licenses'] = [{
                'license': {'id': package['licenseConcluded']}
            }]

        cdx['components'].append(component)

    return cdx

Data Loss in Conversion

CycloneDX → SPDX losses:

  • VEX vulnerability status details
  • Component criticality ratings
  • Service and API definitions
  • Evidence and attestation details
  • Operational metadata (deployment context)

SPDX → CycloneDX losses:

  • File-level SBOM details
  • Snippet-level information
  • Complex license expressions nuances
  • Package verification codes
  • SPDX-specific annotations

Mitigation strategies:

  • Document conversion limitations in converted SBOM metadata
  • Maintain original format as authoritative source
  • Use properties/annotations to preserve format-specific data where possible
  • Accept pragmatic information loss for operational scenarios

Loss documentation example:

{
  "metadata": {
    "properties": [
      {
        "name": "cdx:converted-from",
        "value": "SPDX-2.3"
      },
      {
        "name": "cdx:conversion-notes",
        "value": "Converted from SPDX. File-level details not preserved. See original SBOM for complete information."
      },
      {
        "name": "cdx:original-sbom-url",
        "value": "https://example.com/original.spdx.json"
      }
    ]
  }
}

Multi-Format Workflows

Dual-Format Generation

Generate both CycloneDX and SPDX simultaneously during build.

Advantages:

  • Native format quality (no conversion artifacts)
  • Serves all consumer preferences
  • No data loss from conversion
  • Format-specific strengths preserved

Disadvantages:

  • Doubled generation effort and storage
  • Two SBOMs to maintain and sign
  • Potential inconsistencies if tools generate differently
  • Distribution complexity (which format to send?)

Implementation:

# CI/CD dual-format generation
- name: Generate CycloneDX SBOM
  run: cyclonedx-npm --output-file sbom-cdx.json

- name: Generate SPDX SBOM
  run: spdx-sbom-generator --output sbom-spdx.json

- name: Validate both formats
  run: |
    cyclonedx-cli validate --input-file sbom-cdx.json
    spdx-tools Verify sbom-spdx.json

- name: Sign both SBOMs
  run: |
    gpg --detach-sign sbom-cdx.json
    gpg --detach-sign sbom-spdx.json

- name: Publish both formats
  run: |
    upload-sbom.sh sbom-cdx.json format=cyclonedx
    upload-sbom.sh sbom-spdx.json format=spdx

When appropriate: High-compliance environments, diverse customer base with format preferences, sufficient resources for dual maintenance.

On-Demand Conversion

Generate primary format, convert to alternate format on request.

Advantages:

  • Single source of truth
  • Lower operational overhead
  • Format preference flexibility for consumers

Disadvantages:

  • Conversion delays
  • Potential data loss
  • Converted formats may be lower quality

Implementation:

# API endpoint for format conversion
@app.route('/api/sbom/<product>/<version>')
def get_sbom(product, version):
    """Retrieve SBOM in requested format"""

    # Get format preference from query param or Accept header
    requested_format = request.args.get('format', 'cyclonedx')

    # Retrieve native SBOM (CycloneDX in this example)
    native_sbom = fetch_sbom(product, version, format='cyclonedx')

    if requested_format == 'cyclonedx':
        return jsonify(native_sbom)

    elif requested_format == 'spdx':
        # Convert on-demand
        converted_sbom = convert_cyclonedx_to_spdx(native_sbom)

        # Add conversion metadata
        converted_sbom['annotations'] = converted_sbom.get('annotations', [])
        converted_sbom['annotations'].append({
            'annotator': 'Tool: SBOM-Converter-1.0',
            'annotationType': 'OTHER',
            'annotationDate': datetime.utcnow().isoformat(),
            'comment': 'Converted from CycloneDX 1.6'
        })

        return jsonify(converted_sbom)

    else:
        return {'error': 'Unsupported format'}, 400

When appropriate: Most organizations, resource-constrained teams, primary format serves majority needs, occasional alternate format requests.

Format-Agnostic Tooling

Use tools supporting multiple formats natively, avoiding conversion.

Multi-format tools:

  • Dependency-Track (ingests CycloneDX and SPDX)
  • Grype (scans both formats)
  • OSS Review Toolkit (generates and processes both)
  • Syft (outputs either format)

Strategy: Select toolchain supporting both formats. Eliminates conversion need by working with whatever format received.

Example workflow:

# Vulnerability scanning accepting any format
grype sbom:./vendor-sbom.spdx.json -o table
grype sbom:./internal-sbom.cdx.json -o table

# Dependency tracking
dependency-track bom upload --project vendor-product --file vendor-sbom.spdx.json
dependency-track bom upload --project internal-product --file internal-sbom.cdx.json

When appropriate: Flexible tooling budget, willingness to select multi-format tools, need to work with various suppliers using different formats.

Format Selection Guidance

For Producers

Choose CycloneDX if:

  • Primary concern is vulnerability management
  • Developing software (vs. license compliance focus)
  • Need VEX capabilities
  • Target DevSecOps integration
  • Consumers are mostly technical teams

Choose SPDX if:

  • Primary concern is license compliance
  • Legal/compliance driving requirements
  • Government or defense customers
  • ISO standard preference
  • Established SPDX tooling already in place

Choose both if:

  • Diverse customer base with format preferences
  • Resources permit dual maintenance
  • Regulatory requirements specify format choice
  • Different use cases favor different formats (CycloneDX for security, SPDX for compliance)

For Consumers

Request format matching your tooling: If vulnerability scanner requires CycloneDX, request CycloneDX from suppliers. Don't create conversion overhead unnecessarily.

Flexibility when possible: If tooling is format-agnostic, accept whatever format supplier provides. Reduces supplier burden and accelerates SBOM adoption.

Document preferences: Publish format preferences in procurement requirements so suppliers know expectations upfront.

Version Compatibility

CycloneDX Versions

Current: 1.6 (January 2024) Previous: 1.5, 1.4, 1.3, 1.2, 1.1, 1.0

Backward compatibility: Generally good. Older tools can read newer SBOMs ignoring unknown fields. Newer tools understand older SBOMs.

Forward compatibility: Older tools may miss newer features (1.4 tool won't understand 1.6 VEX extensions).

Best practice: Generate latest stable version (1.6). Consumers with older tools still get value from common fields even if advanced features ignored.

SPDX Versions

Current: 2.3 (July 2022) Previous: 2.2, 2.1, 2.0, 1.x Coming: 3.0 (major revision in development)

Backward compatibility: Generally maintained within 2.x line. Breaking changes between 2.x and upcoming 3.0.

Forward compatibility: Similar to CycloneDX—older parsers handle newer SBOMs with graceful degradation.

Best practice: Use 2.3 for current work. Plan for 3.0 migration when released and stabilized.

Practical Recommendations

Single format for internal generation: Choose one primary format for internal SBOM generation. Don't fragment internal processes across formats without clear need.

Multi-format for consumption: Accept SBOMs in either format from suppliers. Use format-agnostic or multi-format tools for ingestion.

Convert only when necessary: Conversion introduces potential errors and data loss. Convert only when tooling absolutely requires specific format and native generation isn't feasible.

Document format decisions: Explain format choice in documentation: "We generate CycloneDX for operational security focus. SPDX available on request via conversion."

Monitor format evolution: Both formats evolve. Track new capabilities and plan periodic reviews of format choice. SPDX 3.0 may change capability comparison significantly.

Avoid format wars: Both formats are legitimate, supported, and regulatory-compliant. Choose based on use case fit, not ideological preference.

Next Steps

On this page