When people talk about SBOM quality, they almost always mean one thing: completeness. Does the SBOM list all the components? That matters, obviously. But completeness is the bare minimum. An SBOM can list every single dependency and still be functionally useless if the data is stale, inaccurate, or lacks the context needed to act on it.
We have reviewed thousands of SBOMs at Safeguard, and the quality gap between "technically complete" and "actually useful" is enormous. Here is the framework we use to evaluate SBOM quality across five dimensions.
Dimension 1: Completeness
Let us get this one out of the way first since it is the one everyone talks about.
Completeness means the SBOM accounts for all software components in the artifact it describes. This includes:
- Direct dependencies -- what your manifest file declares
- Transitive dependencies -- what your dependencies depend on
- Build tools and plugins -- compilers, linters, bundlers that affect the output
- Embedded components -- vendored libraries, copied code, statically linked binaries
- System-level dependencies -- base images, OS packages, runtime libraries
Most SBOM generators handle the first two well. The rest is where completeness breaks down. We routinely see SBOMs that capture 100% of npm dependencies but miss the Alpine packages in the container base image, the Webpack plugins used during build, or the vendored C library that handles TLS.
Metric: Component coverage ratio -- the number of components in the SBOM versus the total number of identifiable components in the artifact. This requires ground truth, which is why automated SBOM quality assessment typically requires comparing multiple generation tools against each other.
Dimension 2: Accuracy
An SBOM can be complete but wrong. Accuracy means the metadata associated with each component is correct.
The most common accuracy failures we see:
Version pinning errors. The SBOM says a package is version 2.3.1 but the actual deployed artifact contains 2.3.0. This happens when SBOMs are generated from lock files that have drifted from the actual build.
Identifier mismatches. A component's CPE (Common Platform Enumeration) or PURL (Package URL) does not match the actual package. This breaks vulnerability correlation -- you think you are running one package, the vulnerability database thinks you are running something else, and real vulnerabilities go undetected.
License misidentification. The SBOM reports a component as MIT-licensed when it actually uses AGPL. This happens frequently with packages that changed licenses between versions.
Supplier attribution errors. The wrong organization is listed as the component supplier, which matters for trust evaluation and regulatory compliance.
Metric: We use a sampling-based accuracy score. Pick N components randomly, verify their metadata against the actual artifact, and calculate the percentage that are fully correct. Our threshold for production SBOMs is 95% accuracy.
Dimension 3: Freshness
An SBOM is a snapshot. The moment it is generated, it starts aging. Freshness measures how well the SBOM reflects the current state of the software it describes.
There are two aspects to freshness:
Generation freshness -- how recently was the SBOM generated relative to the last change in the software? An SBOM generated during last week's build does not reflect this week's hotfix.
Vulnerability data freshness -- how recently were vulnerability correlations updated? New CVEs are published daily. An SBOM that was correlated against vulnerability data a month ago may have significant gaps.
Metric: Time delta between SBOM generation and latest artifact modification, plus time delta between last vulnerability correlation and current date. Both should be measured in hours, not days.
Dimension 4: Depth
Depth measures how much useful metadata each component entry contains beyond the minimum identifier and version.
A minimal SBOM entry has: name, version, type. A deep SBOM entry adds:
- Hash values (SHA-256, SHA-512) for integrity verification
- Download location for provenance
- PURL for universal identification
- CPE for NVD correlation
- License expression (SPDX format)
- Supplier information
- Dependency relationships (what depends on what)
- Scope indicators (runtime vs. devDependency)
- External references (source repo, issue tracker, build system)
Depth matters because it determines what you can do with the SBOM. Without hash values, you cannot verify integrity. Without PURLs, you cannot correlate across ecosystems. Without dependency relationships, you cannot do reachability analysis. Without license expressions, you cannot do compliance checking.
Metric: Average number of populated optional fields per component, normalized against the total available fields in the SBOM format being used.
Dimension 5: Actionability
This is the dimension most people miss entirely. Actionability measures whether the SBOM, as delivered, enables the recipient to actually do something useful with it.
Factors that affect actionability:
Format compliance. Does the SBOM conform to its declared format (CycloneDX, SPDX) without validation errors? We see a surprising number of SBOMs that claim to be CycloneDX 1.5 but fail schema validation.
Correlation readiness. Can automated tools successfully correlate the SBOM's components against vulnerability databases? This requires accurate identifiers (PURLs, CPEs) and standard naming conventions.
Context sufficiency. Does the SBOM include enough context to determine the severity of a discovered vulnerability? For example, knowing that a vulnerable component is only in devDependencies (and not in the production artifact) changes the risk assessment entirely.
Machine readability. Is the SBOM in a format that tools can parse without custom adapters? JSON-formatted CycloneDX and SPDX are the gold standard here. PDF SBOMs exist and they are essentially useless for automation.
Metric: Percentage of components that can be successfully correlated against at least one vulnerability database, plus format validation pass/fail.
Putting It Together: A Scoring Model
We use a weighted composite score:
| Dimension | Weight | Scale | |-----------|--------|-------| | Completeness | 25% | 0-100 | | Accuracy | 30% | 0-100 | | Freshness | 15% | 0-100 | | Depth | 15% | 0-100 | | Actionability | 15% | 0-100 |
Accuracy gets the highest weight because an inaccurate SBOM is actively harmful -- it creates false confidence. Completeness is next because missing components are missing risk. The remaining dimensions are equally weighted.
In practice, we see the following quality distribution among SBOMs submitted to Safeguard:
- Excellent (85-100): 12% of SBOMs
- Good (70-84): 28% of SBOMs
- Acceptable (55-69): 35% of SBOMs
- Poor (below 55): 25% of SBOMs
The most common path from "poor" to "good" is improving accuracy (fixing identifier formats) and depth (adding hash values and PURLs). These are typically configuration changes in the SBOM generation tool, not fundamental process changes.
How Safeguard.sh Helps
Safeguard.sh automatically scores SBOM quality across all five dimensions when you upload or generate an SBOM. Our dashboard surfaces quality issues with specific, actionable recommendations -- "Component X is missing a PURL," "SBOM was generated 14 days after the last commit." Our policy gates can enforce minimum quality thresholds, ensuring that low-quality SBOMs do not enter your supply chain workflows. Better SBOM quality means better vulnerability detection, faster triage, and more reliable compliance reporting.