Your supply chain is a graph, and you only see the first layer
A service declares a dozen dependencies and ships a thousand. Every build tool, base image, CI action and transitive package is code you execute with your privileges, and the practical question is not how to trust all of it but how fast you can answer which parts you have.
TL;DR: The risk is the closure, not the manifest. Three questions decide whether you can act when something is disclosed: what is in this artifact, how was it built, and can I prove this is the artifact I built. SBOM, provenance and signing answer one each, and the value of all three is measured in how long it takes to answer "are we affected".
The graph is bigger than the list
A Node service with fifteen declared dependencies resolves to several hundred packages. A Python image adds the base image's operating system packages, which nobody declared and everyone ships. The build itself pulls a toolchain, a set of CI actions, a package registry and whatever those trust in turn.
Every node in that graph is code that runs with your privileges, either at build time or at runtime. Build time is the more interesting half and the less examined one, because a compromised build step can alter an artifact that passes every test.
Three questions, three artifacts
What is in this? An SBOM, in SPDX or CycloneDX, generated with a declared scope and tied to the artifact digest. Build metadata and analysis of the final image complement each other: include shipped OS packages and check what is deployed. Measure coverage, freshness and time from disclosure to an affected-service list; possession of an SBOM alone guarantees none of them.
How was it built? Provenance, in the shape SLSA describes: an attestation generated by the build system saying which source commit produced this artifact, on which builder, with which inputs. It matters because a signature on an artifact from a compromised pipeline is a signature on a compromised artifact. A verified signature authenticates a signing identity; trusted provenance describes the asserted build process. Neither proves the source or builder harmless.
Is this the artifact I built? Signing, keyless in the Sigstore model so there is no long-lived key to protect, with the signature recorded in a transparency log. Configure admission to verify the artifact digest, expected signer identity and issuer, plus required attestations. A valid signature from an unrelated identity must not pass.
Enforcement is where programmes fail
Every one of those artifacts is inert unless something checks it. The check belongs at admission, as a policy in Kyverno or an OPA equivalent, refusing an image without provenance from a known builder.
The rollout order decides whether it survives. Generate and observe, then warn, then enforce on new workloads, then enforce everywhere. Teams that enforce on day one block every existing deployment, the policy is disabled within the hour, and the programme is set back further than a slow start would have cost. The observe phase also produces the argument for the work, because it usually reveals how many images in production have no provenance at all.
What none of it covers
Scanning finds known vulnerabilities in known components. It does not find a backdoor in a package nobody has reported, a maintainer account takeover, or a dependency that behaves differently when it detects a CI environment. Those need different controls: pinning by digest, vendoring what matters, limiting what a build step can reach, and treating a package's ability to run arbitrary install scripts as the privilege it is.
Being clear about that boundary is what makes the rest credible. A programme sold as making the supply chain safe will be judged against an impossible claim. A programme can instead measure improvements in inventory coverage and response time, and demonstrate which artifacts its admission policy rejects.
What the three artifacts are worth, in hours
The value of an inventory is a response time, so it is worth stating as one. A disclosure lands on a widely used library on a Friday afternoon, and the only question that matters for the next hour is which of your services ship it.
Without an inventory, answering it means a person per service: find the lockfile or the image, resolve the transitive closure, check the version against the advisory, record the answer. Twenty minutes each is optimistic. Across 200 services that is 200 × 20 = 4,000 minutes, about 67 person-hours, which in practice means a handful of engineers working through the weekend and an answer on Monday that is already stale because deploys continued.
With SBOMs generated per artifact and stored against their digests, the same question is a query over the inventory and the answer arrives in minutes. The figures above are illustrative, and the ratio is the point rather than the absolute: the difference between the two is not marginal, and it is entirely determined by work done before the disclosure.
Which reframes what the programme is for. SBOM, provenance and signing do not make the graph safe, and a programme sold that way will be judged against a claim it cannot meet. What they do is convert an unbounded investigation into a lookup, and the honest metric is the time from disclosure to a complete affected-service list, measured by rehearsing it rather than by counting how many SBOMs exist.
Pin by digest, never by tag
Every argument on this page assumes the artifact you verified is the artifact you run, and a tag does not carry that assumption. A tag is a mutable pointer, so myapp:1.4.2 can name different bytes next month, and a signature, an SBOM and a provenance attestation all describe specific content rather than a name that points at it.
So the habit is cheap and the alternative is not: pinning by digest costs a longer string in a manifest, and discovering you did not pin costs an incident in which none of your verification evidence refers to what is running.
Self-check
An image arrives at admission with three things attached: a cryptographically valid signature, an SBOM in CycloneDX listing 312 application packages, and a passing vulnerability scan with no findings. The signature's identity is an account nobody on the team recognises. The image is built FROM a Debian base.
Decide whether this should be admitted, name what each of the three artifacts does and does not establish here, and say what the clean scan is worth. Then answer a second question: a maintainer of one of those 312 packages has their account taken over and publishes a malicious patch release, which your build picks up. Which of the three artifacts detects it? Work through both before reading on.
It should not be admitted, and each artifact fails in a different way. The signature is valid, which establishes only that some key controlled by that identity signed this digest; an unrecognised identity is the case a signature is supposed to catch, and a policy that accepts any valid signature is verifying mathematics rather than trust. The requirement is a signature from an expected signer identity and issuer, and this one does not meet it.
The SBOM's problem is scope rather than validity. It lists 312 application packages and the image is built on a Debian base, so it is missing every operating system package the image ships, which nobody declared and everyone runs. An SBOM whose scope excludes half the shipped components cannot answer "are we affected" for a disclosure in any of them, and its 312 entries make it look complete.
The clean scan is worth the least of the three and is the most likely to be believed. A scan finds known vulnerabilities in components it can see, so this one covers the application packages the SBOM enumerated and not the base image it omitted. No findings is therefore consistent with a vulnerable image, and the absence of provenance means nothing establishes which build produced this artifact at all: a signature on an artifact from a compromised pipeline is a signature on a compromised artifact.
The second question is the more useful one, because the answer is none of them. The malicious release is a legitimately published version of a legitimately named package, so it appears in the SBOM as an ordinary entry, the build is genuine so the provenance is accurate, and the signature correctly attests to an artifact you did build. All three artifacts are working and all three are silent, because they describe what you built rather than whether what you built is trustworthy. The scan is silent too until somebody reports it, which is the gap between disclosure and discovery.
What does address it is a different class of control: pinning by digest so a new release is not picked up without a change, limiting what a build step can reach so an install script cannot exfiltrate or reach the network, vendoring the dependencies that matter most, and treating a package's ability to run arbitrary install scripts as the privilege it is. Being precise about that boundary is what makes the rest of the programme credible.
Next: identity, not network position covers verifying the signer rather than the signature, and the artifact is the unit is why the digest is the thing all of this evidence attaches to.
Sources: SBOM types, Sigstore verification, SLSA provenance.
For verification coverage, SAST, DAST and dependency scanning connects code findings, runtime evidence and the components actually packaged in an artifact.