Skip to main content
All posts
Security

Software supply-chain security: from SBOMs to verifiable build provenance

Software artifacts flow through a verified build into a signed deployable package.
In this article · 12 sections
  1. Start with a claim that can be verified
  2. 1. Build an inventory before building an SBOM
  3. 2. Know what an SBOM can and cannot prove
  4. 3. Capture source and build provenance separately
  5. 4. Bind claims to artifacts with signatures and attestations
  6. 5. Use SLSA as a threat-modelled progression
  7. 6. Turn vulnerability response into a closed loop
  8. 7. Put the controls where CI/CD can enforce them
  9. 8. Measure adoption by coverage and outcomes
  10. A decision framework for teams and buyers
  11. Conclusion: make the path inspectable
  12. References and further reading

Software supply-chain security is often reduced to a document request: “Send us your SBOM.” An SBOM, or software bill of materials, is useful, but it is not a chain of custody. It can tell a customer which components a producer says are present. It does not, by itself, prove that the published binary came from the declared source, that the build ran in an approved environment, or that the dependency list is complete.

A stronger approach treats every release as a set of claims that a consumer can check. The claims begin with an inventory of inputs, continue through source and build provenance, bind evidence to the exact artifact with signatures, and remain useful after release when a vulnerability or suspected compromise appears. The objective is not to produce more paperwork. It is to make the important path from source to deployed artifact observable, tamper-evident, and subject to an explicit decision policy.

This article is scoped to information available on 20 October 2026. Standards, specifications, and government guidance are distinguished from behavior supplied by a particular CI platform, registry, scanner, or signing client. A tool may implement a standard, but the existence of a similarly named feature is not proof of conformance or of a particular security guarantee.

Start with a claim that can be verified

A useful release claim is precise: “Artifact digest H was produced by builder B from source revision C, using build definition D, with resolved inputs R, and it passed policy P.” Each element has a different evidentiary role.

The artifact digest identifies the bytes that were released. A source revision identifies the intended source state. The build definition identifies how the build was meant to run. Resolved inputs include toolchains, base images, packages, scripts, and other material fetched during the process. The builder identifies the service or environment trusted to execute the build and record its result. A policy then decides whether the evidence is sufficient for this product and risk level.

This distinction prevents a common category error. An inventory answers “what is declared?” A signature answers “were these bytes signed by an identity or key accepted by policy?” Provenance answers “what process and inputs does the producer assert created them?” An attestation is a signed or otherwise integrity-protected statement containing a claim and its predicate—the structured data that gives the claim meaning. None of these is a universal guarantee. Verification is the act of checking the statement against an expected identity, digest, schema, and policy.

NIST’s Secure Software Development Framework (SSDF) is a set of high-level practices that can be integrated into different development life cycles, rather than a prescribed product architecture. It is useful as a vocabulary for assigning ownership and evidence across preparation, protection, production, and vulnerability response NIST SP 800-218 SSDF. The supply-chain workflow below makes that vocabulary operational.

1. Build an inventory before building an SBOM

An inventory is more than a package-manager export. Start with the software unit that will be released and enumerate its inputs by lifecycle and trust boundary:

  • direct dependencies declared by the application;
  • transitive dependencies selected by a resolver;
  • runtime libraries, operating-system packages, base images, and language toolchains;
  • build plugins, compilers, linkers, generators, test tools, and CI actions;
  • downloaded scripts, vendored source, patches, submodules, and generated code;
  • configuration that changes the output; and
  • external services or data that the application calls at build time or runtime.

For each package or artifact, retain a stable identity and a content digest where possible. A name and version are convenient labels, not unique identities: names can be reused across ecosystems, versions can be republished, and an internal mirror can serve different bytes under the same label. Record the ecosystem, package URL or equivalent identifier, source location, version or commit, digest, relationship to the released unit, and the tool and time that observed it.

A lockfile improves repeatability by recording resolver choices, but it is not evidence that the selected bytes are safe or that the lockfile itself was the one used by the build. Pin dependencies and build actions to immutable references where the ecosystem allows it. Retain the lockfile and the package-manager configuration as source inputs, then capture the resolved artifact digests in build evidence.

Inventory should happen at more than one point. A source-time inventory reveals declared dependencies and reviewable changes. A build-time inventory observes what the builder actually resolved. An image or binary scan can identify components that declarations missed. Differences are not automatically an incident; they are a prompt to explain whether a component was generated, embedded by a base image, loaded only at runtime, or pulled by an unrecorded build step.

