Secure base images for containerized applications: container image security from the bottom up (2026)

By
Yakir Zagron
May 15, 2026

The base image is the one piece of a containerized application that almost every team inherits without auditing. Snyk reported in 2024 that 44% of Docker image scans contained known vulnerabilities for which a more secure base image was already available. Practical-DevSecOps research shows over 50% of public Docker images carry at least one critical vulnerability.

In the platform-image audits I have run for regulated workloads over the last two years, the same root cause keeps surfacing. Nobody owns the FROM line, and nothing downstream can fix what that line drags in. This article defines what makes a base image secure, names the hidden risks of pulling defaults, walks through evaluation against a six-criteria rubric, and shows how to enforce the discipline in CI/CD and at the cluster admission layer.

Key Takeaways

  • A secure base image is a minimal, signed, source-built container layer that ships only the packages the workload runs, carries an SBOM and VEX, and is patched against critical CVEs on a published SLA, typically within 48 hours of disclosure.
  • The average Debian-based public container image carries roughly 300 known CVEs at pull time per Chainguard's 2024 State of Hardened Container Images report. Standard official runtime images typically ship with 50–60 vulnerabilities, of which 15–20 are rated high or critical.
  • Choosing a secure base image is a six-criteria decision: minimization technique, provenance, signing, patch SLA, SBOM and VEX availability, and compliance posture against NIST SP 800-190, CIS, FIPS 140-3, STIG, and FedRAMP.
  • The base image is the deepest layer of defense in a containerized stack. Every higher control such as admission policies, runtime monitors, and network policies inherits whatever attack surface and CVE backlog the base image brings with it.

