Build Stack Review

SBOM Generation and Embedding in CI/CD Pipelines

Correspondent · · 14 min read
Cover illustration for “SBOM Generation and Embedding in CI/CD Pipelines”
Software Supply Chain Security · August 12, 2026 · 14 min read · 3,127 words

Executive Order 14028 established the baseline obligation for any software sold to the United States federal government: SBOM generation is required, not optional, and that requirement flows through procurement to vendors at every tier of the supply chain. That alone reshaped enterprise behavior. But EO 14028 is now the floor, not the ceiling.

The EU Cyber Resilience Act raises the bar substantially. Article 20 imposes a ten-year SBOM retention requirement, a timeframe that effectively erases any practical distinction between compliance documentation and permanent product record. Article 14 vulnerability reporting obligations are already in effect; manufacturers must report actively exploited vulnerabilities within 24 hours of discovery. The full SBOM mandate arrives in late 2027, but organizations shipping into EU markets can't treat that date as a starting gun. Retention timelines and tooling infrastructure take time to build correctly, and most teams badly underestimate both.

PCI-DSS v4.0 and FDA guidance add sector-specific layers. The FDA's cybersecurity guidance for medical devices requires SBOMs as part of premarket submissions, meaning the SBOM is now a regulated artifact subject to the same scrutiny as the device itself. In payments, PCI-DSS v4.0 extends software security requirements in ways that make component-level transparency a practical necessity for any organization handling cardholder data.

CISA's 2025 draft minimum-elements baseline deserves particular attention because it explicitly signals regulator expectations about process, not just output. The draft extends the original NTIA fields to include Component Hash, License, Tool Name, and Generation Context as proposed additions. The inclusion of "Automation Support" as a named minimum element is unambiguous; manual processes are insufficient. The Generation Context field, which records whether an SBOM was produced by a human-driven or automated process, will matter considerably more as AI-assisted pipelines become the norm. Regulators aren't merely tolerating automated SBOM generation; they're codifying it as a minimum expectation.

Enterprise adoption has tracked the regulatory pressure closely. A large majority of surveyed US and UK enterprises now maintain SBOMs, and a significant share require their vendors to provide them as a condition of procurement. The obligation is flowing downstream, and a startup selling a component library to a defense prime contractor can't treat SBOM generation as a future concern.

What this regulatory landscape demands, cumulatively, is that compliance is no longer a one-time artifact submission. Regulators expect continuous, verifiable, machine-readable outputs tied to each build. A signed SBOM produced at release time two years ago tells a regulator nothing useful about the version you're shipping today.

The three SBOM formats and which pipeline use cases each serves

Table: SBOM Formats: Purpose and Best Fit. Compares Primary Purpose, Best Pipeline Fit, AI/ML Support, Notable Strength, and 1 more by CycloneDX, SPDX and SWID.

The NTIA minimum elements specification recognizes three formats: CycloneDX, SPDX, and SWID. Choosing among them is not a matter of preference. Format determines what downstream tooling can consume, and selecting the wrong one creates translation overhead that compounds at scale.

CycloneDX was designed with cyber-risk mitigation as its primary purpose. It's the right choice for vulnerability management workflows, for pairing with VEX (Vulnerability Exploitability eXchange) documents that communicate exploitability context alongside raw CVE data, and for feeding continuous monitoring platforms. CycloneDX 1.6 ships ratified ML-BOM fields covering model parameters, datasets, and quantitative analysis metadata, making it the current practical choice for any team building or integrating AI and machine learning workloads. The Dependency-Track platform, the most widely deployed open-source SBOM management solution, consumes CycloneDX natively.

SPDX was built for license and copyright communication. Its core strength is open-source compliance, license auditing, and the legal review workflows that procurement and legal teams actually use. SPDX 3.0.1 introduced formal AI and Dataset profiles alongside CycloneDX 1.6, which means both formats are now extending into the AI/ML domain; neither has a clean monopoly on that territory yet. SPDX's ISO standard status gives it traction in regulated industries where recognized international standards carry legal weight, and that matters more than most people expect when a regulator asks you to justify your tooling choices.

SWID tags are designed to uniquely identify installed software. They're useful for asset management and endpoint visibility, particularly in environments managing software inventory across many deployed systems. SWID is less common in CI/CD-native workflows because its primary design assumption is post-deployment identification rather than build-time generation. It answers a different question than the other two formats answer.