The boundary should be explicit. A library imported by the program, an image layer inherited from a base, a package installed only in a test stage, and a CLI used by the compiler may all matter, but they matter in different ways. Marking scope—runtime, build, test, optional, development, or excluded with a reason—makes later vulnerability triage more useful than a flat list.

Treat the inventory as a controlled data product. Give it an owner, record its generation command and tool version, preserve the input artifact digest, validate its schema, and publish it with the release. If a scanner cannot identify a component, keep an “unknown” record rather than silently dropping it. A visible gap is actionable; a clean report caused by an unobserved path is not.

2. Know what an SBOM can and cannot prove

An SBOM is a machine-readable description of software components and their relationships. The current CISA-led 2026 Minimum Elements for an SBOM, published on 29 July 2026, updates and replaces the 2021 NTIA baseline and describes an SBOM as a building block for software security and supply-chain risk management. It also notes that different software types may need additional elements beyond the baseline CISA 2026 Minimum Elements for an SBOM. That date matters: an older procurement template may still be based on the previous baseline.

Choose a format for interoperability, not because one format makes the underlying facts true. SPDX is an international open standard recognized as ISO/IEC 5962:2021; the SPDX project lists document version 3.0 as its current version on the page read for this article SPDX specifications. CycloneDX is an OWASP Foundation and Ecma-supported specification whose object model represents components, services, dependencies, relationships, vulnerabilities, and other supply-chain information; its specification page lists version 1.7 and JSON, XML, and Protocol Buffers representations CycloneDX specification overview. These are standards and schemas. A vendor’s exporter, normalizer, or portal is an implementation with its own coverage and interpretation.

The practical limits are more important than the format choice. An SBOM can be incomplete because a build fetches a script dynamically, a binary embeds an unrecognized library, a base image changes, an application loads a plugin after installation, or a proprietary component has no public identifier. It can be stale because the artifact was rebuilt, repackaged, or deployed with a different configuration. It can be ambiguous because two ecosystems use the same name, a vulnerability database uses a different identifier, or a package was forked and patched locally.

An SBOM also lacks process evidence. It does not normally demonstrate that the producer controlled the source repository, that a review occurred, that a CI runner was isolated, or that the published bytes correspond to the listed source. Nor does the presence of a component mean that every vulnerability associated with that component is exploitable in this product. A vulnerable function may be unreachable, a feature may be disabled, or a fix may have been backported without changing the upstream version string.

Use an SBOM as the join key for response, not as a security verdict. Publish it for the exact artifact digest, include generation metadata and declared completeness, and associate it with provenance and vulnerability-status evidence. When an SBOM is missing data, preserve the uncertainty and route it to an owner. “Not observed” and “not present” are different statements.

3. Capture source and build provenance separately

Source provenance answers where the input came from and what controls governed its change. Useful evidence includes the repository and immutable revision, the release tag or other reference, the source archive digest, review and branch-protection results, the identity that approved the change, and the relationship between the release record and the revision. A signed tag can help establish intent, but it does not by itself prove that the CI system checked out that revision or that the binary was built from it.

Build provenance answers how a particular artifact was produced. The approved SLSA 1.2 specification describes SLSA as a cross-industry specification with levels and tracks that provide increasing security guarantees; its current structure includes Build and Source tracks and recommended attestation formats SLSA specification v1.2. SLSA is not a universal certification label. A level is meaningful only with the defined requirements, the identity of the builder, and the scope of the claimed guarantees.

The SLSA build-provenance predicate is an in-toto attestation predicate with the type https://slsa.dev/provenance/v1. It identifies the artifact subject by digest and records a build definition, run details, builder identity, invocation metadata, and resolved dependencies. External parameters are inputs controlled by a caller or tenant; at stronger build levels the platform must make them complete so an unrecorded input cannot silently influence the result. The specification also treats fetched artifacts as dependencies when they are known SLSA Build: Provenance.

That model changes the verification question from “does the vendor have an SBOM?” to “does this exact digest have provenance that satisfies our policy?” A consumer can require a source repository and revision from an approved organization, a builder identity representing an approved control plane, a build type that is understood, dependency digests rather than floating URLs, and a release workflow that ran from a protected branch. The consumer can then reject a validly signed artifact whose provenance is absent, incomplete, or outside the expected boundary.

