Generate it during build, store it, and you're done.
That's exactly where most implementations go wrong.
Because an SBOM is not a static artifact.
If your SBOM is not updated after deployment, it is already outdated.
The Common Anti-Pattern
A typical workflow looks like this:
- Generate SBOM during CI/CD
- Attach it to the build artifact
- Store it in a repository
- Never look at it again
On paper, this satisfies:
- compliance requirements
- customer requests
- internal checklists
But in practice, it leads to:
- outdated SBOMs
- no connection to what is actually deployed
- false confidence during security analysis
The problem is not that teams generate SBOMs.
The problem is that they treat them as snapshots instead of a timeline.
SBOM Exists in Phases, Not a Single Moment
To understand why this matters, it helps to think of SBOMs across three phases:
1. Design-Time SBOM
What you intend to use:
- dependency files (
package.json, etc.) - early visibility
- incomplete by nature
2. Build-Time SBOM
What gets assembled:
- resolved dependencies
- transitive components
- generated during CI/CD
More accurate — but still not reality.
3. Runtime SBOM
What is actually running:
- containers
- OS packages
- injected components (agents, sidecars)
This is the closest thing to truth.
And often the least captured.
The Drift Problem
Here's the core issue:
Design ≠ Build ≠ Runtime
Over time, they diverge.
Examples:
- base images updated
- patches applied outside CI
- runtime injections
- infrastructure changes
So even a correct SBOM becomes outdated.
SBOM Lifecycle in a Real System (CI/CD + Runtime)
SBOM Lifecycle Diagram

How to Read This Diagram
This flow shows how SBOMs evolve across your system:
- Design phase defines intended dependencies
- Build phase generates the first SBOM
- Deployment & runtime introduce real-world changes
- Runtime observation enriches or corrects the SBOM
- Drift detection & diffing identify mismatches
- Security analysis drives decisions
The key idea:
SBOM is not a file. It's a continuous feedback loop.
Why This Matters in Practice
Imagine this scenario:
A critical vulnerability is disclosed.
Your SBOM says:
"We are not affected."
But that SBOM reflects:
- what was built
- not what is running
Meanwhile:
- a base image update introduced the vulnerable component
- or a runtime dependency pulled it in
Now your assessment is wrong.
This is how incidents escalate.
SBOM as a Continuous Process
To make SBOMs useful, they must be treated as a living artifact:
- Generate at build
- Validate at deploy
- Observe at runtime
- Compare over time
Instead of:
"Here is the SBOM"
You move toward:
"Here is the current state of the system"
Where SBOM Fits in CI/CD
A practical setup looks like:
- Build → generate SBOM
- Deploy → validate or enrich
- Runtime → observe real state
- Monitoring → detect drift
Additionally:
- version SBOMs per release
- diff SBOMs across versions
- link SBOMs to environments
This is where SBOM becomes actionable.
What a "Good" SBOM Looks Like
A useful SBOM is:
- versioned
- continuously updated
- tied to deployments
- reflective of runtime reality
Otherwise, it becomes:
A static file describing a system that no longer exists.And security decisions based on outdated SBOMs are just guesses.
Common Pitfall
Many teams assume:"If we generate an SBOM during build, we're covered."
But that only answers:
- what was built
Not:
- what is running
- what has changed
- what should be trusted
What Comes Next
Now that we understand:
- what an SBOM is
- how it is structured
- and why it must evolve over time
The next step is practical:
How do we generate SBOMs that are actually useful?
In the next article:
"How to Generate SBOMs That Are Actually Useful"
We'll cover:
- tooling (CycloneDX, Syft, etc.)
- common mistakes
- improving SBOM quality
- avoiding "technically correct but useless" outputs