Most modern generation tools can emit both CycloneDX and SPDX from a single build invocation without meaningful additional cost. Many organizations generate both and route each to the appropriate downstream consumer: CycloneDX to the vulnerability monitoring platform, SPDX to the legal compliance system. The decision about which format to generate should be driven by what the downstream consumer expects, not by whatever the tool defaults to.

Where in the CI/CD pipeline to place SBOM generation

Diagram: Where SBOM Work Lands Across the CI/CD Pipeline. Visualizes: Visualize the five distinct pipeline stages where SBOM-related work occurs, each with its specific purpose: (1) Source stage — lock-file snapshot for PR-level…

Generate the SBOM in the same pipeline run that produces the release artifact, using the exact build environment in which that artifact was created. Any deviation introduces the possibility that the SBOM describes a slightly different artifact than the one that shipped. Given enough time and enough builds, that possibility becomes a certainty.

The build stage is the canonical placement. When the build tool resolves the dependency graph and compiles the artifact, that moment captures the exact versions of every component that went into the binary. Generating the SBOM here eliminates the three-way divergence that plagues retrospective inventories: a developer's local environment, the CI runner's resolved packages, and the final artifact can all differ silently. Lock files help, but they don't capture transitive resolution behavior, platform-specific conditional dependencies, or anything that happens during compilation itself.

Across a complete pipeline, SBOM-related work distributes across several stages, each with a distinct purpose.

Source stage

Lock files committed to version control provide a pre-build snapshot that enables PR-level visibility. A developer submitting a pull request that adds a new dependency should trigger an immediate check of that dependency's license and known vulnerability status before the code ever reaches CI. This is not a substitute for build-time generation; it's an early warning layer.

Build stage

This is where primary SBOM generation occurs. The tool runs against the resolved dependency graph immediately after the build tool has done its work, capturing what was actually resolved rather than what was merely declared. The SBOM produced here is the authoritative record of the artifact's composition.

Container and image stage

Application-level tools miss everything that lives below the application layer. OS-level packages in the base image, system libraries pulled by the container runtime, components introduced by the Dockerfile itself — all of them are invisible to application-level scanners. A second-pass scan of the container image, using a tool capable of layer-by-layer analysis, catches these components and reveals the chain of inheritance from base image to final container. Both scans are necessary for a complete picture.

Post-build attestation stage

The SBOM is signed and attached to the artifact before it leaves the pipeline. Signing after the artifact exits the pipeline breaks the chain of custody. The attestation must happen inside the CI environment that produced the artifact, bound to the artifact digest, before any promotion occurs.

Deployment stage

The deployment stage is where SBOM policy is enforced as a gate. The artifact should not be promoted to a higher environment unless a valid, signed SBOM attestation is present and the SBOM passes license and vulnerability policy checks. Automated policy evaluation here converts the SBOM from a passive document into an active control.

Environment consistency as a prerequisite

Placement matters only if the build environment itself is consistent. If the CI runner's toolchain drifts between builds, build-time SBOM generation still produces inconsistent results. Pinning application dependencies is necessary but insufficient; the toolchain itself, including compilers, language runtimes, build utilities, and system libraries, must also be pinned. Tools like Flox, which declaratively pins entire development and CI environments down to system-level packages using the Nix package manager, address exactly this gap. Application-level lock files describe what the application expects; environment-level toolchain pinning describes the environment in which those expectations are evaluated. Both are required for a reproducible SBOM.

Every build should produce an SBOM using the same tools and the same configuration. Consistency of generation matters as much as placement. Alongside the SBOM itself, the pipeline should capture immutable build identifiers: commit SHA, build ID, artifact digest, and timestamp. These fields create the forensic link between the SBOM and the exact artifact it describes.

The main SBOM generation tools and what each actually covers

No single tool covers every package ecosystem and artifact type. Tool selection must be driven by what the build actually produces, not by what the tool's documentation claims to support.

Syft is the most widely adopted open-source SBOM generation tool for general application pipelines. It covers a broad range of package managers including npm, pip, Maven, and Go modules, and emits both SPDX and CycloneDX without additional configuration. It pairs naturally with Grype, a vulnerability scanner that operates directly against Syft's SBOM output, creating a tightly integrated generation-and-scan workflow. For teams starting from scratch, Syft is the practical first choice for most application-level use cases.