Provenance is still an assertion about a trusted system. If the builder identity includes a compromised control plane, or if a tenant-controlled script can alter the build without being represented in external parameters, the statement may be syntactically valid but weaker than policy assumes. Higher SLSA levels narrow those gaps; they do not eliminate the need to assess the builder. Reproducible builds provide an independent check when they are practical: an independent party rebuilds from recorded inputs and compares the resulting digest or a defined reproducibility property. Reproducibility is difficult for many products and should be treated as evidence with a documented scope, not as a prerequisite that every team can satisfy immediately.

4. Bind claims to artifacts with signatures and attestations

A digital signature binds a digest or statement to a key or identity under a trust policy. It provides integrity and signer authentication for what was signed. It does not prove that the signer made a good dependency choice, that the build was isolated, or that the artifact is free of vulnerabilities. Those claims need their own evidence and policy.

Use separate, composable attestations rather than a single opaque certificate. A release may carry an artifact signature, SLSA provenance, an SBOM attestation, test results, a vulnerability scan result, and a VEX statement. Each should name the exact subject digest, identify its predicate type, include a timestamp and issuer or signer, and be retained where a consumer can retrieve it. A verification policy can require all relevant statements and reject mismatched subjects.

Reviewed source passes through a controlled build, separate evidence and signature checks before the exact verified artifact is deployed.Open the full-size diagram

Sigstore illustrates one implementation of a modern signing workflow. Its keyless mode issues a short-lived certificate from Fulcio that binds an ephemeral public key to an OpenID Connect identity, and records the signing event in Rekor, a transparency log. Sigstore distributes roots of trust through The Update Framework (TUF) Sigstore signing overview. This reduces the burden of long-lived private-key storage for some automated workflows and creates an auditable record, but it does not make every OIDC identity an approved release authority. Verification still needs an identity pattern, issuer, artifact digest, certificate validity, transparency evidence, and release policy.

Sigstore’s public service and the cosign client are not themselves universal standards. They are components in an ecosystem that uses established mechanisms and formats. An organization may run a private deployment, use a traditional hardware-protected signing key, or use another attestation store. The decision is about the verifier’s trust roots, identity lifecycle, availability, recovery, and audit requirements—not about the word “keyless.”

in-toto supplies a related conceptual model. Its stable 1.0 specification and its independently developed Attestation Framework are documented as separate specifications; the project says a future in-toto specification will incorporate the framework in-toto specifications. An in-toto statement contains subjects and a predicate type with predicate data. SLSA provenance is one predicate; an SBOM or test result can use another. This common envelope lets a verifier reason about the subject and signature while dispatching predicate-specific checks to the right schema.

Protect signing and attestation paths as production infrastructure. Separate build permissions from release approval. Prefer short-lived workload identity for automation, restrict who can publish to a release location, make the release job consume an immutable build output, and log failed verification as well as successful verification. Keep a recovery plan for compromised keys, issuer configuration, builder identity, or transparency-log dependencies. A signature that nobody checks at install or deployment time is inventory, not enforcement.

5. Use SLSA as a threat-modelled progression

SLSA is most useful when each adoption step closes a named attack path. Start by writing the threat: an attacker changes source after review; a mutable dependency is substituted; a CI token publishes an altered artifact; a build runner fetches an unreviewed script; or a registry serves different bytes. Then choose the smallest control and evidence that makes the attack detectable or harder.

A sensible progression is:

  1. Know the inputs. Generate a component inventory and lock resolved dependencies to digests or immutable revisions. Record unknowns.
  2. Make release identity explicit. Sign the artifact and define which identity may release which repository, package, image, or environment.
  3. Generate provenance in the build. Record the source revision, build type, external parameters, builder identity, invocation, and resolved inputs. Publish it next to the artifact.
  4. Verify at a gate. Make deployment, promotion, or installation reject a missing or mismatched subject, an unapproved builder, an unexpected source, or a failed signature check.
  5. Harden the builder. Reduce untrusted inputs, isolate runners, restrict network access, protect control-plane credentials, and make the provenance-generation path itself part of the trusted computing base.
  6. Add independent confidence. Rebuild selected releases, compare outputs, or obtain an independent review of the builder and release controls where product impact justifies the cost.

