Sign or attest the SBOM against the image digest with cosign, or store it as an OCI artifact that points at the image. The cosign docs suggest cosign attest with a small predicate that records the SBOM location and hash, not the whole SBOM.
Two ways to attach
| Approach | How it works | Trade off |
|---|---|---|
| Separate OCI artifact | Push the SBOM to the registry and sign it like any artifact | Simple, but you must link it to the image yourself |
| Attestation with a pointer | cosign attest with a predicate holding the SBOM path and hash | Small signature bundle, SBOM stored elsewhere |
| Attestation with SBOM predicate | Predicate type holds the full SBOM | Docs say not recommended: the whole SBOM is in the bundle, downloaded on each verify |
Steps
- Build the image and note its digest. Attach to the digest, not to a tag.
- Generate the SBOM from the built image, since it should describe what shipped.
- Store the SBOM somewhere durable, such as an artifact store or registry.
- Write a predicate file with its path and hash.
echo '{"sbom_path": "example.com/sboms/app.spdx.json", "sbom_hash": "sha256:0a1b2c"}' > sbom.predicate.json
cosign attest --type custom --predicate sbom.predicate.json IMAGE_REF
- Verify at deploy time, so a missing attestation blocks the rollout.
The example comes from the sigstore docs, with placeholder values.
Why per image beats per repository
A repository SBOM tells you about source. An image SBOM tells you about the file system you run, including base image packages. When a new vulnerability appears, you want to ask which running images contain the package. Per image records answer that quickly. What a container image SBOM contains and misses covers the limits.
Keep it honest
An attached SBOM is a claim by whoever made it. A signature shows who made it and that it has not changed. Neither proves it is complete. Treat the SBOM as an input to analysis.
Verification at deploy time
Attaching is only half the control. The value comes from checking at deploy time that an image has an attestation from your pipeline identity. Use an admission controller or a deploy step that fails when the attestation is missing or signed by someone else. Keep the failure message clear, so a developer knows to rebuild through the pipeline rather than push by hand.
Keeping SBOMs fresh
An SBOM describes the image at build time. New vulnerabilities appear later, so matching the SBOM against current advisory data is a recurring job. Store SBOMs so you can search them across all images when a new advisory lands, without pulling every image again.
Try it yourself
Try it yourself
Click through it at your own pace, or open it full screen. Open a component and see how version and source are recorded, which is what a per image SBOM should capture.
Quick check
Should the SBOM be generated before or after the image build?
After, from the built image or its layers, so it matches what is deployed.
Do I sign the SBOM or the image?
Sign the image, and sign or attest the SBOM that refers to it, so a verifier can link them by digest.
Safeguard produces SBOMs and runs dependency scanning, and a free scan is at https://gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.