SBOMs and signed attestations sound like checkboxes until you need to answer "did this artifact come from our pipeline?" The minimum viable supply-chain story we run.
For a long time, "supply chain security" was a buzzword that meant "we scan our images." After log4shell, the XZ backdoor, and several smaller incidents, the conversation got serious. Today we generate SBOMs at build, sign artifacts with Sigstore, and verify provenance at deploy. None of this is exotic — most teams could land the same baseline in a couple of weeks. This post is what we actually run, what each piece prevents, and what we deliberately skipped.
Supply chain security gets vague fast. To stay concrete, the three scenarios we design against:
our-org/api:v3.4.1 that wasn't built by our CI. Detected by provenance attestation + verification at deploy.We can't prevent all of these. We can ensure that when one happens, we know fast and have the data to investigate.
A Software Bill of Materials lists every package + version that went into the artifact. We generate one per build using Syft:
syft <image-ref> -o spdx-json > sbom.json
The SBOM is attached as an OCI artifact alongside the image (so it travels with the image to the registry). Anyone who pulls the image can pull the SBOM too. The format we use is SPDX JSON — widely supported by downstream tooling.
What the SBOM enables:
What the SBOM doesn't do: prevent the compromised-dependency scenario at build time. It just makes the response faster after.
For every artifact we produce, the CI also produces a signed attestation: a statement of "this artifact was built by this pipeline run, from this commit, by this identity." Signing uses Sigstore (specifically cosign), which is keyless — the signature is tied to the CI's OIDC identity, not a long-lived key we have to manage.
# At build time, in CI
cosign sign-blob --bundle attestation.bundle --certificate-identity-regexp \
"https://github.com/company/.+" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
--yes \
<image-digest>
The attestation includes provenance fields (workflow name, commit SHA, builder identity) following the SLSA framework. The bundle gets pushed to the same OCI registry as the image.
What this enables:
What it doesn't do: certify that the pipeline itself is uncompromised. If an attacker gets into the CI, they can sign artifacts that look legitimate. Pipeline integrity is a separate problem.
The pieces above are useless without enforcement. Two enforcement points:
At registry pull. When the Kubernetes runtime pulls an image, an admission controller (Kyverno or Gatekeeper) checks the image's signature. Unsigned images, or signatures from unexpected identities, get rejected.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signatures
spec:
validationFailureAction: Enforce
rules:
- name: verify-our-images
match:
resources:
kinds: ["Pod"]
verifyImages:
- imageReferences:
- "our-registry.io/company/*"
attestors:
- entries:
- keyless:
subject: "https://github.com/company/.+"
issuer: "https://token.actions.githubusercontent.com"
The first version of this policy is the most enlightening one. We deployed it in audit-only mode (logging violations but not blocking). Within a week we'd found:
Fixed each, then switched to enforce mode. Now any unsigned image in our registry namespace fails admission.
At CI for downstream pipelines. If pipeline A produces an artifact that pipeline B consumes (e.g. a base image), B verifies A's signature before using it. Catches the case where the base image got tampered with between A and B.
A few patterns that look reasonable and didn't earn a place:
Verify signatures on every container we run. We verify our own; we don't verify every third-party image (the ecosystem isn't there yet). Most images we use are from well-known projects whose maintainers don't sign with our trust roots. Pragmatically, we treat third-party images as a separate trust decision: pin to specific tags, scan for CVEs, but don't require signatures.
Full SLSA Level 3. SLSA defines four levels of supply chain hardening. Level 3 requires hermetic builds (no network during build, all deps prefetched and signed) and source-tracking that's substantially more elaborate than what we run. We're at roughly Level 2 (provenance attestations, signed artifacts, no privileged build runners) and that catches the bulk of the risk for our threat model.
Reproducible builds. The promise: anyone can rebuild the artifact byte-for-byte from source and verify it matches. Real but hard. Practical for some pure-Go binaries; very hard for typical Node/Python with mixed deps. Not on our roadmap.
Vendor-attestation registries. Some products promise centralized registries of "trusted" artifact attestations. We rely on Sigstore's public transparency log (Rekor) instead — it's open, auditable, and the standard the ecosystem is converging on.
The SBOM + signing setup pays off most when a CVE drops:
Steps 1 and 2 are minutes with this infrastructure. Without it, they're "everyone search the codebases by hand for a week." That's the actual ROI.
For reference, the current stack:
Total cost (operational): a couple of hours per week for vulnerability triage and exception management. The setup itself was about two weeks of focused work.
Supply chain security feels like a Big Topic until you break it into pieces. SBOM at build. Sign with provenance. Verify at deploy. Each piece prevents a specific scenario. The full setup is a couple of weeks of work and pays for itself the first time you respond to a major CVE.
Get the latest tutorials, guides, and insights on AI, DevOps, Cloud, and Infrastructure delivered directly to your inbox.
Edge compute is useless without an edge data layer. Three serverless databases that put data within ms of your edge functions, with the tradeoffs that aren't on the marketing pages.
Bad resource requests waste money or trigger OOMs. The methodology we use to right-size requests based on actual usage, and the gotchas the autoscalers don't fix.
Explore more articles in this category
Production monitoring catches user-facing issues. CI failures stay invisible until someone notices the merge queue is stuck. The metrics and alerts that make pipelines observable.
Static thresholds on error rate produce noisy alerts. Burn-rate alerting flips the question to "are we burning the error budget faster than we can sustain?" — and pages only on real problems.
Argo CD ships your manifests; Argo Rollouts ships them gradually with automated quality gates. The setup, the analysis templates that earn their place, and what we measure.