What Makes a Base Image Secure (and What Doesn't)

A secure base image is a container base layer built from auditable upstream source, signed at publication, accompanied by a Software Bill of Materials (SBOM) and a VEX document, stripped of components the application never executes, and patched against critical CVEs on a published, contractual cadence — usually 48 hours.

The phrase covers more ground than container base image, which is the broader term for any layer referenced by the Dockerfile FROM directive. A secure base image satisfies six measurable criteria, listed below as both a numbered list and a rubric table any platform team can score vendors against.

  1. Minimization: no shell, no package manager, no compiler, no curl or wget left in the image.
  2. Provenance: SLSA Build Level 3 or higher attestation tied to the upstream source commit.
  3. Signing: a Cosign or Notation signature verifiable by image digest.
  4. Patch SLA: a critical CVE triggers a rebuilt and re-signed image within 24–48 hours of disclosure.
  5. SBOM and VEX: a CycloneDX or SPDX SBOM ships with the image, plus a VEX document for any "not affected" claims.
  6. Compliance posture: the image is mapped to NIST SP 800-190, CIS, FIPS 140-3, STIG, and FedRAMP controls.
Criterion What "Secure" Looks Like
1. Minimization No shell, no package manager, no compiler, no curl or wget
2. Provenance SLSA Build L3+ attestation tied to upstream commit
3. Signing Cosign or Notation signature verifiable by digest
4. Patch SLA Critical CVE triggers a rebuild and re-sign within 24–48 hours
5. SBOM + VEX CycloneDX or SPDX SBOM plus VEX for "not affected" claims
6. Compliance posture Mapped to NIST SP 800-190, CIS, FIPS 140-3, STIG, FedRAMP

What is not a secure base image: the :latest tag pulled at every build, an unsigned image from an unknown community repo, an image with no published patch cadence, an image whose SBOM cannot be retrieved, an image whose maintainer is one volunteer, or an image that bundles a shell and package manager "for convenience." I have personally seen all six patterns slip into FedRAMP boundary diagrams when the platform team forgets to score base images on a written rubric.

Base Image vs. Parent Image vs. Scratch

The Docker community uses three terms loosely. A base image is the bottommost layer in an image's lineage. It has no parent and is built FROM scratch or imported directly from a distribution tarball such as debian, alpine, or ubi9-micro.

A parent image is whatever image your Dockerfile names in its own FROM directive, which itself usually has a base image upstream. Every parent image has a base image; not every base image is a parent image.

Scratch is Docker's reserved empty image and the hard floor of minimization, required for fully static binaries, as documented in the Docker Docs base image guide.

Common Misconceptions

  • "Alpine is automatically secure." False. Alpine is small but a stale Alpine image with old musl, busybox, or apk packages still ships CVEs.
  • "Distroless is automatically secure." Partial. Distroless removes the shell and package manager, but a distroless image still inherits everything its upstream Debian or Wolfi base ships.
  • "Smaller equals safer." Correlated, not equivalent. A 5 MB image with stale OpenSSL is more dangerous than a 30 MB image patched yesterday.
  • "Official images on Docker Hub are vetted." Partially. Kennasecurity research found roughly one in five of the top 1,000 Docker Hub images carries at least one critical vulnerability.

The Hidden Risks of Standard Base Images

Standard public base images carry hidden risks that compound the moment an attacker gets a foothold. The risks include outdated OS packages with unpatched CVEs, bloated attack surface from unused shells and compilers, mutable tags that silently change between builds, supply-chain compromise via typosquatting and namespace hijacks, and a near-total absence of cryptographic provenance. The workload inherits all of it at the FROM line.

The CVE numbers are not abstractions. The average Debian-based public container image carries roughly 300 CVEs at pull time per Chainguard's 2024 report. Standard runtime images such as node, python, and openjdk typically ship 50–60 vulnerabilities, with 15–20 rated high or critical. Snyk's scanning data shows 44% of scans had known vulnerabilities for which a newer, more secure base image already existed.

Every image-hardening review I have performed for an enterprise customer has surfaced the same gap. The security team owns scan results, but nobody owns the upstream that generated them.

Outdated and Unpatched OS Packages

Maintainers patch on their own cadence, not the disclosure cadence. CVEs in glibc, openssl, and libxml2 routinely sit in popular base images for weeks after disclosure, while exploitation campaigns frequently begin within 72 hours. The published Mean Time to CVE on standard public images for high and critical bugs runs to multiple weeks.

Bloated Attack Surface

A typical nginx:latest ships with /bin/sh, apt, and dozens of binaries that exist only for image-build convenience. MITRE ATT&CK for Containers technique T1611 (Escape to Host) assumes the attacker uses whatever post-exploitation tooling is already on disk. An image without a shell or package manager limits that toolkit by default, which is the discipline behind container image attack surface reduction.

Supply-Chain Compromise

Recent incidents make the risk concrete. The Kong Ingress Controller cryptominer pushed to Docker Hub in December 2024 reached every cluster that pulled the affected build. The xz-utils backdoor (CVE-2024-3094) shipped in any base image that included the compromised release.

Log4Shell (CVE-2021-44228) was added to the CISA Known Exploited Vulnerabilities catalog on December 10, 2021. It exposed every image bundling Log4j 2.0-beta9 through 2.14.1 regardless of whether the workload used it. A base image with a verifiable signature, a published SBOM, and a documented build attestation would have surfaced or contained each of these.

Mutable Tags and Tag Drift

The :latest tag, and even semantic-version tags such as :1.27, can be republished by the maintainer. The image bytes can change silently between two docker pull runs of the same tag, which breaks reproducibility and undermines every downstream signature. The first time I watched a re-tagged base layer ship a new glibc into production over a holiday weekend, the post-incident fix was the same one I now write into every platform standard: pin by sha256: digest.

Missing SBOM, Signature, and Provenance

Without a signed SBOM and VEX document, the consumer cannot answer the only question that matters during an incident: what is in this image, and is this CVE actually exploitable here? Most public base images sit at SLSA Level 0 or 1 against the SLSA framework; secure base images target Level 3 or higher. NIST SP 800-190 section 4.1.1 requires an accurate inventory of software components, which without an SBOM cannot be met.

How to Evaluate and Choose a Secure Base Image

Choosing a secure base image is an evaluation problem with five inputs. The inputs are workload type, language runtime, compliance environment, patching capacity, and tolerance for vendor lock-in. Each is scored against the six-criteria rubric of minimization, provenance, signing, patch SLA, SBOM and VEX, and compliance posture. The table below scores the eight base image options most commonly evaluated by platform teams in 2026.

Base Image Option Minimization Has Shell? Pkg Mgr? Signed SBOM Avg CVE Count Patch SLA Compliance
Alpine 3.20 Minimal distro Yes (/bin/sh) Yes (apk) No (community) No (community) 10–30 Community None claimed
Google Distroless static Distroless No No Yes Yes Near zero (static) Google cadence None claimed
Wolfi (Chainguard public) Undistribution + glibc Optional Optional Yes Yes Designed for zero Chainguard cadence FIPS, FedRAMP-aligned
Red Hat UBI Micro 9 Minimal RHEL No No Yes (Red Hat) Yes Tens (RHEL-tracked) Red Hat erratum FIPS, NIST 800-190
Chiselled Ubuntu 24.04 Static slicing No No Yes (Canonical) Yes Low (LTS-tracked) Canonical Ubuntu Pro FIPS, CIS-aligned
BellSoft Alpaquita Minimal Java-tuned Optional Optional Yes Yes Low BellSoft LTS FIPS modules available
Docker Hardened Images Minimal No No Yes (Docker) Yes Designed for zero Docker SLA FIPS, FedRAMP-aligned
Iron Bank (USAF) Hardened + scanned Varies Varies Yes (DoD) Yes Tracked + accredited DoD process DoD STIG, FedRAMP, IL-class

How to read this table. No row is universally "best." A statically compiled Go binary has a different optimum than a Java microservice or a Python data pipeline.

In every paid platform-engineering review I have done, the row that breaks the tie is patch SLA, not image size. A 4 MB image with a 30-day patch latency loses to a 40 MB image with a 48-hour SLA every time. Pick the rows that satisfy your compliance posture first, then optimize within that subset for patch SLA, then for image size.

Decision Matrix by Workload Type

Workload Type Recommended Starting Base Reason
Static Go, Rust, or C binary scratch or distroless/static Binary already bundles dependencies
Dynamic Go, Node.js, Python Distroless variant or Wolfi Need libc and CA certs but no shell
Java or JVM workload Alpaquita, distroless Java JVM-aware, glibc compat, LTS Java backports
Web server (nginx, caddy) Hardened minimal nginx Stripped of shell, package manager, signed
Windows-native app Windows Server Core or Nano Server Per Microsoft Learn, only Microsoft images run Windows containers
DoD or federal workload Iron Bank or vendor-hardened DoD and FedRAMP accreditation already in place

Distroless vs. Minimal vs. Hardened

Three terms collide on this SERP. Minimal describes footprint, which is small but may still ship a shell. Distroless describes a specific minimization technique with no shell and no package manager. Hardened describes the outcome: any base image, minimal or distroless or otherwise, that has been patched, signed, SBOM-attested, and committed to a published patch SLA. Minimal and distroless are techniques; hardened is the goal.

When scratch Is the Right Answer

Use scratch only for fully static binaries (Go with CGO_ENABLED=0, Rust musl targets, GraalVM native images). The caveat is that scratch ships no CA certificates, no /etc/passwd, and no DNS resolver, so any of those must be COPY-ed in deliberately. Both Docker Docs and the AWS EKS image-security best practices recommend FROM scratch as the floor for compiled-binary workloads.

Integrating Secure Base Images Into Your Container Workflow

Integrating secure base images into a container workflow is a six-step pipeline discipline. Pin by digest, verify the upstream signature before build, attest a fresh SBOM at build, scan with at least two engines, deploy under an admission controller that enforces signature and SBOM policy, and rebuild every base image automatically when upstream patches drop.

Pin by Digest, Never by Tag

FROM nginx:1.27 may pull different bytes today versus last month if the maintainer rebuilt the tag. Replace it with the digest:

# base image: nginx 1.27.0-alpine

FROM nginx@sha256:5646cf896dafe95def30420defa8077fc8ee71ef5578e2c018c2572aae0541e2

Use Renovate or Dependabot to auto-bump the digest and the version comment together. Every team I have onboarded to a digest-pinning policy initially complains about merge friction, then stops complaining the first time Renovate catches a silent base-layer rebuild before it reaches staging.

Verify Signatures Before Build

cosign verify \
  --certificate-identity "$EXPECTED_IDENTITY" \
  --certificate-oidc-issuer "$EXPECTED_ISSUER" \
  <chosen-image>@sha256:<PINNED_DIGEST>

Verification ties the image you build on to a specific publisher identity and OIDC issuer. This satisfies SLSA Level 3 provenance and OWASP Docker Cheat Sheet Rule #13 on supply-chain integrity.

Generate and Attest an SBOM at Build Time

Use Syft, the CycloneDX Generator, or Trivy to produce the SBOM. Then attest it with cosign attest --predicate sbom-syft.json --type cyclonedx $IMG. Without an SBOM you cannot triage CVE alerts in minutes when the next disclosure lands; with one, you can.

Scan With Multiple Engines and Gate on Policy

Two-engine scanning reduces false negatives. A common combination is trivy plus grype or snyk. Build-time scans fail the pipeline on critical findings, registry scans re-scan daily, and runtime scans flag new CVEs in already-deployed workloads. The OWASP DevSecOps Guideline section 02f is the canonical control reference.

Run as Non-Root With Minimum Capabilities

Drop privileges per OWASP Cheat Sheet Rules #2 (non-root user), #3 (drop capabilities), #4 (--security-opt=no-new-privileges), and #8 (read-only root filesystem). This matters even more when the base image is minimal: there is no shell to escalate from, but kernel calls remain.

Use Multi-Stage Builds

Keep build tooling out of production. A Go service builds with golang:1.24 as the builder stage and ships from gcr.io/distroless/static-debian12 as the final stage. The build-time base and the runtime base should almost never be the same image.

Automate Base-Image Rebuilds

Renovate, Dependabot, or an in-house bot watches upstream digest changes. After every base image update: rebuild, re-scan, re-sign, re-attest, redeploy. Without automation, even a vendor's 48-hour patch SLA never reaches your production cluster.

Enforce in Admission Controllers

Cluster-side policies in Kyverno, OPA Gatekeeper, Connaisseur, Ratify, or Portieris reject any pod whose image is unsigned, missing an attached SBOM, carrying a critical CVE older than your SLA, or pulled by tag instead of digest. The Minimus blog covers this enforcement pattern in depth in using the Kyverno admission controller to enforce hardened base images.

Control Framework Section Base Image Control
NIST SP 800-190 §4.1.1 Inventory of components — SBOM is the artifact
NIST SP 800-190 §4.3.2 Capability minimization — no shell, no package manager
CIS Docker Benchmark v1.6 §4.1–§4.6 Image build (single-purpose, USER, no secrets, content trust)
FIPS 140-3 Module validation FIPS-validated cryptographic modules in the base image
DISA STIG Container Platform STIG V1R3 Minimal base, signed, scanned
FedRAMP Vulnerability scanning 30-day scan window, hardened images mandate per FedRAMP guidance

This control mapping is the artifact most platform teams need for an audit. It demonstrates that a hardened base image program produces evidence for compliance dashboards covering CIS, FIPS, and STIG without manual evidence collection.

A final honest caveat: a secure base image program reduces build-time attack surface and produces audit evidence. It does not replace runtime threat detection, network policy, secrets management, or EDR on the host node. Treat the base image as the foundation, not the entire stack.

How Minimus Approaches Secure Base Images

Minimus builds hardened container images directly from upstream source code and provides signed artifacts and SBOM support for its images. Its Trust Center describes a 48-hour patch SLA for critical CVEs (and 14 days for high and medium severity), and Minimus offers compliance-oriented support for frameworks including NIST SP 800-190, STIG, FIPS 140-3, and FedRAMP. The base layer of your stack becomes the strongest, not the weakest, control.

The build-from-source approach (rather than stripping packages out of an existing distribution after the fact) produces substantially lower CVE counts at pull time, with Minimus reporting a 97%+ reduction compared with common base images. Minimus also publishes signed SBOMs and OpenVEX documents per image digest, which helps make incident triage a lookup against existing artifacts rather than a reconstruction from scratch. Adoption is often a low-friction Dockerfile change for workloads built on Debian, Ubuntu, RHEL, or Alpine, depending on the workload and its runtime assumptions, and Minimus images are designed to work with common scanners such as Trivy, Grype, Snyk, and AWS Inspector. For regulated environments, FedRAMP-, FIPS 140-3-, NIST SP 800-190-, and STIG-aligned support is documented in the Minimus compliance materials.

Browse the Minimus image gallery at images.minimus.io or compare any current base image against its Minimus equivalent from the documentation at docs.minimus.io.

Frequently Asked Questions

What Is a Container Base Image?

A container base image is the bottommost filesystem layer of a container, declared via the Dockerfile FROM instruction. It typically contains an operating system distribution (Debian, Alpine, Red Hat UBI), shared libraries, and a CA bundle. Every layer above it (application code, runtime, dependencies) inherits the base image's contents, including its CVEs and its attack surface.

What Makes a Base Image Secure?

A base image is secure when it satisfies six criteria: it is minimized (no shell, no package manager, no compiler), it is signed with a verifiable cryptographic signature such as Cosign, it ships an SBOM and VEX document, it is published with a contractual patch SLA for critical CVEs (typically 24–48 hours), its build process produces SLSA Level 3 or higher provenance, and it is mapped to NIST SP 800-190, CIS, FIPS 140-3, STIG, and FedRAMP controls.

What Is the Difference Between a Base Image and a Parent Image in Docker?

A base image is the original parentless layer at the bottom of an image's lineage, built FROM scratch or imported directly from a distribution. A parent image is whatever image your Dockerfile names in its FROM directive. Every parent image has a base image somewhere in its lineage, but not every base image is a parent image.

Are Alpine and Distroless Images Secure by Default?

No. Alpine is small and distroless removes the shell and package manager, both of which reduce attack surface. Neither guarantees a low CVE count, neither provides a signed SBOM by default in their public form, and neither commits to a contractual patch SLA. A secure base image combines a minimization technique like Alpine or distroless with signing, SBOM, and a published patch SLA from the maintainer.

How Often Should I Rebuild My Base Image?

Rebuild whenever an upstream version is published and whenever a critical or high CVE in any of its components is disclosed. The industry-recommended SLA for critical CVEs is 24–48 hours from disclosure to a re-signed, re-attested rebuild. Without automated rebuilds via Renovate, Dependabot, or an internal bot, even a vendor's published patch SLA cannot reach your production deployment.

Yakir Zagron
Backend Developer
Sign up for minimus

Avoid over 97% of container CVEs

Access hundreds of hardened images, secure Helm charts, the Minimus custom image builder, and more.