Safeguard
Concepts

What is an SBOM Drift

SBOM drift is the gap between what your software bill of materials claims and what the artifact actually contains. Here's how it happens and how to detect it with a diff.

Elena Kovacs
Compliance Architect
7 min read

SBOM drift is the divergence between what a software bill of materials documents and what the corresponding artifact actually contains. The SBOM says openssl 3.0.8; the running container has 3.0.12 because the base image was rebuilt. Or the SBOM was generated from package.json while the deployed bundle includes a dependency that a postinstall script fetched at build time. An SBOM is a snapshot of one build at one moment, and everything that happens after that moment — rebuilds, base image updates, hotfixes, floating tags — pulls the artifact away from the document. A drifted SBOM is worse than no SBOM, because people make incident-response and compliance decisions based on a list that is quietly wrong.

Where drift comes from

Drift is rarely malicious. It falls out of normal build mechanics:

  • Floating references. FROM node:20 or FROM ubuntu:latest resolves to a different image digest next month. Same Dockerfile, different 400 packages. Any SBOM generated last month no longer describes this month's rebuild.
  • Unpinned dependency ranges. A requirements.txt with requests>=2.28 or an npm range like ^4.17.0 means two builds a week apart can produce different trees. The SBOM describes whichever tree existed on generation day.
  • SBOMs generated from the wrong input. Scanning the source manifest instead of the built artifact misses everything the build itself introduces: vendored code, compiled-in static libraries, files fetched by curl in a Dockerfile RUN step, packages installed by a postinstall hook.
  • Post-build mutation. Someone kubectl execs into a pod and installs a debugging tool, or a hotfix is applied directly to a long-lived VM. The artifact changed; no build ran; no SBOM was regenerated.
  • Registry tag reuse. Pushing a new image over an existing tag (myapp:1.4.2) while the SBOM store still associates that tag with the old build. Content-addressing by digest exists precisely to prevent this.

The polyfill.io incident in June 2024 is the CDN-flavored version of the same problem: what pages actually loaded diverged from what anyone had reviewed, because the reference was floating and the content behind it changed ownership.

Why it matters more than it sounds

The whole point of an SBOM is answering "are we affected?" in minutes instead of days. When Log4Shell dropped, organizations with accurate SBOMs grepped for log4j-core and had an answer before lunch. With a drifted SBOM you get a confident wrong answer — arguably worse than the honest "we don't know," because it ends the investigation.

Compliance raises the stakes. Executive Order 14028 and the follow-on OMB M-22-18 attestation requirements push vendors to provide SBOMs to US federal buyers; the FDA now expects SBOMs in premarket submissions for medical devices. An SBOM you hand to a customer is an assertion about the product. If an auditor or a customer's security team regenerates one from your artifact and gets a materially different list, you have a credibility problem, not just a tooling one.

Detecting drift: regenerate and diff

Detection is conceptually simple: generate a fresh SBOM from the artifact as it exists now, and diff it against the stored SBOM from build time.

# Stored at build time
syft registry:myco/api@sha256:3f1b... -o cyclonedx-json > sbom-build.json

# Regenerated now, from the same digest (or the running image)
syft registry:myco/api:1.4.2 -o cyclonedx-json > sbom-now.json

# Diff at the component level
sbom-utility diff --input-file sbom-build.json --input-revision sbom-now.json

If the diff at the same digest is non-empty, your SBOM generator changed behavior between runs (tool version drift is its own category — pin your syft version in CI). If you're diffing across a tag rather than a digest and the diff is non-empty, the tag was rebuilt or overwritten, and every consumer of the old SBOM is misinformed.

For running workloads, compare the SBOM against what a runtime agent or an in-cluster scan actually observes. The delta between "documented," "present," and "loaded at runtime" is also the basis for reachability filtering in SCA tooling — the same machinery that tells you a vulnerable package isn't loaded can tell you an undocumented package is.

We covered automation patterns for this in more depth in automated SBOM drift detection.

Preventing drift structurally

You can't prevent artifacts from changing; you can make every change produce a fresh, correctly-associated SBOM.

  1. Generate the SBOM in the build, from the artifact. Not from source manifests, not in a nightly batch job. The SBOM step runs after the image is built, against the image: syft <image-digest> as a CI stage, or BuildKit's native --attest type=sbom on docker buildx build.
  2. Key SBOMs by digest, never by tag. Store and retrieve by sha256 digest. Attach the SBOM to the image as an attestation (cosign attest --predicate sbom.json --type cyclonedx <digest>) so the association is cryptographic rather than a row in a database that can go stale.
  3. Pin your inputs. Base images by digest, lockfiles committed and enforced (npm ci, pip install --require-hashes, poetry.lock). Pinning doesn't stop drift across intentional rebuilds, but it makes builds reproducible enough that drift becomes a signal instead of noise.
  4. Make post-build mutation an event. Immutable infrastructure policies (read-only root filesystems, no exec in production namespaces) turn "someone changed the artifact without a build" from routine into an alert.
  5. Rescan stored SBOMs against new advisories. This isn't drift prevention, but it's the companion discipline: the artifact may be unchanged while the world's knowledge about it changes. A drift-free SBOM pipeline plus continuous re-analysis — the model behind SBOM Studio — covers both directions.

A quick maturity check

LevelPracticeDrift exposure
0No SBOMs, or one-off exports on requestTotal — every answer is archaeology
1SBOM per release, generated from manifestsHigh — build-time additions invisible
2SBOM per build, generated from artifact, stored by tagMedium — tag overwrites still lie
3SBOM per build, keyed by digest, attached as signed attestationLow — drift is detectable and attributable
4Level 3 plus runtime reconciliation and scheduled diffsMinimal — drift raises an alert within hours

Most organizations we talk to sit at level 1 and believe they're at level 3. The regenerate-and-diff exercise above takes an afternoon and settles the question.

Frequently asked questions

Is SBOM drift the same as configuration drift?

Same shape, different object. Configuration drift is running systems diverging from their declared infrastructure-as-code definitions; SBOM drift is artifacts diverging from their declared component inventory. The remedies rhyme too: immutable references, regenerate-and-diff, and treating out-of-band mutation as an incident.

How often should I regenerate SBOMs to catch drift?

Regenerate on every build automatically — that's the baseline, not a schedule. For long-lived artifacts that rarely rebuild, a weekly scheduled diff between stored SBOM and current artifact state catches mutation and tooling drift. Anything less frequent than your deploy cadence guarantees blind spots.

Does a signed SBOM prevent drift?

No — signing proves the SBOM wasn't tampered with after generation and binds it to a specific artifact digest. The artifact behind a floating tag can still change. Signing plus digest-keying makes drift detectable and non-repudiable; it doesn't make it impossible.

Which SBOM format handles drift better, SPDX or CycloneDX?

Neither format prevents drift; both are snapshots. CycloneDX's BOM serialNumber and version fields plus tooling like sbom-utility make revision diffing slightly more ergonomic, while SPDX 2.3 relationships express build lineage well. Pick the format your consumers require and invest in the pipeline instead.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.