Most teams don’t wake up one morning excited to generate SBOMs. Sbom For Beginners: What It Is And How To Generate It In Ci ?
They care because something went wrong.
In my case, it was usually one of these:
-
A critical CVE drops (Log4Shell-style), and leadership asks: “Are we affected?”
-
A customer security questionnaire lands with a new checkbox: “Provide an SBOM.”
-
An audit turns into a week-long archaeology dig through dependency trees no one fully understands anymore.
SBOMs didn’t come from theory. They came from repeated failure modes in modern software delivery.
We build systems out of hundreds or thousands of third-party components. Most of them are indirect. Many come from base images we didn’t create. When something breaks or becomes vulnerable, “grep the repo” stops working fast.
Before SBOMs, teams answered these questions manually:
-
What versions of OpenSSL are we shipping?
-
Does this service include that vulnerable library?
-
Which container images actually contain it?
That approach doesn’t scale. Not with microservices. Not with containers. Not when the dependency graph changes every week.
SBOMs exist to answer one simple question reliably:
What an SBOM actually is
The most useful mental model is this:
An SBOM is an ingredient list for a build artifact
- Not a scan result.
- Not a risk assessment.
- Not a compliance report.
Just a structured inventory of components.
A typical SBOM includes:
-
Package names
-
Versions
-
Package type (npm, pip, rpm, apk, etc.)
-
Relationships (what depends on what)
-
Sometimes checksums, licenses, and metadata
That’s it.
What it does not include:
-
Vulnerability severity
-
Exploitability
-
Whether you should panic
-
Runtime behavior
-
Business impact
I’ve seen teams treat SBOMs like vulnerability reports and get frustrated when “nothing useful” shows up. That’s misunderstanding the tool.
An SBOM answers “what is there?”
Other tools answer “is it bad?”
Another common misunderstanding:
“We already have a , so we have an SBOM.”
No. You have source-level dependency metadata. That’s related, but not the same thing.
I’ve seen this go wrong when:
-
The container base image pulled in vulnerable system libraries
-
A build step compiled in a dependency not declared in source
-
A transitive dependency resolved differently in CI than locally
The SBOM that matters is the one that reflects what actually shipped, not what you intended to ship.
That’s why SBOMs are artifact-focused, not repo-focused.
One more misconception:
SBOMs are not perfect.
- They can be incomplete.
- They can miss dynamically loaded dependencies.
- They can misidentify packages.
They are still dramatically better than guessing during an incident.
SPDX vs CycloneDX: which formats actually matter
You’ll hear about two formats immediately: SPDX and CycloneDX. Both are real. Both are useful. They exist for different reasons.
SPDX
SPDX came first. It grew out of the open source and legal compliance world.
What it’s genuinely good at:
-
License tracking
-
Provenance and attribution
-
Long-term documentation
-
Supplier and copyright metadata
If your primary concern is:
-
“Can we legally ship this?”
-
“Who owns this component?”
-
“What license obligations do we have?”
SPDX is solid.
Where it feels heavy in practice:
-
Verbose and complex
-
Slower to evolve
-
Awkward for CI pipelines
-
Overkill for quick security workflows
In real pipelines, SPDX often feels like filling out a tax form when all you wanted was a receipt.
When you’d realistically choose SPDX:
-
Regulated industries
-
Legal/compliance-driven programs
-
Customers explicitly require SPDX
-
You’re producing SBOMs as formal deliverables, not operational inputs
CycloneDX
CycloneDX came from the AppSec and DevSecOps world.
It was designed for:
-
Automation
-
CI pipelines
-
Vulnerability correlation
-
Speed and practicality
Why it fits CI and security workflows better:
-
Simpler structure
-
Easier to generate
-
Better support for containers and images
-
Plays nicely with vulnerability scanners
Why most teams end up here first:
-
Tools default to it
-
Security teams understand it
-
It integrates cleanly into existing pipelines
Where it has limits:
-
Less expressive for complex licensing nuance
-
Not ideal as a long-term legal record
-
Some enterprise customers still prefer SPDX
My honest recommendation
If you’re just starting:
Generate CycloneDX in CI
Use SPDX only when:
-
A customer contract requires it
-
Legal explicitly asks for it
-
You already have a mature SBOM process
Rule of thumb I give teams:
- CycloneDX for operations.
- SPDX for obligations.
You can generate both later if needed. Don’t block adoption by picking the “most correct” format on day one.
How SBOM generation works in real CI pipelines
This is where the theory usually falls apart.
There are three broad approaches:
Repo-based SBOMs
You scan the source
Pros:
-
Fast
-
Easy
-
Good early signal
Cons:
-
Misses system packages
-
Misses base image contents
-
Lies when builds behave differently than expected
Useful for development. Dangerous to rely on for incident response.
Artifact-based SBOMs
You generate the SBOM from:
-
A built binary
-
A compiled artifact
-
A release bundle
Better, but still incomplete for containerized systems.
Container image SBOMs
You scan the final container image:
-
After build
-
Before push (or immediately after)
This tells the truth.
It includes:
-
OS packages from the base image
-
Language dependencies
-
Compiled binaries
-
Transitive dependencies you didn’t know existed
This was the biggest “oh wow” moment the first time I did it. We found:
-
Vulnerable libraries no one realized were there
-
Old packages inherited from base images
-
Multiple versions of the same dependency
Tooling people actually use
Tools like Syft-style scanners are common because:
-
They understand containers
-
They’re fast enough for CI
-
They output CycloneDX or SPDX easily
The workflow usually looks like:
-
Build image
-
Generate SBOM from image
-
Attach SBOM to build metadata
-
Push image
-
Store SBOM somewhere durable
Where it fits in CI:
-
After build
-
Before deploy
-
Not blocking initially
Mistakes I’ve seen:
-
Generating SBOMs from source and calling it “done”
-
Blocking builds immediately on SBOM diffs
-
Regenerating SBOMs without versioning or storage
-
Not tying SBOMs to image digests
What surprised me the first time:
-
SBOM generation was faster than expected
-
The noise level was high initially
-
The value showed up during the next incident, not immediately
Treat SBOM generation as plumbing, not a gate, at first.
What you actually do with an SBOM after it’s generated
An SBOM by itself is inert. Value comes from how you use it.
Vulnerability scanning
- An SBOM is not a vulnerability report.
- But it enables one.
Instead of rescanning images every time a CVE drops, you can:
-
Store SBOMs
-
Correlate them against new vulnerability data
-
Answer “are we affected?” in minutes
This matters during zero-days when time is everything.
License checks
Legal teams don’t want scanners. They want inventories.
SBOMs let you:
-
Identify licenses across the stack
-
Spot copyleft surprises
-
Prove what you shipped at a specific time
This is one of the fastest ways to reduce legal friction.
Incident response
This is where SBOMs earn their keep.
Real workflow:
-
CVE announced
-
Identify affected package + version
-
Query stored SBOMs
-
Get list of impacted services
-
Prioritize response
Without SBOMs, this becomes Slack archaeology and guesswork.
Storage
If you don’t store SBOMs:
-
You can’t answer historical questions
-
You lose traceability
-
You regenerate inaccurate data later
Best practice:
-
Store SBOMs alongside artifacts
-
Tie them to immutable identifiers (image digest, build ID)
-
Keep them longer than logs
Losing SBOMs makes the whole exercise pointless.
SBOM best practices
A few hard-earned lessons:
-
Start by generating. Don’t over-police.
-
Scan final artifacts, not intentions.
-
Expect noise early. It settles.
-
Don’t fail builds on SBOM changes initially.
-
Store SBOMs immutably.
-
Tie SBOMs to deployable artifacts.
-
Treat SBOMs as operational data, not paperwork.
Where teams over-engineer:
-
Perfect formatting
-
Custom schemas
-
Blocking gates too early
Where teams under-invest:
-
Storage
-
Traceability
-
Incident workflows
SBOMs are boring until they save you hours during a crisis.
You Might Be Interested In
- How Phishing Attacks Trick Users?
- How Application Security Prevents Risks?
- How Zero Trust Architecture Is Being Adopted by Governments?
- Top Cybersecurity Certifications Worth Pursuing in 2025
- How Cybersecurity Threats Affect Users?
Conclusion
SBOMs aren’t a silver bullet, and they’re not something you adopt because a standard says you should. They exist because modern software is too complex to reason about during a crisis without an accurate inventory. When a serious CVE drops or a customer asks hard questions, guessing is no longer acceptable—and SBOMs are how you stop guessing.
The biggest mistake teams make is treating SBOMs as paperwork or compliance output. In practice, they’re operational data. Their value shows up later, under pressure, when you need fast, defensible answers about what you shipped and where the risk actually is. That only works if SBOMs are generated from real artifacts, stored properly, and tied to your delivery pipeline.
If you’re just starting, keep it simple. Generate SBOMs from container images. Use CycloneDX. Don’t block builds on day one. Focus on accuracy and storage before enforcement. You can layer on policy, scanning, and automation once the foundation is solid.
SBOMs are boring when everything is fine. They’re invaluable when it isn’t. That’s usually the right tradeoff.
FAQs about Sbom For Beginners: What It Is And How To Generate It In Ci ?
Is an SBOM the same as a vulnerability scan?
No, and this distinction matters more than most teams realize at first. An SBOM is a factual inventory: it tells you what components and versions are present. A vulnerability scan is an interpretation layered on top of that inventory, usually by matching those components against vulnerability databases that change over time.
In practice, this separation is actually a strength. A vulnerability scan is only “correct” at the moment it runs. An SBOM stays useful long after the build finished. When a new CVE drops next week or next year, you don’t need to rescan everything from scratch—you can re-evaluate existing SBOMs against new vulnerability data. Teams that conflate SBOMs with scans usually end up regenerating data repeatedly instead of reusing it.
Should I generate SBOMs from source or from container images?
If you care about accuracy, generate SBOMs from container images. Source-based SBOMs only reflect what your dependency files say, not what actually ends up in production. The moment you introduce base images, OS packages, build tooling, or compiled artifacts, source-only SBOMs start lying by omission.
In real systems, the most serious surprises almost always come from outside the application code: inherited libraries from base images, system packages pulled in by language runtimes, or build-time dependencies baked into the final image. Scanning the final container image captures reality. Source SBOMs can still be useful earlier in development, but they should never be the authoritative record for incident response or audits.
Which format should I pick if I’m just starting?
If you’re starting from zero, pick CycloneDX. It’s easier to generate, easier to consume, and better aligned with CI and security tooling. Most modern SBOM generators default to CycloneDX for a reason: it’s optimized for automation, not paperwork.
That doesn’t mean SPDX is “wrong.” It just solves a different problem. Teams that start with SPDX often slow themselves down trying to model every edge case before they even have a working pipeline. You can always add SPDX later if a customer or legal requirement demands it. The worst outcome is picking a format so heavy that SBOM adoption never actually happens.
Where should SBOMs be stored?
SBOMs should be stored as durable build artifacts, tied to immutable identifiers like image digests or build IDs. Treat them the same way you treat release artifacts, not like temporary CI logs. If you can’t retrieve the SBOM for a specific deployed version six months later, you’ve lost most of the value.
In practice, this usually means storing SBOMs in artifact storage, registries that support attachments, or a dedicated SBOM repository. What matters less is where and more that the relationship between “this thing running in prod” and “this SBOM” is unambiguous and permanent. Re-generating SBOMs later is risky because the ecosystem may have changed.
Do SBOMs include transitive dependencies?
Yes—if they’re generated from the final artifact. This is one of the main reasons SBOMs are useful in the first place. A proper SBOM includes not just the dependencies you explicitly declared, but also the ones pulled in indirectly by your dependency graph, your runtime, and your base image.
This is also where teams get surprised. Many vulnerabilities live several layers deep, in libraries no one on the team has ever heard of. An SBOM surfaces those layers explicitly. If your SBOM doesn’t include transitive dependencies, it’s usually a sign that it was generated too early in the build process or from the wrong input

