Knowledge · SBOM

CycloneDX or SPDX: which SBOM format for the CRA?

The CRA prescribes no format. TR-03183-2 requires CycloneDX 1.6 or SPDX 3.0.1 or later.

In practice that means CycloneDX and SPDX. Both work for firmware; the fields you fill matter more than the format.

As of 23 October 2026 · 5 min readYou make the conformity statement. This page and our reports provide technical findings as its basis.

The test subject
File
CycloneDX export from the app for ble_freertos_amota.axf
Build
Public Keil project, Apollo3, FreeRTOS
SHA-256
c4b38f3a52b01e3a8def5645c27b273b69cd8b0e1ea3b1981c421f4096f3a444

Build: sparkfun/AmbiqSuiteSDK, commit e280cbd

The test subject: Build: sparkfun/AmbiqSuiteSDK, commit e280cbd

What does the CRA say about the format?

Annex I, Part II, point 1 requires manufacturers to identify and document vulnerabilities and components, including by drawing up a software bill of materials in a commonly used and machine-readable format covering at the very least the top-level dependencies of the products. The Regulation names no specific format.

The Commission may specify the format and elements by implementing acts (Art. 13(24)). As of 23 October 2026 no such act has been adopted. The SBOM obligation applies from 11 December 2027.

Which versions of CycloneDX and SPDX apply in October 2026?

FormatVersions and status
CycloneDXCurrent version 1.7 (21 October 2025), before it 1.6 (9 April 2024). Patch releases: 1.7.2 of 17 September 2026, 1.6.2 of 2 June 2026. Ecma standard ECMA-424, second edition December 2025 for version 1.7. JSON, XML, Protocol Buffers.
SPDXSPDX 2.3 (3 November 2022) and SPDX 3.0.1 (17 December 2024). SPDX 2.2.1 is standardised as ISO/IEC 5962:2021. Version 3 is a new data model with profiles, for example for security and build. SPDX 3.1 has existed as a release candidate since 24 January 2026; it is not a release yet.
BSI TR-03183-2, v2.1.0Newly created SBOMs as JSON or XML, valid against CycloneDX 1.6 or later or SPDX 3.0.1 or later (§ 4). Up to version 2.0.0, CycloneDX 1.5 and SPDX 2.2.1 applied.

What does TR-03183-2 require per component?

For German manufacturers the guideline is the most precise statement of what an SBOM should contain. For the SBOM itself it requires the creator and a timestamp (§ 5.2.1), and for each component:

  1. 1

    Creator of the component, as an e-mail address or URL.

  2. 2

    Name and version. If there is no version, the modification date of the file.

  3. 3

    File name of the component.

  4. 4

    Dependencies on other components, with a statement of whether the list is complete.

  5. 5

    Distribution licences.

  6. 6

    Hash value of the shipped component, as SHA-512.

  7. 7

    Whether the component is executable, an archive, and structured.

Which fields do the schemas themselves require?

That an SBOM is valid against its schema says little about its content. CycloneDX requires only bomFormat and specVersion in the document, and type and name for each component. SPDX 2.3 requires spdxVersion, dataLicense, SPDXID, name and creationInfo, and SPDXID, name and downloadLocation for each package. SPDX 3.0.1 requires only creationInfo for each element, with created, createdBy and specVersion.

None of the three schemas requires a version for each component, nor a hash. TR-03183-2 requires both. So check an SBOM twice: against the schema, and against the fields you need.

CycloneDX 1.7.2: required fields in the document and per component
curl -s https://raw.githubusercontent.com/CycloneDX/specification/1.7.2/schema/bom-1.7.schema.json | jq -c '.required, .definitions.component.required'

Output

["bomFormat","specVersion"]
["type","name"]
SPDX 2.3: required fields in the document and per package
curl -s https://raw.githubusercontent.com/spdx/spdx-spec/v2.3/schemas/spdx-schema.json | jq -c '.required, .properties.packages.items.required'

Output

["SPDXID","creationInfo","dataLicense","name","spdxVersion"]
["SPDXID","downloadLocation","name"]
SPDX 3.0.1: required fields per element and in creationInfo
curl -s https://spdx.org/schema/3.0.1/spdx-json-schema.json | jq -c '."$defs".Element_props.allOf[1].required, ."$defs".CreationInfo_props.allOf[1].required'

Output

["creationInfo"]
["created","createdBy","specVersion"]
SPDX: the latest releases
curl -s https://api.github.com/repos/spdx/spdx-spec/releases | jq -r '.[0:3][] | "\(.tag_name) \(.published_at[0:10]) prerelease=\(.prerelease)"'

