Overview
This is the third part of our SBOM compliance series. In the previous post, we discussed Framing Software Component Transparency (FSCT), how it builds on NTIA and shifts the focus from minimum presence to meaningful transparency. In this post, we will discuss BSI TR-03183-2 v1.1, Germany’s SBOM compliance framework, why it exists, what it expects from an SBOM, and how it compares to what we’ve seen so far. Let’s go.
Context
🇩🇪 Germany’s Federal Office for Information Security, known as the BSI (Bundesamt für Sicherheit in der Informationstechnik), published a Technical Guideline TR-03183-2, specifically for Software Bill of Materials. Version 1.1 was released on 2023-11-28, with updates to creator, version, and licence requirements.
But why did Germany need its own SBOM framework?
The answer is the EU Cyber Resilience Act (CRA). The CRA is a regulation from the European Union that makes software security transparency mandatory for any product with digital elements sold in the EU market. Under CRA, manufacturers are required to maintain and provide SBOMs as part of their software lifecycle. And BSI TR-03183-2 is the technical guideline that tells you exactly what that SBOM must contain.
In short: if you are selling software products in the EU or plan to, BSI TR-03183-2 v1.1 or future latest version of BSI such as BSI TR-03183-2 v2.0, BSI TR-03183-2 v2.1, etc is what you need to align with.
BSI’s Definition of SBOM
Before we look at the fields, let’s understand how BSI itself defines an SBOM. This matters because the definition shapes every requirement that follows.
BSI §3.1 defines it as:
“A ‘Software Bill of Materials’ (SBOM) is a machine-processable file containing supply chain relationships and details of the components used in a software product. It supports automated processing of information on these components. This covers both the so-called ‘primary component’ and used (e.g. external/third-party) components.”
What makes BSI different from NTIA and FSCT?
If you’ve followed Part 1 (NTIA) and Part 2 (FSCT), you’ll notice that BSI takes a more structured and technically strict approach. Here’s what sets it apart:
Two-tier field system. BSI divides its fields into two clear categories:
- Required: fields that MUST always be present in the SBOM. No exceptions.
- Additional: fields that MUST be included if the data exists and prerequisites are met. They are not optional in the “nice-to-have” sense. If the data is available, it must be declared.
Machine-actionable contacts only. BSI does not accept a plain name or phone number. Creator fields must carry an email address or, if no email is available, a URL. This is intentional, BSI is designed for automated supply chain workflows where tooling needs to reach out programmatically.
SPDX identifiers for licences. License information must use SPDX identifiers. Free-text names like "Apache License" are not accepted. It must be Apache-2.0.
Recursive dependencies. BSI expects a Build SBOM, one produced during the build process with recursive dependency resolution across the full scope of delivery.
Now, let’s walk through each field.
BSI TR-03183-2 v1.1 Required Fields
BSI §5.2 defines required fields at two levels: for the SBOM document itself, and for each component listed in the SBOM.
SBOM-Level Required Fields
1. Creator of the SBOM
Official definition:
“Email address of the entity that created the SBOM. If no email address is available this MUST be a ‘Uniform Resource Locator (URL)’.”
This is the contact for the SBOM itself, not the software product. BSI requires a machine-actionable contact so that automated tooling can reach out when a new vulnerability affects a component listed in this SBOM. A name alone provides no actionable channel for that.
Accepted values: a valid email (preferred), or a valid URL (fallback).
SBOM Mapping:
SPDX:
creationInfo.creator(Person or Organization entry, email extracted from value)
CycloneDX:
metadata.authors[].emailmetadata.manufacturer.emailormetadata.manufacturer.urlmetadata.supplier.emailormetadata.supplier.url
NOTE: Any one of these sources satisfying the email/URL requirement is sufficient. Only one valid contact is needed.
2. Timestamp
Official definition:
“Date and time of the SBOM data compilation according to the specification of the formats.”
The timestamp ties the SBOM to a specific point in time. Since known vulnerabilities change continuously, automated tools use this timestamp to correctly correlate listed components against vulnerability databases (like NVD or OSV) as of the SBOM’s creation date. It also supports audit trails.
Accepted values: RFC 3339 / ISO 8601 compliant timestamp (e.g., 2025-04-25T00:42:27Z).
SBOM Mapping:
SPDX:
creationInfo.created
CycloneDX:
metadata.timestamp
Component-Level Required Fields
3. Component Creator
Official definition:
“Email address of the entity that created and, if applicable, maintains the respective software component. If no email address is available this MUST be a ‘Uniform Resource Locator (URL)’.”
Same rationale as the SBOM creator, but applied at the component level. If a CVE is discovered in a specific library, automated tooling must be able to identify and contact its maintainer, without any manual intervention. A name alone doesn’t give you that.
Accepted values: valid email (preferred), valid URL (fallback only).
SBOM Mapping:
SPDX:
PackageOriginator(email preferred)PackageSupplier(fallback)
CycloneDX:
components[].authors[].emailcomponents[].manufacturer.emailorcomponents[].manufacturer.urlcomponents[].supplier.emailorcomponents[].supplier.url
4. Component Name
Official definition:
“Name assigned to the software component by its creator.”
The component name is the most fundamental identifier. Without it, an SBOM entry cannot be matched against vulnerability databases, licence registries, or other SBOMs. It is the entry point for all downstream analysis.
SBOM Mapping:
SPDX:
PackageName
CycloneDX:
components[].name
5. Component Version
Official definition:
“Identifier used by the creator to specify changes in the software component to a previously created version.”
Vulnerability tracking is version-specific. A CVE may affect version 1.2.3 of a library but not 1.2.4. Without a version, you cannot determine whether a component instance is actually affected by a known vulnerability. The version is what makes a component entry security-actionable.
SBOM Mapping:
SPDX:
PackageVersion
CycloneDX:
components[].version
6. Dependencies on Other Components
Official definition:
“Enumeration of all components on which this component is directly dependent, according to the requirements in section 5.1.”
BSI doesn’t just ask for a list of dependencies, it requires a recursively resolved dependency graph. Every component in the scope of delivery must enumerate its direct dependencies, and those dependencies must also be present in the SBOM. This continues recursively until you reach the boundary of what is actually shipped.
Think of it as: if your software uses library A, then A is in the SBOM. If A uses library B (and B is within what you deliver), then B is also in the SBOM. No hidden or undeclared dependencies.
NOTE: Leaf components (those with no dependencies) are compliant by simply declaring an empty dependency list.
SBOM Mapping:
SPDX:
Relationshipsof typeDEPENDS_ONorCONTAINS
CycloneDX:
dependencies[]:ref(the component) anddependsOn(its direct dependencies)
7. Licence
Official definition:
“Associated licence(s) of the component from the perspective of the SBOM creator.”
BSI mandates standardized licence identifiers so that licence information is machine-processable across toolchains. Free-text names are not accepted.
The hierarchy of accepted identifiers:
- SPDX identifier (e.g.,
MIT,Apache-2.0) preferred - If not in SPDX list:
LicenseRef-scancode-[...]from the Scancode LicenseDB - If completely unknown:
LicenseRef-<entity>-[...]
SPDX expressions for multiple licences (AND, OR, WITH) are required for dual-licensed or exception cases.
Not accepted: NONE, NOASSERTION, or free-text names without SPDX/LicenseRef format.
SBOM Mapping:
SPDX:
PackageLicenseConcluded(preferred, the SBOM creator’s concluded licence)PackageLicenseDeclared(fallback, the component creator declared license)
CycloneDX:
components[].licenses[].license.id(SPDX identifier)components[].licenses[].expression(SPDX expression)
8. Hash Value of the Executable Component
Official definition:
“Cryptographically secure checksum (hash value) of the component in its executable form as SHA-256.”
A SHA-256 hash of the delivered binary provides a tamper-evident fingerprint. It lets any consumer verify that what they received matches what the SBOM declares, which guards against supply chain attacks where a malicious binary is substituted for the genuine artifact.
SHA-256 only. MD5, SHA-1, SHA-512, and all other algorithms do not satisfy this requirement.
NOTE: This is the hash of the executable (compiled/delivered binary), not the source code. The source code hash is a separate additional field.
SBOM Mapping:
SPDX:
PackageChecksumwith algorithmSHA256
CycloneDX:
components[].externalReferences[]with typedistributionordistribution-intake, including associatedhashes[]withalg=SHA-256
BSI TR-03183-2 v1.1 Additional Fields
Additional fields MUST be provided if they exist and their prerequisites are fulfilled (BSI §5.3). This is an important distinction they are not discouraged or optional in the everyday sense. If the data exists, declaring it is mandatory.
SBOM-Level Additional Fields
9. SBOM-URI
Official definition:
“Uniform Resource Identifier (URI) of this SBOM.”
A URI uniquely identifies the SBOM document itself, independent of where it is stored. It enables automated systems to reference, retrieve, and cross-link SBOMs across the supply chain. It is also essential for associating VEX documents or updated SBOMs with a specific SBOM version.
SBOM Mapping:
SPDX:
documentNamespace
CycloneDX:
serialNumbercombined withversion(together they form a unique SBOM document identifier)
Component-Level Additional Fields
10. Source Code URI
Official definition:
“Uniform Resource Identifier (URI) of the source code of the component, e.g. the URL of the source code repository.”
Knowing where a component’s source code lives enables downstream consumers to audit the code, verify licence compliance by inspecting the actual source, and locate patches when a vulnerability is discovered.
SBOM Mapping:
SPDX:
- No dedicated native field. May be expressed via
ExternalRefwith categoryOTHER.
- No dedicated native field. May be expressed via
CycloneDX:
components[].externalReferences[]with typevcs(preferred) orsource-distribution
11. URI of the Executable Form
Official definition:
“Uniform Resource Identifier (URI) which points directly to the executable form of the component.”
This URI allows automated tools to retrieve the exact distributable artifact the compiled binary, container image, or installable package for integrity verification or deployment automation. It connects the SBOM entry to the actual artifact stored in a registry or distribution platform.
SBOM Mapping:
SPDX:
PackageDownloadLocation
CycloneDX:
components[].externalReferences[]with typedistributionordistribution-intake
12. Hash Value of the Source Code
Official definition:
“Cryptographically secure checksum (hash value) of the component source code as SHA-256.”
Together with the executable hash (field 8), this establishes a verifiable chain from source to binary. It enables detection of cases where the distributed binary does not match what was actually built from the declared source, a common indicator of a compromised build pipeline.
SBOM Mapping:
SPDX:
PackageVerificationCode(closest available SPDX field)
CycloneDX:
components[].externalReferences[]with typevcsorsource-distribution, including associatedhashes[]withalg=SHA-256
13. Other Unique Identifiers
Official definition:
“Other identifiers that can be used to identify the component or to look it up in relevant databases, such as Common Platform Enumeration (CPE) or Package URL (purl).”
Standard identifiers like PURL and CPE enable automated cross-referencing against vulnerability databases (NVD, OSV, GitHub Advisory Database). Without them, matching a component to external databases requires fuzzy name/version matching, which is error-prone and not machine-reliable.
Accepted values:
- PURL (e.g.,
pkg:npm/lodash@4.17.21) - CPE (e.g.,
cpe:2.3:a:lodash:lodash:4.17.21:*:*:*:*:*:*:*)
SBOM Mapping:
SPDX:
ExternalRefwith categoryPACKAGE-MANAGER, typepurlExternalRefwith categorySECURITY, typecpe22Typeorcpe23Type
CycloneDX:
components[].purlcomponents[].cpe
BSI TR-03183-2 v1.1 Field Summary Table
| # | Field | Level | Category | BSI Section |
|---|---|---|---|---|
| 1 | Creator of the SBOM | SBOM | Required | §5.2.1 |
| 2 | Timestamp | SBOM | Required | §5.2.1 |
| 3 | Component creator | Component | Required | §5.2.2 |
| 4 | Component name | Component | Required | §5.2.2 |
| 5 | Component version | Component | Required | §5.2.2 |
| 6 | Dependencies on other components | Component | Required | §5.2.2 |
| 7 | Licence | Component | Required | §5.2.2 |
| 8 | Hash value of executable | Component | Required | §5.2.2 |
| 9 | SBOM-URI | SBOM | Additional | §5.3.1 |
| 10 | Source code URI | Component | Additional | §5.3.2 |
| 11 | URI of the executable form | Component | Additional | §5.3.2 |
| 12 | Hash value of source code | Component | Additional | §5.3.2 |
| 13 | Other unique identifiers | Component | Additional | §5.3.2 |
How to evaluate your SBOM against BSI TR-03183-2 v1.1
At this point, we’ve looked at why BSI TR-03183-2 v1.1 exists and what each field expects. The next natural question is:
How do you actually check whether your SBOM meets BSI v1.1 requirements?
This is where sbomqs comes in.
sbomqs is an open-source CLI tool that evaluates SBOMs after they are generated. It checks both SBOM quality and compliance against standard frameworks, including BSI TR-03183-2 v1.1.
For a deeper look at how sbomqs scoring works and how scores are structured, see our earlier post on sbomqs BSI scoring support.
Run a single command to score your SBOM against BSI v1.1:
sbomqs score --profile bsi-v1.1 your-sbom.cdx.json
And the o/p looks like this:
sbomqs score --profile bsi-v1.1 validFullyCompliantBsiV11.cdx16.json
SBOM Quality Score: 10.0/10.0 Grade: A Components: 2 EngineVersion: 6 File: validFullyCompliantBsiV11.cdx16.json
+---------------------+-------------------------+------------------------+--------------------------------+
| PROFILE | FEATURE | STATUS | DESC |
+---------------------+-------------------------+------------------------+--------------------------------+
| BSI TR-03183-2 v1.1 | sbom_creator | 10.0/10.0 | SBOM creator contact(email) |
| | | | provided via authors |
+ +-------------------------+------------------------+--------------------------------+
| | sbom_timestamp | 10.0/10.0 | SBOM creation timestamp is |
| | | | valid and RFC3339-compliant. |
+ +-------------------------+------------------------+--------------------------------+
| | comp_creator | 10.0/10.0 | creator contact (email or URL) |
| | | | declared for all components |
+ +-------------------------+------------------------+--------------------------------+
| | comp_name | 10.0/10.0 | component name declared for |
| | | | all components |
+ +-------------------------+------------------------+--------------------------------+
| | comp_version | 10.0/10.0 | component version declared for |
| | | | all components |
+ +-------------------------+------------------------+--------------------------------+
| | comp_depth | 10.0/10.0 | Dependencies are recursively |
| | | | declared and structurally |
| | | | complete. |
+ +-------------------------+------------------------+--------------------------------+
| | comp_license | 10.0/10.0 | licence information declared |
| | | | for all components |
+ +-------------------------+------------------------+--------------------------------+
| | comp_hash | 10.0/10.0 | primary executable declares a |
| | | | valid SHA-256 hash. |
+ +-------------------------+------------------------+--------------------------------+
| | sbom_uri | 10.0/10.0 (additional) | SBOM-URI is declared. |
+ +-------------------------+------------------------+--------------------------------+
| | comp_source_url | 10.0/10.0 (additional) | Source code URI declared for |
| | | | all components. |
+ +-------------------------+------------------------+--------------------------------+
| | comp_executable_url | 10.0/10.0 (additional) | Executable URI declared for |
| | | | all components. |
+ +-------------------------+------------------------+--------------------------------+
| | comp_source_hash | 10.0/10.0 (additional) | source hash declared for all |
| | | | components. |
+ +-------------------------+------------------------+--------------------------------+
| | comp_unique_identifiers | 10.0/10.0 (additional) | Unique identifiers declared |
| | | | for all components. |
+---------------------+-------------------------+------------------------+--------------------------------+
Summary:
Required Fields : 8/8 compliant
Additional Fields : 5/5 compliant
Love to hear your feedback https://forms.gle/anFSspwrk7uSfD7Q6
The o/p gives you two clear sections:
- Required fields (8 checks): mapped exactly to BSI §5.2: creator, timestamp, component identity, dependencies, licence, and executable hash.
- Additional fields (5 checks, marked
additional): mapped to BSI §5.3: SBOM-URI, source code URI, executable URI, source hash, and unique identifiers.
Notice the (additional) label in the STATUS column, sbomqs clearly distinguishes required from additional, so you know exactly which tier each field belongs to.
For most real-world SBOMs generated by standard tools, the Required Fields score will vary depending on how completely your tooling captures component metadata. The Additional Fields score depends on how much supplementary data (source URLs, executable URIs, unique identifiers) your build pipeline provides.
Conclusion and what’s next
In this post, we discussed BSI TR-03183-2 v1.1 Germany’s SBOM compliance framework and a key reference point for EU Cyber Resilience Act readiness. We looked at the motivation behind it: not just a list of fields, but a framework designed for machine-processable, automated supply chain workflows where tooling needs to act on SBOM data without human intervention.
We discussed its distinctive two-tier structure. Required fields that must always be present, and Additional fields that must be included whenever the underlying data exists. We walked through all 13 fields: what BSI officially expects, why each field matters, and how it maps to SPDX and CycloneDX. And we saw how sbomqs evaluates your SBOM against BSI v1.1 with a single command, clearly separating required from additional compliance.
If you are building software products targeting the EU market, aligning with BSI TR-03183-2 v1.1 now puts you ahead of the CRA curve.
In the next post of this series, we’ll look at BSI TR-03183-2 v2.0.0.