Developer Productivity & Platform EngineeringPlaybook3 min readUpdated September 2026

Hardening Containers: The Checks That Actually Stop Real Attacks

Container security checklists tend to have thirty items on them, and not all thirty carry equal weight. A few specific practices close the paths attackers actually use. The rest are good hygiene, but they're not where your limited time should go first.

Vendors Covered in this Article

Disclosure: We may earn a commission if you buy through some links on this page. It doesn't change what we recommend.

Don't Run as Root Inside the Container

This is the single highest-value fix on most hardening lists, and it's often skipped because the base image defaults to root and nobody changes it. A process running as root inside a container that escapes its isolation has root on the host, full stop.

Set a non-root user explicitly in your Dockerfile and verify it in CI, not just at build time on someone's laptop. This is a small change with an outsized effect on what an attacker can do if they get a foothold.

Scan Images for Known Vulnerabilities Before They Ship

Base images accumulate known vulnerabilities over time as new CVEs get disclosed against the packages inside them. Federal patch guidance treats closing a known exploited vulnerability as a tight-clock obligation, and that same clock is a reasonable bar to hold your own image scanning process to, even without a legal requirement to do so1.

Scan at build time and block the pipeline on anything critical, not just at deploy time when it's already too late to catch it before the image reaches a registry other services might pull from.

Minimize What's in the Image, Not Just What's Exposed

A debugging shell, a package manager, or a compiler left in a production image isn't a functionality most services need, and each one is a tool an attacker can use if they get in. Build from a minimal base image and strip anything the running application doesn't actually need at runtime.

This is the difference between a container that's merely locked from the outside and one that has nothing useful inside it even if someone gets past the lock.

Read-Only Filesystems Catch What Scanning Misses

Mounting the container's filesystem as read-only, with explicit writable volumes only where the application genuinely needs to write, blocks a whole category of attack that persists by writing a malicious file to disk. It's a cheap change that most teams skip simply because it's not the first thing anyone thinks of.

Where Real Attacks Actually Land

In practice, most container compromises come from a known vulnerability in a dependency that was never patched, combined with a process running as root that let the attacker escalate. Fix those two things first, root and patch cadence, before spending time on more exotic hardening steps further down the checklist.

For example, a service image is built on a default base that runs as root and includes a shell, and one dependency inside it has a known exploited vulnerability that was never patched. An attacker who exploits it lands as root with tools already available. Two changes break that chain: switch to a non-root user, and patch or block the image at build time. Neither needs new tooling, only a Dockerfile edit and a CI rule. Do these before spending time on more exotic items further down a long checklist.

Work through these checks in priority order:

  1. Set a non-root user explicitly in the Dockerfile and verify it in CI, not just on a laptop.
  2. Scan images at build time and block the pipeline on anything critical, then rescan running images on a regular schedule.
  3. Build from a minimal base image without a debugging shell, package manager, or compiler.
  4. Mount the filesystem read-only, with writable volumes only where the application genuinely needs to write.
  5. Apply the same checks to third-party and vendor images running in your deployment.

Don't Let Hardening Become a One-Time Project

A hardening pass that happens once, when a security review is scheduled, and never again is a snapshot that starts going stale the day it's finished. New base image versions get published, new CVEs get disclosed against packages you're already running, and a policy that isn't enforced in CI quietly drifts as new services get added without it.

Bake the checks that matter most, non-root, scanning, read-only filesystem, into your CI pipeline as blocking checks, not a checklist someone runs by hand before a compliance deadline. That's what keeps hardening current instead of a one-time exercise.

Third-Party Images Deserve the Same Scrutiny as Your Own

It's easy to harden the images your own team builds and forget that a base image pulled from a public registry, or a sidecar container from a vendor, carries the same risk if it's running as root or hasn't been scanned recently.

Apply your hardening standards to every image in your deployment, not just the ones your team wrote. A vendor's container is still running on your infrastructure with the same access to your network as anything you built yourself, so pull it into your regular scanning and policy checks rather than treating it as someone else's responsibility to secure just because your team didn't write the original code.

Executive Capability Standard

What Good Looks Like

Solid container hardening means non-root by default, images scanned and blocked on critical vulnerabilities before shipping, and a minimal, mostly read-only runtime footprint.

Building The Capability (5-Stage Skill Ladder)

1. Learn:Audit your current base images for root users, unnecessary packages, and how recently they were scanned.
2. Do Manually:Manually fix your highest-traffic service's Dockerfile first: non-root user, minimal base image, read-only filesystem.
3. Delegate:Assign image hardening standards to a specific engineer to write down and enforce in code review.
4. Automate:Add vulnerability scanning to your CI pipeline with a hard block on critical findings before deploy.
5. Buy:Bring in a dedicated scanning and endpoint security platform once manual image review can't keep pace with your deploy volume.

How to Get Started

Disclosure: We may earn a commission if you buy through some links on this page. It doesn't change what we recommend.

Frequently Asked Questions

Is image scanning enough on its own, or do we need runtime protection too?

Scanning catches known vulnerabilities before deploy, but it can't catch a zero-day or a misconfiguration exploited at runtime. Runtime protection tools add a second layer, but for most small teams, consistent scanning plus the basic hardening steps (non-root, minimal image, read-only filesystem) cover the majority of real risk first.

How often should we rescan images already in production?

At least weekly, since new vulnerabilities get disclosed against existing packages constantly, even if you haven't changed the image yourself. An image that was clean at build time can have a newly disclosed critical vulnerability a month later.

Do these hardening steps apply the same way to a managed Kubernetes service?

Yes, the container-level practices, non-root, minimal image, read-only filesystem, scanning, apply regardless of who manages the orchestration layer. A managed service handles infrastructure security, not what's inside the images you deploy to it.

Sources

Where we quote a benchmark, we show its source. Other figures in this guide are estimates or general guidance, so check them against your own numbers.

  1. Security patch remediation SLAs (CISA federal mandates, used as industry norm). CISA Binding Operational Directives 19-02 and 22-01 (CISA briefing hosted at NIST CSRC), 2022.

Related Guides