Output

v3.1-RC1 2026-01-24 prerelease=true
3.0.1 2024-12-17 prerelease=false
v3.0 2024-04-15 prerelease=false

How do CycloneDX and SPDX describe a firmware component?

For firmware, what counts most is whether a component is identified unambiguously, because matching it against vulnerabilities depends on that. Both formats carry the Package URL (purl) and CPE for this. CycloneDX has the component type firmware, SPDX 2.3 the purpose FIRMWARE, SPDX 3.0.1 the purpose firmware.

Format and version of the export
jq -r '.bomFormat, .specVersion' sbom.json

Output

CycloneDX
1.6
The product itself, as firmware
jq '.metadata.component | {type,name}' sbom.json

Output

{
  "type": "firmware",
  "name": "ble_freertos_amota.axf"
}
A component with a Package URL
jq '.components[] | select(.name=="FreeRTOS") | {type,name,version,purl}' sbom.json

Output

{
  "type": "library",
  "name": "FreeRTOS",
  "version": "10.1.1",
  "purl": "pkg:generic/FreeRTOS@10.1.1"
}

Which differences matter day to day?

TopicCycloneDX and SPDX
IdentifierCycloneDX: purl, CPE, plus OmniBOR and SWHID. SPDX 2.3: externalRefs of the categories SECURITY and PACKAGE-MANAGER. SPDX 3.0.1: cpe22, cpe23, packageUrl, gitoid, swhid, swid.
HashBoth support SHA-512, as the TR requires.
DependenciesCycloneDX: dependencies, completeness via compositions. SPDX 3.0.1: relationships with their own completeness statement.
Vulnerabilities and VEXCycloneDX has VEX states in the format, SPDX 3.0.1 a security profile. Under the TR, vulnerabilities do not belong in the SBOM; they go to the customer as CSAF with a VEX profile (§ 8.1.14).
LicencesBoth with SPDX licence identifiers and expressions. SPDX separates the declared and the concluded licence.

CycloneDX or SPDX: which should I use?

  1. 1

    If a customer or auditor asks for TR-03183-2: CycloneDX 1.6 or later or SPDX 3.0.1 or later, JSON or XML.

  2. 2

    If your toolchain already uses a format: stay with it. Tools convert between the two, but lose fields the target does not know.

  3. 3

    A separate SBOM for each shipped firmware version, from the build that is shipped.

  4. 4

    Keep vulnerability status separately: the SBOM says what is inside, VEX and CSAF say which of it is exploitable.

Questions

Does the CRA prescribe CycloneDX or SPDX?

No. It requires a commonly used and machine-readable format. The Commission may specify the format and elements by implementing acts (Art. 13(24)); as of 23 October 2026 none has been adopted.

Is SPDX 2.3 enough?

For the CRA, yes: it names no format. Since version 2.1.0, BSI TR-03183-2 requires SPDX 3.0.1 or later or CycloneDX 1.6 or later for newly created SBOMs.

Does SPDX 3.1 count for TR-03183-2 yet?

No, not while it exists only as a release candidate. The TR admits only officially released versions of the specifications (§ 4). As of 23 October 2026, 3.0.1 is the latest SPDX release.

Is a schema-valid SBOM complete?

No. Neither CycloneDX nor SPDX requires a version or a hash for each component in the schema. Whether the fields TR-03183-2 or your customer asks for are filled, you check separately.

Do vulnerabilities belong in the SBOM?

TR-03183-2 rules that out: an SBOM that lists vulnerabilities does not meet the TR (§ 8.1.14). Vulnerabilities belong in CSAF with a VEX profile. The reason: the bill of materials changes with the release, the vulnerability situation every day.

Which formats does LegacyMind export?

CycloneDX 1.6 JSON, SPDX 2.3 JSON and SPDX 3.0.1 JSON, plus CSV. We read supplier SBOMs in CycloneDX (JSON, XML) and SPDX (JSON, tag-value, 3.0 JSON-LD).

Sources

  1. [1]CycloneDX: specification
  2. [2]Ecma International: ECMA-424
  3. [3]SPDX: specifications
  4. [4]BSI TR-03183-2, version 2.1.0
  5. [5]Regulation (EU) 2024/2847, Cyber Resilience Act, Official Journal

Check your own image

Upload one firmware image, an AXF or a supplier SBOM in your own LegacyMind account. Report and SBOM within three working days, NDA on request. The app and the reports are in German; questions in English are welcome.