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?
| Format | Versions and status |
|---|---|
| CycloneDX | Current 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. |
| SPDX | SPDX 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.0 | Newly 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
Creator of the component, as an e-mail address or URL.
- 2
Name and version. If there is no version, the modification date of the file.
- 3
File name of the component.
- 4
Dependencies on other components, with a statement of whether the list is complete.
- 5
Distribution licences.
- 6
Hash value of the shipped component, as SHA-512.
- 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.
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"]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"]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"]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=falseHow 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.
jq -r '.bomFormat, .specVersion' sbom.jsonOutput
CycloneDX
1.6jq '.metadata.component | {type,name}' sbom.jsonOutput
{
"type": "firmware",
"name": "ble_freertos_amota.axf"
}jq '.components[] | select(.name=="FreeRTOS") | {type,name,version,purl}' \
sbom.jsonOutput
{
"type": "library",
"name": "FreeRTOS",
"version": "10.1.1",
"purl": "pkg:generic/FreeRTOS@10.1.1"
}Which differences matter day to day?
| Topic | CycloneDX and SPDX |
|---|---|
| Identifier | CycloneDX: 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. |
| Hash | Both support SHA-512, as the TR requires. |
| Dependencies | CycloneDX: dependencies, completeness via compositions. SPDX 3.0.1: relationships with their own completeness statement. |
| Vulnerabilities and VEX | CycloneDX 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). |
| Licences | Both with SPDX licence identifiers and expressions. SPDX separates the declared and the concluded licence. |
CycloneDX or SPDX: which should I use?
- 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
If your toolchain already uses a format: stay with it. Tools convert between the two, but lose fields the target does not know.
- 3
A separate SBOM for each shipped firmware version, from the build that is shipped.
- 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).