Quality, completeness and depth

An incomplete SBOM is worse than no SBOM: it gives false assurance. This page defines what a usable SBOM is and how to verify it automatically.

Quality criteria

Criterion Question Verifiable
Completeness Are all components present? By gap with the analysed SBOM
Accuracy Do the versions match the actual artefact? By hash
Freshness Does the SBOM correspond to the latest build? By timestamp and build reference
Resolvable identifiers Does every component carry a valid purl or cpe? Automatic
Licences populated What proportion of NOASSERTION? Automatic
Relationships expressed Is the dependency graph present? Automatic
No unknowns How many components have no name, no version, or are unidentified? Automatic
Declared completeness Does the composition section honestly state coverage? Automatic

Automated scoring

Every SBOM produced receives a score against these criteria, and the threshold is blocking in CI. The policy must state explicitly:

  • the minimum score for a build to be promotable to production;
  • the maximum tolerated proportion of components without a resolvable identifier;
  • the maximum proportion of NOASSERTION licences;
  • the maximum tolerated gap between build SBOM and analysed SBOM.

Without a numeric threshold, “SBOM quality” remains an intention. With a blocking threshold it becomes a property of the pipeline.

Depth: direct and transitive

The Regulation requires at the very least top-level dependencies. That floor is insufficient in practice.

Direct dependencies Transitive dependencies
Definition Explicitly declared by you Dragged in by your dependencies
Typical volume Dozens Hundreds to thousands
Control You choose them You inherit them
Share of supply chain incidents Minority Majority

The doctrine adopted: full depth, with an explicit direct / transitive distinction in the graph, to support prioritisation and to identify how a problematic component got in.

Which dependencies to include

Category In the shipped product’s SBOM?
Runtime dependencies Yes, no discussion
Build dependencies whose output is embedded Yes
Build dependencies not embedded In a separate build-chain SBOM
Test dependencies No in the product SBOM — their presence is a major cause of false positives
Container base image packages Yes if shipped with the product

The seven traps

1. Statically linked binaries. A C or Rust library compiled into the executable appears in no manifest. Remedy: binary analysis, and language-specific tools.

2. Vendored code. Third-party sources copied into your repository, often modified. Remedy: file-hash detection, of the kind licence-oriented composition analysis tools perform.

3. Container system dependencies. The base image brings in dozens of packages. Remedy: generate the SBOM on the image, not only on the application; shrink the surface with minimal images.

4. Multi-language artefacts. A Python package embedding a compiled native library, a Node module with a binary. Remedy: combine several generators.

5. Code generated at build time. The generator itself has dependencies, and the code it produces may embed some. Remedy: document the generation chain in the SBOM.

6. Firmware. Embedded file systems, partitions, binary blobs. Remedy: firmware analysis tooling, and a contractual SBOM requirement on the platform supplier.

7. Renamed or repackaged components. The same component under two names in two ecosystems. Remedy: normalisation by purl — see Identifiers.

What to write down

A one-page SBOM quality policy setting: format and version, required depth, dependency categories included, minimum score, blocking thresholds, the temporary waiver procedure and its automatic expiry.