Supply-chain & image security
You write maybe 5% of the code you ship. The other 95% is dependencies — libraries, base images, build tools — written by strangers and pulled in automatically. Your application's security is therefore only as good as your software supply chain: everything that flows into your build and deployment. A single poisoned dependency or a CVE-ridden base image can compromise you no matter how careful your own code is. This lesson is about hardening that supply chain — building minimal, non-root images, scanning everything early (shift-left), tracking what's inside (SBOMs), and cryptographically proving that only the artifacts you built and approved can run.
On-ramp in one breath: most of your code comes from other people. Build the smallest possible images, scan every input for known holes early in the pipeline, and cryptographically sign your artifacts so only verified ones can run.
The vocabulary, defined once
- Software supply chain — every input to your software: dependencies, base images, build tools, the pipeline itself.
- CVE — a publicly catalogued known vulnerability (Ch. 8.1). "This image has 40 CVEs" means 40 known holes.
- Shift-left — moving security checks earlier (left) in the pipeline — into the developer's commit and PR — instead of only scanning the finished artifact at the end.
- DevSecOps — folding security into DevOps so it's automated and continuous, not a separate gate at the end.
- SBOM — Software Bill of Materials: a complete, machine-readable list of every component in an artifact (like an ingredients label).
- Signing / verification — cryptographically stamping an artifact so consumers can prove it came from you and wasn't tampered with.
- Admission control — a gate at deploy time (in Kubernetes) that rejects anything not meeting policy — e.g. an unsigned image.
Build minimal, non-root images
The cheapest supply-chain win is to ship less. Every package in your base image is attack surface and a potential CVE. Two durable habits:
- Minimal / distroless base images. A full OS base image carries a shell, package managers, and hundreds of libraries you never use — each a possible CVE. A distroless or minimal base (just your app and its runtime, no shell or package manager) can cut the vulnerability count dramatically and removes the tools an attacker would use after breaking in.
- Run as non-root. By default a container often runs as root (the all-powerful user). If an attacker breaks out of the app, they're root — a much worse day. Set the image to run as an unprivileged user; if it's compromised, the attacker is not root, sharply limiting what they can do.
These two changes — minimal base, non-root — are the highest-return image hardening you can do, and they're durable regardless of language or tool.
Shift-left: scan everything, early
The failure mode most guides leave you in is scan-the-built-image-at-the-end: security is one check, right before deploy, when fixing anything is expensive. Shift-left DevSecOps instead runs many automated checks throughout the pipeline (Ch. 5), starting at the developer's commit. The durable taxonomy of scans — learn the categories, the tools are dated:
| Scan type | What it checks | Catches | Example tools |
|---|---|---|---|
| SAST (static app sec testing) | Your source code | Insecure code patterns (e.g. injection) | (language-specific) |
| SCA / dependency scanning | Your dependencies | Known CVEs in libraries you import | Snyk, Trivy, Grype |
| IaC scanning | Your Terraform / manifests | Misconfigurations (public bucket!) before apply | Checkov, tfsec, Terrascan |
| Container/image scanning | Your built image | CVEs in OS packages + app deps | Trivy, Grype, Snyk |
| Secret scanning | Your commits | Keys/tokens about to be committed | Gitleaks, TruffleHog |
The point: a misconfiguration or known CVE is caught where it's cheapest to fix — at the keyboard — and a problem never reaches production because the pipeline failed on it. Note IaC scanning is how the "no public bucket / no public database" rules from 8.1 and 8.5 get caught before terraform apply — security and the IaC of Chapter 3 meeting in the pipeline.
:::tip Shift-left is the durable fix for "security at the end" Scanning only the finished image is too late and too narrow. Shift-left means many categories of scan (SAST, SCA, IaC, container, secret), running automatically from commit onward, so problems are caught early and cheaply. The categories are durable; the specific scanners (Trivy, Snyk, Checkov, Gitleaks…) are the dated layer you'll swap over the years. :::
Know what's inside: SBOMs and CVE management
When a major vulnerability drops (think the kind that makes the news), the first question every team scrambles to answer is: "Are we affected — does anything we ship include the vulnerable component?" Without an inventory, that's a frantic manual hunt across every image. An SBOM answers it instantly: it's a complete ingredient list of every component in an artifact, generated at build time. With SBOMs you can query your whole fleet — "which images contain library X version Y?" — and respond in minutes. CVE management is the ongoing practice of scanning against SBOMs, prioritizing by severity and exploitability, and patching — continuously, because new CVEs are disclosed against old artifacts every day.
Prove provenance: signing and admission control
Scanning checks for known holes. Signing answers a different question: is this the exact artifact we built and approved — or did someone swap it? With signing (e.g. Cosign, part of the Sigstore project), your pipeline cryptographically signs each image it builds. Then at deploy time, an admission controller in Kubernetes verifies the signature and rejects any image that isn't signed by your pipeline. Trace the protection:
- Pipeline builds image, scans it, signs it, pushes to the registry.
- Someone (or an attacker) tries to deploy a different, unsigned image — maybe a tampered one, maybe a random public image with malware.
- The cluster's admission controller checks the signature, finds none from your trusted key, and refuses to run it.
Only artifacts your pipeline built and signed can run. This closes the "an attacker pushed a malicious image" path and enforces image provenance — and admission control is the same enforcement mechanism that policy-as-code uses in 8.7.
Why it matters
You author a sliver of what you ship; the rest is a supply chain of other people's code and images, and it's only as secure as its weakest input. Harden it durably: build minimal/distroless, non-root images (less surface, smaller blast radius), and shift security left — run SAST, SCA, IaC, container, and secret scanning automatically from the commit onward so problems are caught where they're cheap, not in production. Keep an SBOM so you can answer "are we affected?" in minutes and run continuous CVE management. Finally, sign your artifacts and verify signatures at admission so only the images your pipeline built and approved can ever run. Categories and principles are durable; the specific scanners and signers are the dated layer.
Common pitfalls
- Scanning only the final image. Too late and too narrow. Shift left: scan source, dependencies, IaC, and commits throughout the pipeline.
- Bloated base images full of CVEs. A full-OS base ships hundreds of unused packages and a shell for attackers. Use distroless/minimal bases.
- Running containers as root. A breakout becomes root. Run as an unprivileged user by default.
- No SBOM. When the next big CVE drops you'll be hunting blind. Generate SBOMs at build so you can query your fleet instantly.
- No signature verification at admission. Without it, an attacker (or a typo) can run an unsigned, tampered image. Verify provenance at deploy time.
- Treating a scan as a one-time gate. New CVEs are disclosed against old artifacts daily. Re-scan continuously, not just at build.
Where this connects
- Back to Chapter 4 · Images & registries — this hardens the images you learned to build and store.
- Back to Chapter 5 · CI/CD & GitOps — shift-left scanning lives inside the pipeline; signing is a pipeline step.
- Back to 8.4 Secrets & encryption — secret scanning is the supply-chain check that keeps keys out of Git.
- Forward to 8.7 Posture, policy-as-code & continuous compliance — admission control here is the same gate policy-as-code uses to block insecure configs.