SBOM in Practice: Generating, Signing, and Consuming SPDX/CycloneDX
Cybersecurity
An SBOM is not a compliance artifact you upload once and forget. It is a live inventory that must be generated at build, signed by the producer, and consumed by every downstream team that cares about exploitability. We walk through the workflow with Syft, Grype, and Cosign.
By Arjun Raghavan, Security & Systems Lead, BIPI · August 2, 2023 · 10 min read
Every regulator memo since log4shell has asked the same question. What is actually inside the software you ship. The answer is supposed to be the SBOM, but most teams generate one, drop it in a release bucket, and call the work done. That misses the point.
An SBOM is only useful if it is generated at the right moment, signed by the right identity, and consumed by a workflow that does something with it. Otherwise it is a JSON file gathering S3 storage cost.
Pick a format and stop debating
SPDX and CycloneDX both work. SPDX leans toward license inventory and is the ISO track. CycloneDX leans toward vulnerability tooling and has richer fields for components, services, and pedigree. Pick one, document the decision, and move on.
- SPDX 2.3 if your audience is procurement, legal, and government buyers
- CycloneDX 1.5 if your audience is your own security and SRE teams
- Generate both if you have the build minutes to spare, they are cheap to produce
Generate at build, not at scan
The SBOM must come from the same build that produces the artifact. Generating it later from a registry scan is a guess, not an inventory. Syft running inside the build container, pointed at the final image or jar, gives you the ground truth manifest.
If your SBOM and your binary do not come out of the same build job, you have two artifacts that happen to share a name.
Sign the SBOM, not just the binary
An unsigned SBOM is a suggestion. Cosign attest lets you bind the SBOM to the image digest using a keyless signature backed by Fulcio and a Rekor transparency log entry. The verifier downstream can then trust the manifest as strongly as it trusts the binary.
- Build the artifact and capture its digest
- Run syft on the artifact to produce a CycloneDX or SPDX document
- cosign attest --predicate sbom.json --type cyclonedx <image-digest>
- Publish the Rekor entry URL alongside the release notes
- Downstream consumers run cosign verify-attestation before pulling
Consumption is the hard part
Producing SBOMs is a solved problem. Consuming them is where teams fall down. The SBOM needs to feed a vulnerability database lookup that fires automatically when a new CVE lands. Grype, Trivy, and the commercial Anchore and Snyk stacks all do this. Pick one and wire it to the deploy gate.
The other consumption path is exploitability. A raw CVE list is noise. Pair the SBOM with reachability data from runtime instrumentation or static call graph analysis, and the alert count drops by an order of magnitude.
What we recommend on day one
- Syft in the build pipeline, output CycloneDX JSON
- Cosign attest with keyless OIDC against your CI identity
- Grype scan on every nightly with results posted to a SARIF dashboard
- A weekly diff job that flags new components added to any production image
- An SBOM retention policy of at least the support window of the release
The pitfalls we keep finding
Multi-arch images that ship one SBOM for amd64 and silently lose the arm64 manifest. Base image components that get stripped from the final SBOM because the scanner only walked the application layer. Vendored binaries inside python wheels that no parser sees. All of these are caught by running Syft twice, once at the image level and once at the filesystem level, and diffing the output.
Closing
The teams that get value from SBOMs are the ones that wired them into a workflow within a quarter of starting. The teams that treat SBOMs as a compliance deliverable are still generating them, still uploading them, and still asking the same question every time a new CVE drops. Do not be the second team.
Read more field notes, explore our services, or get in touch at info@bipi.in. Privacy Policy · Terms.