All knowledge articles

SBOMs: What They Solve and What They Do Not

A Software Bill of Materials gives fast, accurate vulnerability-impact assessment against a known component inventory — and nothing more. What it does not do: prove the software is safe, verify build integrity, stop a malicious dependency from being included, or exceed the accuracy of its own generation process.

Supply Chain SecurityCI/CD PipelinesVulnerability Management

A Software Bill of Materials (SBOM) is a structured, machine-readable inventory of the components that went into building a piece of software — typically expressed in a standard format such as SPDX or CycloneDX, listing components alongside identifying metadata like name, version, supplier, and how components relate to one another. Its proven, concrete value is speed: when a new vulnerability is disclosed in a widely used library, an organization with accurate SBOMs across its shipped software can answer 'which of our artifacts include this component' in minutes by querying existing data, instead of manually tracing dependency trees across every repository and pipeline it owns.

What an SBOM captures versus what it can missDeclared source dependencies feed a build process, which feeds SBOM generation, which produces a shipped artifact together with its SBOM. Interactive: switch between the normal path, where SBOM generation accurately records everything the build process actually used, and a failure mode showing a dependency fetched dynamically at runtime — after the build finished — that never passes through SBOM generation at all, producing a coverage gap between what the SBOM says is present and what is actually running. Explore each node for details.Declared sourcedependenciesBuildprocessSBOMgenerationShipped artifact+ SBOMCoverage gap: absentfrom SBOMRuntime-fetcheddependency

Hover or focus a node to explore it.

Fictional build: declared source dependencies → build process → SBOM generation → shipped artifact. In the failure mode, a dependency fetched dynamically at runtime bypasses the build process and SBOM generation entirely, so it ends up running inside the shipped artifact without ever appearing in that artifact's own SBOM.
01

Executive summary

This guide is about the gap between that real value and the much broader assurance an SBOM is often assumed to provide. An SBOM is an inventory, not a verdict. It does not prove the software is safe, does not verify that the artifact was actually built the way its records claim, does not stop a malicious dependency from being included in the first place, and is only ever as accurate as the process that generated it. None of that makes an SBOM useless — it makes it a specific, bounded tool that answers one class of question well and several adjacent questions not at all.

02

What you will learn

  • What an SBOM actually is — a structured component inventory in a standard format — and the specific operational problem it solves well: fast, accurate vulnerability-impact assessment when a new CVE is disclosed.
  • Why an SBOM is fundamentally a list, not a verdict: it says nothing on its own about whether a listed component is well-written, correctly configured, or free of undisclosed vulnerabilities.
  • Why an SBOM does not verify build integrity, and how that question is a separate concern from component inventory — addressed by build-provenance practices, not by the SBOM itself.
  • Why an SBOM cannot stop a malicious or dependency-confused package from being included in the first place — it is a downstream record of what happened, not an upstream gate deciding what is allowed to happen.
  • Why an SBOM's accuracy is entirely bounded by its generation method, and where the common coverage gaps actually come from — dynamically fetched or runtime-loaded components chief among them.
  • A repeatable way to evaluate whether an SBOM practice is producing something a team can actually rely on during an incident, versus producing paperwork that looks complete without being tested.
03

Intended audience

  • Developers who ship software and are being asked to produce an SBOM, without necessarily having a clear model of what question it does and doesn't answer.
  • DevOps practitioners standing up SBOM generation inside a build pipeline and deciding how it should actually work.
  • Security engineers who receive SBOMs — from an internal team or a vendor — and need to know how much evidentiary weight that document actually carries.
04

Problem or security question

SBOM adoption has often been driven from the outside in — a customer questionnaire, a contract clause, a procurement requirement — rather than from a team's own decision about what problem it needed solved. That ordering matters, because it creates pressure to treat 'we can produce an SBOM' as equivalent to 'we manage our software supply-chain risk,' when those are different claims with very different levels of assurance behind them. A team can generate a technically well-formed SBOM for every release and still have no better answer than before to questions like 'was this artifact built the way we think it was' or 'did anything malicious slip into this dependency tree before the SBOM was generated.'

