The Container Vulnerability Lifecycle
Summary
- The container vulnerability lifecycle is the path a CVE takes from disclosure, into your image layers, through your registry and clusters, and back out again once patched.
- Insight: A vulnerability is almost never introduced by your code alone. It rides in on a base image or a transitive dependency you did not write.
- Key Concepts: CVE (a catalogued flaw), base layer (the OS packages under your app), SBOM (a software bill of materials), scanner (Trivy/Grype), and admission policy (the gate that blocks bad images).
- When to Use: Reach for this mental model when you design where scanning runs, how often you rebuild, and which severities block a deploy.
- Limitations/Trade-offs: No scanner catches everything, and every gate you add is a place that can slow or break delivery. Policy is a balance, not a wall.
- Related Topics: Vulnerability Basics, Base Image Pinning by Digest, Exception Process.
Foundations
A container image is a stack of read-only layers. Most of those layers are not yours.
The bottom layers come from a base image such as debian, ubuntu, alpine, or a distroless variant. They carry an operating system and its packages.
Your application layer sits on top. It adds your compiled binary or interpreted code plus the language dependencies you pulled in with pip, npm, go mod, or similar.
A CVE (Common Vulnerabilities and Exposures) is a publicly catalogued security flaw with a unique ID like CVE-2024-3094. Each CVE maps to one or more affected package versions.
The core idea of the lifecycle: a package version you shipped weeks ago is fine until a researcher discovers a flaw in it. The moment that CVE is published, your already-built image becomes vulnerable without you changing a single line.
This is why a container that passed every scan on Monday can fail on Friday. The image did not change. The world's knowledge about it did.
Mechanics & Interactions
Trace one CVE through the system to see where each control sits.
Entry. A flaw exists in openssl inside your base image, or in a library like log4j in your dependency tree. You inherit it the moment you build FROM that base or install that package.
Disclosure. The CVE is published to the National Vulnerability Database with a CVSS score and severity (Low, Medium, High, Critical). Scanner vendors ingest this feed continuously.
Detection at build. Your CI pipeline runs a scanner such as Trivy or Grype against the freshly built image. The scanner reads the image's package metadata, builds or consumes an SBOM, and matches installed versions against the CVE feed.
Detection in the registry. Registries like Harbor, GitHub Container Registry, or ECR re-scan stored images on a schedule. This is how they catch the "fine on Monday, vulnerable on Friday" case for images you already pushed.
Enforcement at admission. When you deploy, a Kubernetes admission controller can check the image against policy before the pod is ever scheduled. This is the last gate.
# A minimal ValidatingAdmissionPolicy shape (conceptual)
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: require-signed-images
spec:
validations:
- expression: "object.spec.containers.all(c, c.image.contains('@sha256:'))"Remediation. The base image maintainer publishes a patched version. You rebuild FROM the new digest, your scanner reports the CVE as resolved, and the new image flows out to clusters.
The pieces interact as a feedback loop. Detection feeds policy, policy blocks or allows, and remediation resets the clock.
Advanced Considerations & Applications
Not every CVE is reachable. A flaw in a package that your app never calls at runtime is real but low-risk. This is why teams pair raw CVE counts with reachability or "in-use" analysis so engineers triage what actually matters.
The fixed versus unfixed distinction drives real decisions. If a CVE has no upstream fix, rebuilding will not clear it. Your only levers are removing the package, switching bases, or filing a time-boxed exception.
Rebuild cadence is the quietest lever and the most important. If you pin a base by digest but never rebuild, you freeze both your reproducibility and your vulnerabilities in place.
Distroless and minimal bases shrink the lifecycle's entry surface. Fewer packages means fewer CVEs to inherit and fewer scanner findings to triage each week.
At scale, the lifecycle becomes an SLA. Teams commit to remediating Critical findings within a fixed window and track mean time to remediate as a platform metric.
Common Misconceptions
"If it scanned clean, it is safe." Clean means no known CVEs at scan time. New disclosures land daily, so a clean image ages into a vulnerable one.
"My code is the risk." Most findings live in base OS packages and transitive dependencies, not in your application source.
"A Critical CVE always means we are exploitable." Severity reflects worst-case impact, not whether the flawed code path is reachable in your app or exposed to attackers.
"Rebuilding is optional once we pin a digest." Pinning gives reproducibility, not immunity. Without a rebuild cadence, pinned images accumulate unpatched CVEs.
"The registry scan replaces the CI scan." They cover different moments. CI blocks bad images from being published; registry scans catch images that went bad after publishing.
FAQs
Where should scanning run first? In CI, on every build, so a vulnerable image fails fast before it reaches a registry or cluster.
Why do the same images get flagged again later? Because the CVE feed grows. Registry re-scans surface newly disclosed flaws in images you already shipped.
What is an SBOM and why does it help? It is a machine-readable inventory of every package in an image. Scanners and auditors use it to answer "am I affected?" in seconds rather than hours.
Can I ever ship a known Critical CVE? Only through a recorded, time-boxed exception with a named owner, as covered in the Exception Process page.
Does pinning by digest reduce vulnerabilities? No. It makes builds reproducible. You reduce vulnerabilities by rebuilding onto patched digests on a cadence.
Is Docker the runtime that scanning protects on nodes? No. You build and scan with Docker, but containerd via the CRI runs the pods on your Kubernetes nodes.
Related
- Vulnerability Basics
- Base Image Pinning by Digest
- Exception Process
- Minimal Attack Surface
- Image Policy Best Practices
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).