Every workload in a Kubernetes cluster begins life as a container image. That single fact makes Kubernetes image security the foundation of container supply chain security: if a compromised or vulnerable image reaches the scheduler, Kubernetes will faithfully pull it, run it, and hand it the network access, secrets, and privileges you granted the workload. The orchestrator does not judge what is inside the image; it trusts it. Securing that image, and proving where it came from, is one of the highest-leverage things a platform or security team can do.
This article is a deep dive on image security within the broader Kubernetes security picture. If you own the pipeline that builds and deploys containers, this is the layer where container image scanning, image signing, and admission policy come together to protect your container supply chain.
Why the image is a prime attack surface in Kubernetes
A container image is a frozen snapshot of a filesystem: an operating system layer, language runtimes, application dependencies, your code, and whatever configuration got baked in along the way. It is assembled from many sources — public base images, package registries, third-party libraries, internal build artifacts — and each of those is a place an attacker can try to inject or exploit something.
Kubernetes amplifies the consequences. A vulnerable image is not deployed once; it is pulled onto every node that schedules the workload and can be replicated across dozens or hundreds of pods in seconds. Software supply chain failures are prominent enough that the OWASP Top 10 (2025) tracks them as category A03, reflecting how routinely attackers target dependencies and build systems rather than the running application directly. In a cluster, the image is the concentrated form of that risk.
Anatomy of image risk
To secure images deliberately, it helps to name the distinct kinds of risk they carry.
OS packages
The base image ships a Linux distribution's worth of system libraries and utilities. These pick up CVEs over time, and a base image that was clean six months ago almost certainly is not today. Old, unpatched OS packages are the single most common source of image vulnerabilities.
Application dependencies
Your app pulls in open-source libraries — npm, PyPI, Maven, Go modules, and their transitive dependencies. A known-vulnerable version of a library deep in the tree is just as exploitable inside a container as anywhere else, and often harder to notice.
Misconfiguration
How the image is built matters. Running as root, exposing unnecessary ports, leaving package managers and shells in the final image, or setting overly permissive file permissions all widen the attack surface even when no single CVE is present.
Embedded secrets
Secrets get baked into images more often than anyone would like: an API key in an ENV line, a .npmrc token, a private key copied in during a build step and never removed. Because image layers are immutable and cached, a secret committed once can persist in layer history even after a later layer "deletes" it.
Provenance
Finally, there is the question few images can answer on their own: where did this actually come from? Without provenance, you cannot distinguish an image your CI system built and approved from one an attacker pushed to your registry with the same name.
Start at the base: minimal images and non-root
The cheapest security wins happen before any scanner runs, by choosing what goes into the image.
Prefer minimal or distroless base images. A distroless image contains your application and its runtime dependencies and little else — no shell, no package manager, no general-purpose utilities. That dramatically shrinks the attack surface (fewer packages means fewer CVEs) and makes life harder for an attacker who does get code execution, because there is no shell to pivot with.
Run as a non-root user. If the process inside the container does not need root, do not give it root.
# Multi-stage build: compile in a full image, ship a minimal one
FROM golang:1.23 AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /app ./cmd/server
FROM gcr.io/distroless/static:nonroot
COPY --from=build /app /app
USER nonroot:nonroot
ENTRYPOINT ["/app"]
A multi-stage build like this keeps compilers and build tooling out of the final artifact entirely, so they can never become part of your runtime attack surface. Pair non-root images with restrictive pod-level controls — see Kubernetes pod security for how security contexts and admission standards enforce non-root and drop capabilities at deploy time.
Vulnerability scanning: SCA across the whole image
You cannot fix what you cannot see, and container image scanning is how you see it. Effective scanning uses software composition analysis (SCA) to inventory everything in the image — both OS packages and application dependencies — and match that inventory against vulnerability data.
Two principles make scanning actually useful rather than noise:
Scan in more than one place. Scan in CI so developers get feedback on the pull request that introduced a bad dependency, and scan at the registry so images are re-evaluated as new CVEs are disclosed against artifacts you already shipped. An image that passed last week can fail this week when a new critical is published; only continuous re-scanning catches that.
Fail builds on critical findings. A scan that only produces a report gets ignored. Wire the scanner into the pipeline so that new critical (and, where appropriate, high) severity findings break the build.
# CI step: scan and fail on new critical/high findings
- name: Scan image
run: |
rainforest image scan registry.example.com/app:${GIT_SHA} \
--severity CRITICAL,HIGH \
--fail-on CRITICAL,HIGH \
--ignore-unfixed
Scoping to fixable, high-severity issues keeps the gate meaningful instead of drowning teams in findings they cannot act on.
Image provenance and signing
Scanning tells you what is inside an image. Image signing and provenance tell you where it came from and whether to trust it at all.
The idea is straightforward. When your pipeline builds an image, it cryptographically signs the resulting digest and records attestations — machine-readable statements about how the image was produced: which source commit, which build system, which steps ran. This is the core of the SLSA framework (Supply-chain Levels for Software Artifacts), which describes increasing levels of provenance integrity for a build.
Later, before anything runs, you verify the signature. If an image is not signed by a key your organization controls, or its provenance does not match your expectations, it is rejected. That closes the gap a registry alone cannot: even if an attacker pushes a malicious image under a legitimate name, it will not carry a valid signature, and verification will catch it.
Signing and verification belong in the pipeline (sign at build, verify at deploy) rather than being a manual ritual, so that provenance is enforced automatically for every workload.
Registry security
The registry is where images live between build and deploy, so it deserves the same care as any other production system.
- Use private registries for internal images, and be deliberate about which external registries you allow images to be pulled from.
- Enforce access control. Push access should be limited to CI systems and a small set of trusted identities; broad push rights turn the registry into an easy injection point.
- Use immutable tags. Once a tag points at a digest, it should not be repointed. Mutable tags let an image change out from under you after it was scanned and approved.
- Ban `:latest` in deployments. Deploying
:latestmeans you cannot say with certainty what is running, cannot reproduce a deploy, and cannot tie a running workload back to a specific scan. Pin to an immutable tag or, better, to a digest (app@sha256:...).
Pinning by digest is the strongest option: the digest is the image's content-addressed identity, so it cannot silently change.
Admission control: enforce policy at the gate
All of the above is advisory until something refuses to run images that violate it. That something is admission control. A Kubernetes admission controller (typically a policy engine running as a validating admission webhook) inspects every pod spec before it is scheduled and can reject it.
A mature image-security posture uses admission control to block:
- Unsigned images — no valid signature from a trusted key, no admission.
- Unscanned images — no recent, passing scan result, no admission.
- High-severity images — images carrying vulnerabilities above your threshold.
- Disallowed sources — images from registries not on your allowlist, or referenced by mutable tags like
:latest.
# Illustrative admission policy: require a valid signature and a passing scan
apiVersion: policy.example.com/v1
kind: ImagePolicy
metadata:
name: require-signed-and-scanned
spec:
match:
registries: ["registry.example.com/*"]
rules:
- requireSignature: true # provenance must verify
- requireScanPassed: true # no unresolved CRITICAL/HIGH
- disallowTags: ["latest"] # digest or immutable tag only
onViolation: deny
This is the point where policy becomes a guarantee: an image that skipped scanning or lacks provenance simply cannot start.
Runtime drift
Even a perfectly built, signed, and admitted image can drift once it is running. Someone execs into a container and installs a package; a process writes new binaries to a writable layer; a workload starts behaving unlike the image it was built from. That divergence between the trusted image and the live container is runtime drift, and it undermines every guarantee you established at build and admission time.
The defenses are mostly preventive and reinforce earlier choices: run containers with read-only root filesystems where possible, drop unnecessary capabilities, disallow privilege escalation, and keep distroless images that offer no shell to tamper with. The less a running container can be changed, the more the image you verified is still the image that is executing.
Shift left across the whole pipeline
Notice the pattern across every section: the earlier a problem is caught, the cheaper it is to fix. A vulnerable dependency flagged on a developer's pull request is a five-minute change; the same dependency discovered in a production image is an incident. That is what "shift left" means in practice for images — pushing base-image choices, SCA, secret detection, and signing as early into the pipeline as they can go, while still enforcing at the registry and admission gates as a backstop.
Image security is therefore not a single tool but a chain of checkpoints: base image, build, scan, sign, store, admit, and run. A weakness at any link undermines the rest, which is exactly why the container supply chain has to be treated as one connected system.
How Rainforest helps
Securing that whole chain is easier when the checkpoints share one view of your software. Rainforest brings container security and software composition analysis together so you can scan images for vulnerabilities across OS packages and application dependencies, surface embedded secrets and misconfigurations, and track findings from the pull request all the way to the registry. Because Rainforest also covers your infrastructure-as-code and the dependencies your applications pull in, the manifests that deploy your images and the libraries inside them are assessed as part of the same supply chain rather than in isolation — which is how the OWASP-tracked supply chain risks actually reach a cluster.
If you are building out Kubernetes image security, book a demo and we will walk through securing your container supply chain end to end, from base image to admission.
Frequently asked questions
What is Kubernetes image security?
Kubernetes image security is the practice of ensuring that only trustworthy, vulnerability-checked container images run in your cluster. Because every pod starts from an image, it covers hardening the image contents (minimal base images, non-root users, no embedded secrets), scanning for vulnerabilities in OS packages and application dependencies, signing images to prove their provenance, securing the registry that stores them, and using admission control to block images that do not meet policy.
How do I scan container images for vulnerabilities?
Use a container image scanner built on software composition analysis (SCA) that inventories both OS packages and application dependencies and matches them against known CVEs. Run the scan in CI so developers get feedback on the change that introduced a problem, and again at the registry so already-published images are re-evaluated as new vulnerabilities are disclosed. Configure the pipeline to fail the build on new critical (and typically high) severity findings, scoping to fixable issues so the gate stays actionable.
Why should I sign container images?
Signing proves where an image came from. When your pipeline signs an image's digest and records provenance attestations (the SLSA model), an admission controller can later verify that signature and admit only images your build system actually produced and approved. Without signing, an attacker who can push to your registry could substitute a malicious image under a legitimate name; signature verification catches exactly that, closing a gap that scanning and registry access control alone cannot.
Should I use distroless or minimal base images?
Yes, wherever your runtime allows it. Minimal and distroless base images contain only your application and its runtime dependencies — no shell, package manager, or extra utilities — which shrinks the attack surface, reduces the number of CVEs a scanner will ever find, and makes post-exploitation harder because there is no shell to pivot with. Combine them with a non-root user and, ideally, a multi-stage build that keeps compilers and build tooling out of the final image.
How do I stop vulnerable images from being deployed?
Enforce policy with a Kubernetes admission controller. A validating admission webhook inspects every pod before scheduling and can deny images that are unsigned, lack a recent passing scan, carry vulnerabilities above your severity threshold, come from registries not on your allowlist, or use mutable tags like :latest. Pairing admission control with CI and registry scanning turns your image policy from a recommendation into an enforced guarantee.

Written by
Bruno Baldo
CMO
Um pouco de marketing e um pouco de curiosidade e temos a receita pra criar um apaixonado por cyber!

Kubernetes Security: The Complete Guide
A complete guide to Kubernetes security: the 4C's model, attack surface, RBAC, pods, network policies, secrets, supply chain, and shift-left practices.

Kubernetes Pod Security: Standards, Admission and securityContext
A practical guide to Kubernetes Pod Security: the Pod Security Standards, Pod Security Admission, and the securityContext settings that keep pods locked down.

Kubernetes Security Best Practices: A Practical Checklist
A practical Kubernetes security checklist covering the control plane, RBAC, pods, network, secrets, images, and CI to help you harden your cluster.