Do not report “SLSA compliant” without naming the version, track, level, builder, and evidence. A vendor may expose a button labelled “provenance” that produces a useful statement, but the verifier should inspect the actual predicate, signing identity, subject digest, completeness promises, and retention behavior. A platform’s documented default is not necessarily the same as the configuration used by an individual repository.

6. Turn vulnerability response into a closed loop

A vulnerability process begins when a new advisory is matched to an inventory, not when an engineer reads a dashboard. Normalize package identifiers, map each release SBOM to deployed artifact digests, and record which products, versions, environments, and owners are affected. Keep the original advisory and the matching decision so that a later correction can be audited.

Machine-readable data can improve precision. The OSV schema models affected packages and ranges for ecosystems such as semantic versions, ecosystem-specific versions, and Git commits. It defines introduced, fixed, last-affected, and limit events, with different evaluation rules for each OSV schema. That distinction matters: “fixed in 1.2.3” is not the same as “last known affected in 1.2.3,” and a Git commit range requires the repository graph. An automated match is a lead for triage, not a final exploitability decision.

Add context through VEX, or Vulnerability Exploitability eXchange. CISA’s minimum-requirements document describes the elements needed to create a VEX document, whose purpose is to communicate the status of a vulnerability in a particular product CISA VEX minimum requirements. A product team can state, with evidence, that a vulnerable component is affected, not affected because the vulnerable code is unreachable, not affected because a mitigating configuration is always enforced, or under investigation. The statement should identify the product and version or artifact, the vulnerability, status, justification, issuer, and revision information.

Response policy should combine technical facts with exposure. Prioritize an internet-facing artifact with demonstrated exploitation above an unused build-time tool, but do not dismiss a build tool that can inject code into releases. Set service-level targets for triage, containment, fix or mitigation, and customer communication. If a patch cannot be shipped immediately, isolate the affected path, disable the feature, constrain access, or document acceptance with an owner and expiry. After remediation, regenerate the inventory, verify the new digest and provenance, and confirm that the deployed artifact—not only the source branch—changed.

NIST guidance for federal agencies recommends coordinated vulnerability disclosure, machine-readable advisories such as VEX where appropriate, and integration of SBOMs with vulnerability databases and other reporting mechanisms NIST software supply-chain vulnerability management. That is guidance for its stated audience, not a blanket requirement for every organization. Other organizations can adopt the same workflow in proportion to product impact and customer commitments.

7. Put the controls where CI/CD can enforce them

The pipeline is the natural place to make evidence deterministic, but it is also a high-value target. Separate source, build, test, artifact, and deployment permissions. Use ephemeral or regularly rebuilt workers for untrusted jobs. Give workflows the minimum token scope and prevent pull-request code from accessing release credentials. Restrict egress for release builds where feasible, and make exceptions visible because a network block that breaks legitimate package resolution can encourage unsafe bypasses.

A practical release path looks like this:

  • A protected source change is reviewed and merged; the merge revision is recorded.
  • The build resolves dependencies from approved registries and records content digests, toolchain versions, base-image digests, and build configuration.
  • Tests, static analysis, package checks, and SBOM generation run before publication. The generated files are associated with the output digest.
  • The builder emits provenance from the control plane or another path whose trust boundary is documented. Do not let a tenant-controlled build step freely invent a higher assurance claim.
  • A release identity signs the artifact and attestations. Approval is separate from compilation when the risk warrants separation of duties.
  • A verifier checks the artifact digest, signer identity, transparency or key evidence, provenance schema, source and builder policy, required attestations, and vulnerability gates before promotion.
  • Deployment records the verified digest and verification result. Rollback selects a previously verified digest rather than rebuilding from a moving branch.

Test failure modes deliberately. Attempt to publish an unsigned artifact, replace a dependency without changing its version, alter the source revision in provenance, remove an SBOM component, use an unapproved builder identity, and replay an old attestation against a new digest. The expected result is a clear, actionable rejection. Also test the recovery path: if a transparency service is unavailable, a key is revoked, or an advisory is corrected, define whether the pipeline fails closed, uses a cached root, or permits a time-bounded exception.

Standards define interchange and assurance concepts; CI systems, registries, and security products define their own policy hooks and retention. Document the adapter between them. For example, “the registry accepts a signature” is weaker than “the deployment controller verifies a signature for this digest, requires a builder identity matching this pattern, and records the decision.”

8. Measure adoption by coverage and outcomes