cdxgen is the strongest option for polyglot or multi-language repositories where a single codebase mixes several runtimes. It emits CycloneDX natively and handles the dependency resolution complexity that arises when, for example, a repository contains both a Python service and a Go binary with entirely distinct dependency graphs.

Tern focuses specifically on container images and Dockerfiles. It generates SPDX output and performs the layer-by-layer analysis that reveals how each component entered the image, which is essential for tracing base-image inheritance and understanding the provenance of OS-level packages. Tern is not a replacement for application-level tools; it fills the container-layer gap they leave open.

OWASP Dependency-Check focuses on identifying known vulnerabilities in open-source components. The CycloneDX generator ecosystem extends coverage to internally developed and custom components, which Dependency-Check's design doesn't naturally accommodate. The choice between them depends on whether internal code needs to appear as a named component in the SBOM.

The coverage-gap problem is real and well-documented. In direct comparisons of the same container image processed by different tools, SBOM outputs have differed substantially in their vulnerability counts. The divergence traces partly to whether the tool generates CPEs (Common Platform Enumerations) needed to match components against the NVD, and partly to differences in the underlying detection heuristics. Running a single scanner and treating its output as complete is false confidence.

Running Syft alongside Grype and a container-focused scanner like Trivy against the same artifact is not redundant caution; it's the only way to meaningfully reduce false negatives. I've been in rooms where teams shipped what they believed was a clean bill of materials, only to discover significant gaps during a customer audit. The gaps weren't obscure edge cases. They were OS-level packages that no application-level scanner would have ever surfaced. The multi-tool approach is not optional for any team that will be asked to defend their outputs.

For managing SBOMs at scale, two open-source platforms address different parts of the problem. OWASP Dependency-Track is a CycloneDX-native continuous monitoring platform that consumes VEX documents and maintains a queryable inventory of component vulnerabilities across many projects simultaneously; it's the practical operational layer for teams standardizing on CycloneDX. GUAC (Graph for Understanding Artifact Composition), an OpenSSF project, takes a broader approach by aggregating SBOMs, provenance attestations, and vulnerability reports into a queryable graph structure, which addresses the problem of correlating component data across large portfolios where individual SBOMs provide limited cross-project visibility.

Prefer open standards throughout: CycloneDX, SPDX, in-toto, SLSA, OSV, and VEX. Proprietary formats create translation overhead, limit the ability to share evidence with customers and regulators without conversion, and introduce vendor lock-in at the layer of the supply chain record itself.

How signing and attestation turn an SBOM into verifiable evidence

An unsigned SBOM is an assertion. A signed, attested SBOM is evidence. The difference is not semantic; it's the entire basis on which a downstream verifier, whether a regulator, a customer, or an automated policy engine, can trust the document at all.

Without a cryptographic signature, there's no way to confirm that the SBOM presented at audit time matches what was produced during the build. It could have been modified after the fact, generated from a different artifact, or assembled manually from a different source. The signature closes that gap. Everything downstream of signing depends on it being done correctly, inside the pipeline, before the artifact moves anywhere.

Sigstore and Cosign are the practical implementation layer for signing. Cosign attaches a cryptographic signature to the SBOM and binds it to the artifact digest, creating a tamper-evident link between the document and the artifact it describes. Keyless signing via Sigstore's Rekor transparency log removes the key management burden that historically made signing impractical at the team level; the build identity itself, derived from the CI environment's OIDC token, serves as the signing credential. The key management infrastructure that previously required dedicated security engineering work is replaced by a workflow that integrates naturally into CI. Signing must happen inside the pipeline, immediately after SBOM generation. If it happens outside, the chain of custody is already broken before the artifact reaches its first consumer.

SLSA provenance operates at the layer above the SBOM. Where the SBOM answers "what components are in this artifact," SLSA provenance answers "how was this artifact produced, and can I trust that the process was not tampered with." SLSA uses provenance attestations and hardened build requirements to create a verifiable link from source code to delivered binary, addressing the integrity of the build process itself rather than the composition of its output. An SBOM without provenance tells you composition but not process integrity; provenance without an SBOM tells you the process was sound but not what it produced. Together they cover the full chain.