The actual, well-supported value of an SBOM shows up at a specific moment: the day a serious vulnerability is disclosed in a component used somewhere across an organization's software. Without an SBOM, answering 'are we affected, and where' means manually inspecting manifests, lockfiles, or installed packages across every repository and build pipeline the organization maintains — slow, error-prone, and easy to get wrong under the time pressure a live disclosure creates. An accurate SBOM turns that into a query. That is a real, specific, and valuable capability. It is also a narrower capability than 'supply-chain security,' and confusing the two is where an SBOM's assurance tends to get overstated.

05

Threat model or relevant risk

Frame this less as attacker-versus-defender and more as: what does having an SBOM actually change, and what stays exactly as risky as before. What it changes is response time and completeness during vulnerability-impact assessment — the specific scenario above. What it does not change, on its own: whether a component already included in the dependency tree is malicious or compromised (the SBOM will simply, correctly, list it); whether the build process that produced the artifact was itself trustworthy and free of tampering (a separate question — see 'validation, not observation' in the main content below); and whether every component that ends up running inside the shipped artifact was actually captured by the generation process in the first place.

That last point is the specific failure mode this guide's diagram illustrates: a component that a deployed application fetches on its own, at startup or during operation, rather than one installed during the build. Because SBOM generation commonly works by observing what a build process resolved and installed, a component that enters the system through a different path — a plugin pulled at runtime, a module loaded dynamically based on configuration — was never present for the generator to see. The resulting SBOM isn't wrong about what it lists; it is silently incomplete about what actually ships and runs.