A single supply-chain score hides the paths that remain unprotected. Measure the workflow as a set of denominators and exceptions. Useful measures include:

  • Inventory coverage: percentage of release artifacts with a validated SBOM, and percentage of SBOM entries with a stable identifier and digest. Report unknown and excluded components separately.
  • Provenance coverage: percentage of production artifacts with provenance whose subject digest matches the artifact and whose builder and source satisfy policy.
  • Verification enforcement: percentage of production promotion paths that actually reject missing or invalid evidence, measured with controlled negative tests rather than configuration screenshots.
  • Dependency discipline: percentage of dependencies and CI actions pinned to immutable references; time that a new or changed dependency remains unreviewed; and the number of unexplained differences between declared and observed inputs.
  • Response performance: median and high-percentile time from advisory publication to affected-release identification, decision, remediation, redeployment, and customer notice. Track false matches and reopened cases.
  • Builder assurance: coverage of isolated workers, restricted release credentials, provenance generated outside the untrusted workload, and independently rebuilt or reviewed releases.
  • Exception quality: count, owner, rationale, compensating control, age, and expiry of exceptions. An exception with no expiry is a policy change disguised as a temporary workaround.

OpenSSF Scorecard is one possible input to dependency assessment. Its automated checks cover source, build, dependencies, testing, and maintenance; each check returns a score and risk level, with an aggregate score intended to help assess posture OpenSSF Scorecard. It is an assessment aid, not a substitute for verifying the artifact consumed by a particular product. A high score on an upstream repository cannot prove that an organization used the intended release, and a low score may reflect a missing signal rather than a confirmed compromise.

Set targets that describe capability, not activity. “Generate 100 SBOMs” rewards documents. “Ninety-five percent of production digests have a matching SBOM, provenance, and enforced verification decision; the remainder have an owner and expiry” describes control coverage. Pair it with outcome measures such as time to identify affected deployments and the percentage of remediation changes that were verified in production. Review metrics by product criticality, because a universal threshold can be either unaffordable for low-risk software or inadequate for a release that controls sensitive systems.

A decision framework for teams and buyers

Before choosing a product or demanding a particular badge, answer five questions.

What must be proven? Decide whether the priority is component visibility, release integrity, source control, build isolation, vulnerability response, or all of these for a high-impact product. Write the unacceptable failure as a sentence.

Who will verify it? A producer may publish evidence, but the consumer, platform team, or deployment controller must define acceptance. Specify allowed identities, builders, repositories, predicate types, algorithm and key requirements, retention, and revocation behavior.

What is the trust boundary? Name the source system, CI control plane, runner, package registries, signing service, attestation store, and deployment gate. For each, state what is trusted, what is tenant-controlled, what is recorded, and what happens if it is compromised.

What is the evidence unit? Prefer the immutable artifact digest as the join key. A release tag, package name, container label, or URL can point to changing bytes. Bind SBOM, provenance, signatures, test results, VEX, deployment, and rollback records to the digest or to a signed statement that names it.

What happens when evidence is missing? Choose fail-closed, quarantine, manual approval, or a compensating control by risk tier. Record the exception and its expiry. A universal fail-closed rule can stop emergency response; a universal fail-open rule makes verification decorative. The policy should make that trade-off explicit.

This framework also clarifies procurement. Ask for a sample attestation and its schema, not only a product page. Ask how the producer identifies the builder, resolves dependencies, handles generated files, records failed builds, rotates signing material, preserves evidence, and responds when an advisory changes. Verify a supplied artifact independently. If the answer relies on an undocumented portal field, treat it as a vendor-specific convenience until the underlying claim and trust model are clear.

Conclusion: make the path inspectable

An SBOM is the beginning of a verifiable workflow, not its conclusion. Inventory the inputs, preserve uncertainty, and publish the inventory for the exact artifact. Record source and build provenance so a consumer can evaluate how the bytes were made. Sign the artifact and its claims, but keep identity and key trust separate from vulnerability and process claims. Use in-toto-style statements to carry typed evidence, apply SLSA requirements against named threats, and make CI/CD gates verify what production actually receives.

The mature measure is not how many documents a team emits. It is how often a consumer can answer, quickly and with evidence: what is this artifact, where did it come from, what influenced its build, who authorized it, which vulnerabilities matter here, and what will happen if any answer changes? That is software supply-chain security as an operating capability rather than a compliance file.

References and further reading

#Software supply chain#SBOM#SLSA#Provenance