in-toto attestations provide the envelope format that wraps SBOM, SLSA provenance, and other supply chain metadata in a standardized, verifiable structure. An in-toto attestation enables a downstream verifier to check not just that a signature is valid, but that the SBOM was generated by the expected tool, in the expected environment, at the expected build step, using the expected configuration. This is what makes SBOM attestations machine-enforceable rather than merely human-readable documentation.

The fields captured in the attestation alongside the SBOM matter as much as the SBOM itself: commit SHA, build ID, artifact digest, tool name and version, timestamp, and the Generation Context field proposed in the CISA 2025 draft. Generation Context is what tells a verifier whether the SBOM was produced by an automated build process or by an agent-driven or partially manual workflow. As AI agents become part of the build process, this field becomes critical audit evidence, not a bureaucratic formality.

Policy enforcement at the deployment gate is where attestation converts from a technical mechanism into an operational control. Tools like Kyverno and Open Policy Agent (OPA) can enforce rules in Kubernetes and container-based deployment workflows that prevent artifact promotion unless a valid, signed SBOM attestation is present and passes defined policy checks. NIST Cybersecurity Framework 2.0 and NIST supply chain security guidance both push toward verifiable provenance rather than after-the-fact documentation. Signing and attestation aren't gold-plating; they're the mechanism that makes any provenance claim credible at all.

The additional SBOM problem introduced by AI-generated code and agent-driven pipelines

AI coding agents have introduced a class of SBOM challenge that didn't exist when the original NTIA minimum elements were written. The fundamental issue is that agents can introduce dependencies at edit time, bypassing the code review and lock-file discipline that human development workflows rely on to maintain inventory visibility.

Research on agent-generated code finds that a substantial share of agent edits introduce entirely new direct dependencies at rates far higher than typical human-authored pull requests. The velocity is the problem. A human developer who adds a dependency typically does so deliberately, reviews the package, and updates the lock file consciously. An agent adds the import, installs the package, and moves on. Unless the pipeline catches it immediately, it ships before any human has reviewed the dependency decision at all.

LLM package hallucination compounds the risk. Studies of code-generating models find that a meaningful fraction of generated package names don't correspond to real packages. These are plausible-sounding names, syntactically correct, consistent with the ecosystem's naming conventions, but fictitious. Some hallucinated names are registrable on public package registries, and some remain available long enough for an attacker to register them. Multiple frontier models hallucinate some of the same package names identically, which means the attack surface is not random. It's predictable. An attacker who studies which package names a popular model hallucinates for a given task can pre-register those names and wait for agent-generated code to install them. This is dependency confusion as an attack at model scale.

Build-time SBOM generation is the specific control that catches this. Agent-introduced dependencies appear in the resolved dependency graph at build time; a post-release audit would miss them entirely, or catch them only after the dependency has been in production for weeks. Continuous SBOM generation with every build closes the speed mismatch between agent velocity and periodic inventory cycles. The pipeline doesn't care whether a dependency was introduced by a human engineer or an AI agent; it resolves the graph and generates the SBOM from what is actually there.

The Model Context Protocol (MCP) introduces a further surface. MCP is the emerging standard for giving AI agents structured access to external tools and data sources, and it's been adopted rapidly across major agent runtimes. An MCP server is effectively a dependency of the agent's operating environment, potentially pulling in external code, making external API calls, or introducing data sources that affect build behavior. The current generation of SBOM tooling was not designed to inventory MCP servers as components. Their origin, version, and integrity status don't appear in a standard build-time SBOM. This is an open problem without a clean solution today, and I'm skeptical that the format specifications will catch up to deployment reality before MCP-based agent architectures are already widespread.

The CycloneDX 1.6 ML-BOM fields and the SPDX 3.0.1 AI and Dataset profiles both gesture toward this problem. Neither yet provides a complete answer for agent-runtime infrastructure. The CISA Generation Context proposal is a step in the right direction. At minimum, the SBOM should record that it was generated in an environment where an AI agent was operating, so that a downstream verifier knows to apply additional scrutiny.

What this means practically is that the boundary of what counts as a build component is expanding, and SBOM workflows designed only for declared package dependencies are already operating with blind spots in agent-assisted pipelines. For any team running AI coding agents or agent-driven pipelines, build-time SBOM generation becomes more important as agent autonomy increases, not less. The pipeline is the last reliable checkpoint between agent behavior and production. That checkpoint needs to be enforced, not assumed.

More in Software Supply Chain Security