A second, related gap runs in the opposite direction: build-time-only tooling — a compiler plugin, a code generator, a test-only library — that never ships as part of the running artifact but does execute during the build with whatever access the build process has. Whether that tooling belongs in a 'what we ship' SBOM is a scope question the generation process has to answer deliberately; treated carelessly, it produces either an SBOM that omits a real execution-time risk (the tool itself has a vulnerability, but nobody tracks it because it 'isn't shipped') or one so broad it buries the components that actually matter to a downstream consumer.

06

Main technical content

**An SBOM is a format-level answer to 'what's in here,' not a security judgment.** The two dominant machine-readable SBOM formats are SPDX, an open standard maintained by the Linux Foundation and published as ISO/IEC 5962:2021, and CycloneDX, an OWASP project now also published as the Ecma International standard ECMA-424. Both represent a software artifact as a structured list of components together with identifying metadata — name, version, supplier, and the relationships between components — and both are designed to be produced and consumed by tooling rather than read as prose. Neither format, by itself, expresses a judgment about whether any listed component is safe to use. That distinction matters more than it sounds: a perfectly well-formed, standards-compliant SBOM can faithfully describe a dependency tree that includes a component with a known, unpatched, critical vulnerability, and the SBOM will have done exactly what it's for by listing it accurately.

**The real, provable value is speed during vulnerability-impact assessment.** When a widely used library discloses a new vulnerability, the operational question every affected organization faces is the same: which of our shipped artifacts include this component, at which version, and where. Without SBOM data, answering that requires manually inspecting manifests, lockfiles, or installed packages across however many repositories and pipelines the organization maintains — a process that scales badly and is easy to get wrong under time pressure. With accurate SBOM data collected across an organization's software, that same question becomes a lookup against existing records. This is the concrete, well-supported capability an SBOM provides — not a general promise about supply-chain risk being 'handled.'

**What an SBOM does not do: prove the software is safe.** Presence of a component in a well-formed SBOM is a statement of fact about inventory, not a statement about quality or trustworthiness. The NTIA's 2021 baseline guidance on SBOM minimum elements — since built on by more recent guidance from CISA — describes the data fields a usable SBOM should carry: things like component name, version, supplier, dependency relationships, and who generated the data and when. Those are identification and provenance fields. None of them assert that the identified component is well-written, correctly configured for its use, or free of vulnerabilities that simply haven't been disclosed yet. An SBOM answers 'what is present,' not 'is what's present okay.'

**What an SBOM does not do: verify build integrity.** Knowing what components a build used and knowing that the resulting artifact was actually produced the way records claim are two separate questions, addressed by two separate kinds of control. The SBOM answers the first. Build-provenance frameworks — SLSA (Supply-chain Levels for Software Artifacts, slsa.dev) is the widely referenced example — address the second, through practices like generating signed, verifiable provenance about how and where a build ran, and hardening the build environment itself against tampering. An artifact can ship with a completely accurate SBOM while the build process that produced it was compromised in a way the SBOM has no mechanism to detect — the SBOM describes intended inputs, not a guarantee about what actually happened to them during the build. The build environment's own trustworthiness is a distinct concern from component inventory; see 'Why Build Runners Should Be Treated as Untrusted' for that question specifically, which this guide deliberately does not repeat.

**What an SBOM does not do: stop a malicious dependency from being included.** An SBOM is generated downstream of the decision to include a component, not upstream of it as a gate. If a malicious or dependency-confused package gets installed during a build — see 'Dependency Confusion and Package-Name Trust' for how that specific failure happens — a working SBOM generator will typically do exactly what it's designed to do: record that the package is present, correctly, alongside everything else. The SBOM has no way to distinguish 'this component was deliberately and safely chosen' from 'this component snuck in through a resolution failure,' because that distinction depends on intent and trust decisions the generator was never given visibility into. Catching that kind of inclusion is a job for registry-resolution and namespace controls applied before or during the build, not for the inventory produced afterward.

**Accuracy is entirely bounded by generation method — and this is where most real-world coverage gaps come from.** A static, manifest-based generator that walks a package manifest or lockfile can only describe what that manifest declares; it will miss anything installed or fetched outside that declared set. A build-observed generator that watches what an actual build process resolves and installs is more accurate about that specific build, but still cannot see anything a deployed application later fetches on its own — a plugin pulled at runtime, a module loaded dynamically based on configuration — because that activity happens after the build the generator was watching has already finished. The diagram accompanying this article shows exactly this case: a runtime-fetched dependency bypasses both the build process and SBOM generation entirely, ending up inside the shipped artifact without ever appearing in that artifact's own SBOM. The opposite scope problem also exists: an overly broad generator that captures build-only tooling (compilers, code generators, test-only libraries) alongside genuinely shipped runtime components can make an SBOM look inflated with things a consumer will never actually run, obscuring the components that matter.

**Treat an SBOM's evidentiary weight as bounded by its documented scope, not by its formatting.** A well-formatted, standards-compliant SBOM produced by a generator with an undocumented or poorly understood scope is not more trustworthy than a rougher one whose limitations are written down plainly. The useful question to ask of any SBOM is not 'is this valid SPDX or CycloneDX' — that's a necessary, mechanical property — but 'what could this generation process actually see, and what could it structurally never have seen.' Answering that honestly is what turns an SBOM from a compliance artifact into something a team can actually use during an incident.

07

Requirements

  • Access to, or the ability to run, an SBOM generation tool integrated with your actual build process — not only a manifest file inspected in isolation.
  • A documented understanding of what your current generation tool's scope actually covers: static manifest parsing, build-observed resolution, or some hybrid, and whether it includes or excludes build-only tooling.
  • Authority, or a path to someone with authority, to change build tooling if generation needs to move from manifest-based to build-observed.
08

Procedure

  • Inventory what SBOM, if any, your build currently produces, and identify which generation method created it: static manifest parsing, build-observed resolution, or a hybrid of the two.
  • Identify categories of dependency your current generation method might not be capturing: components fetched dynamically at runtime, build-only tooling that executes during the build but isn't part of the shipped runtime footprint, and anything installed through a mechanism your SBOM tool doesn't understand.
  • For a representative sample of shipped artifacts, test whether existing SBOM data alone is sufficient to answer 'are we affected' for a disclosed vulnerability in a widely used component — treat any manual digging required beyond the SBOM as a documented gap, not a one-off inconvenience.
  • Cross-check SBOM output against an independent method for at least one artifact — for example, inspecting a running instance's actually loaded modules in a lab or non-production environment — to confirm the SBOM's declared scope matches what is genuinely present.
  • Document the generation method, its scope, and any known gaps alongside the SBOM itself, so a consumer of the SBOM — internal or external — knows what confidence to place in it rather than assuming completeness from formatting alone.
  • Establish a cadence for regenerating SBOMs on every build or release, rather than treating a single snapshot as permanently accurate.
09

Validation

  • Confirm that a newly disclosed vulnerability in a component listed in the SBOM can be traced to every affected artifact using SBOM data alone, within a reasonable time, without manual dependency-tree archaeology.
  • Confirm that any component known to be fetched dynamically at runtime is explicitly documented as out of SBOM scope, rather than silently absent with no accompanying note.
  • Confirm the SBOM's declared generation method matches how it was actually produced, by spot-checking the SBOM against the lockfile or manifest actually used for a specific build.
  • Record any generation gap discovered during this process as UNVERIFIED coverage rather than assuming completeness because the generation tool reported success.
10

Rollback

  • If moving to build-observed generation surfaces performance or tooling problems, keep manifest-based generation as a documented, explicitly-labeled fallback while investigating, rather than reverting silently without recording the gap it reintroduces.
  • If cross-checking reveals your SBOM's real scope is narrower than assumed — for example, missing runtime-loaded components — do not continue treating the existing SBOM as complete; update its documented scope statement immediately, even before the underlying tooling gap can be fixed.
  • If a generation-process change breaks a downstream consumer expecting a specific SBOM format or schema version, coordinate the change with them directly rather than silently altering structure they depend on.
11

Validation or evidence

This guide describes SBOM formats, standards, and generation-method distinctions grounded in the cited standards documentation; it does not include a reproduced generation exercise, a specific tool benchmark, or a completed assessment of a real pipeline's SBOM output. Its evidence state remains UNVERIFIED — the technical claims are grounded in the cited standards and guidance, not in an exercise performed for this article.

12

Limitations

This guide covers what an SBOM is, what it proves, and what it structurally cannot prove. It does not compare or evaluate specific commercial or open-source SBOM generation tools, and it does not provide regulatory or contractual compliance guidance — SBOM-related requirements vary by jurisdiction, industry, and counterparty, and change over time; consult current authoritative guidance for compliance-specific questions rather than this guide.

It does not repeat 'Dependency Confusion and Package-Name Trust' (registry-resolution trust — how a malicious package gets included) or 'Why Build Runners Should Be Treated as Untrusted' (the build environment's own blast radius) — both are related, distinct concerns this guide deliberately leaves to those articles.

It does not detail every field in the SPDX or CycloneDX specifications, or walk through the full SLSA build-track requirements; it describes each at the level needed to support the distinctions this guide draws, and points to the primary sources for anyone implementing against them directly.

13

Defensive recommendations

  • Generate SBOMs from the actual build process where feasible — recording what a specific build resolved and installed — rather than solely parsing a manifest in isolation, to reduce the gap between declared and actual dependencies.
  • Document the generation method and scope for every SBOM you produce or consume: what it includes, what it deliberately excludes (dev dependencies, build-only tooling), and what it structurally cannot see (runtime-fetched or dynamically loaded components), so anyone relying on it knows how much confidence to place in it.
  • Treat SBOM data as one input to vulnerability-impact assessment, not a substitute for build-provenance verification, dependency-trust controls, or code review — pair it with the controls those other concerns actually require.
  • Separately inventory and monitor any components your architecture fetches dynamically at runtime, since a build-time SBOM generator cannot see them by construction; this needs a different detection approach entirely, not a more thorough SBOM generator.
  • Regenerate SBOMs on every build or release rather than relying on a single point-in-time snapshot, since dependency trees change between releases even when source code doesn't.
  • Prefer a standard, widely supported format — SPDX or CycloneDX — over a bespoke listing, so SBOM data remains machine-comparable across your own tooling and any consumer's tooling.
14

Key takeaways

  • An SBOM's proven value is fast, accurate vulnerability-impact assessment when a new CVE is disclosed — not a general supply-chain-security guarantee.
  • An SBOM is a downstream inventory, not an upstream gate: it cannot stop a malicious or dependency-confused package from being included, and it cannot verify that the build producing the artifact was itself trustworthy.
  • An SBOM's accuracy is entirely bounded by its generation method; static, manifest-based generation systematically misses dependencies fetched dynamically at runtime, after the build has already finished.
  • Pair SBOM inventory with build-provenance controls (SLSA) and dependency-trust controls (registry and namespace configuration) — none of these three concerns substitutes for the other two.
15

References

  • NTIA, "The Minimum Elements For a Software Bill of Materials (SBOM)" (2021): https://www.ntia.gov/report/2021/minimum-elements-software-bill-materials-sbom
  • CISA, updated minimum-elements guidance for a Software Bill of Materials: https://www.cisa.gov/resources-tools/resources/2026-minimum-elements-software-bill-materials-sbom
  • SPDX Specification (ISO/IEC 5962:2021), Linux Foundation: https://spdx.dev/
  • OWASP CycloneDX (Ecma International ECMA-424): https://cyclonedx.org/
  • SLSA — Supply-chain Levels for Software Artifacts: https://slsa.dev/