Skip to main content
Category: Cloud Security

Container Hardening

Also known as: Container Image Hardening, Docker Hardening
Simply put

Container hardening is the process of securing containers by tightening their configuration settings, removing unnecessary components, and restricting access controls to reduce the chance of a security breach. It typically involves steps like using minimal base images, eliminating default credentials, and limiting what the container is allowed to do when it runs. The goal is to shrink the attack surface so that even if an attacker gains access, there is less they can exploit.

Formal definition

Container hardening encompasses a set of security practices applied to container images, runtime configurations, and host environments to minimize the attack surface and reduce exploitable vulnerabilities. Key measures include using minimal or distroless base images, removing unnecessary packages and utilities, enforcing least-privilege principles (such as running as a non-root user), applying read-only filesystems where feasible, configuring resource limits, restricting Linux capabilities, and scanning images for known CVEs. Vulnerability scanners used in the hardening pipeline can produce both false positives (flagging components that are not actually reachable or exploitable in context) and false negatives (missing vulnerabilities not yet cataloged in advisory databases, or embedded in custom code that static image scanners cannot evaluate without execution context). Practitioners should anticipate tuning scanner results accordingly. Frameworks such as the DOD DevSecOps Enterprise Container Hardening Guide provide prescriptive requirements for hardening containers in regulated environments. Container hardening is most effective when integrated across the full container lifecycle, from image build through registry storage to runtime deployment, though runtime-specific threats (such as container escape exploits leveraging kernel vulnerabilities) may require additional host-level and orchestration-level controls beyond image hardening alone.

Why it matters

Containers are widely adopted as a deployment model for modern applications, but their default configurations are often permissive and ship with unnecessary packages, utilities, and elevated privileges. Without deliberate hardening, each container in an environment can become an entry point or lateral movement vector for attackers. Unhardened containers may run as root, include shell utilities that facilitate post-exploitation activity, or contain known CVEs in base image layers that were never reviewed. Reducing this attack surface is a foundational step in defense-in-depth for containerized workloads.

Who it's relevant to

DevSecOps Engineers
DevSecOps engineers are responsible for embedding hardening steps into CI/CD pipelines, including base image selection, vulnerability scanning, and enforcement of build-time security policies. They must also tune scanner results to manage false positives and false negatives effectively.
Platform and Infrastructure Engineers
Platform teams configure the runtime environment, orchestration policies, and host-level controls that complement image hardening. They enforce resource limits, security profiles, and network segmentation for container workloads.
Application Security Teams
AppSec teams define and review hardening standards, assess whether container configurations meet organizational or regulatory requirements, and validate that scanning tools are appropriately integrated and their outputs are acted upon.
Compliance and Risk Officers
In regulated environments, compliance teams must verify that containers meet prescriptive hardening requirements, such as those defined in the DOD DevSecOps Enterprise Container Hardening Guide or similar frameworks, and ensure evidence of hardening is documented for audit purposes.
Software Developers
Developers who author Dockerfiles or container build configurations make early decisions that directly affect the security posture of the resulting image, including base image selection, package inclusion, and user privilege configuration.

Inside Container Hardening

Minimal Base Images
Using stripped-down base images (such as distroless or Alpine-based images) that include only the libraries and binaries required for the application, reducing the overall attack surface by eliminating unnecessary packages and tools.
Least-Privilege Configuration
Running containers as non-root users, dropping unnecessary Linux capabilities, and applying read-only filesystem mounts where feasible to limit the impact of a potential container compromise.
Image Vulnerability Scanning
Scanning container images for known vulnerabilities in OS packages and application dependencies. Scanners typically rely on CVE databases and may produce false negatives for vulnerabilities not yet cataloged, zero-day issues, or custom application code flaws. Scanners can also generate false positives, particularly when a vulnerable package is present in the image but the affected code path is not reachable, so practitioners should anticipate and tune for this behavior.
Seccomp, AppArmor, and SELinux Profiles
Applying mandatory access control and system call filtering profiles to restrict the set of kernel interactions a container process can perform, reducing the blast radius of exploitation attempts.
Image Signing and Provenance Verification
Cryptographically signing container images and verifying signatures before deployment to ensure image integrity and authenticity throughout the software supply chain.
Network Policy Enforcement
Restricting container-to-container and container-to-external network communication using network policies, limiting lateral movement opportunities in the event of a breach.
Immutable and Reproducible Builds
Building container images through deterministic, reproducible pipelines and treating running containers as immutable artifacts that are replaced rather than patched in place.

Common questions

Answers to the questions practitioners most commonly ask about Container Hardening.

If I'm using minimal base images, does that mean my containers are already hardened?
Using minimal base images is an important first step, but it is not sufficient on its own. Container hardening encompasses a broader set of practices including removing unnecessary capabilities, enforcing read-only filesystems where possible, running as non-root users, applying seccomp and AppArmor or SELinux profiles, restricting network access, and continuously scanning for vulnerabilities. A minimal image reduces the attack surface but does not address runtime configuration, privilege management, or ongoing maintenance concerns.
Does container isolation mean a hardened container is as secure as a virtual machine?
Not necessarily. Containers share the host kernel, which means that kernel-level vulnerabilities can potentially allow container escapes regardless of how well the container itself is hardened. Virtual machines provide hardware-level isolation through a hypervisor, offering a stronger boundary in most cases. Container hardening significantly raises the difficulty of exploitation, but it does not make containers equivalent to VMs in terms of isolation guarantees. Some environments address this gap by using microVMs or sandboxed container runtimes for additional isolation.
How should vulnerability scanning be integrated into a container hardening workflow?
Vulnerability scanning should be applied at multiple stages: during image build in CI/CD pipelines, in container registries before deployment, and continuously at runtime. Practitioners should anticipate that scanners may produce both false positives (flagging packages that are not actually exploitable in the given context) and false negatives (missing vulnerabilities in custom code, misconfigurations, or components not covered by the scanner's vulnerability database). Tuning scanner policies, triaging results carefully, and supplementing scanning with additional controls such as runtime monitoring are important to maintain both accuracy and coverage.
What is the recommended approach for managing user privileges inside a hardened container?
Containers should typically run as a non-root user. This can be enforced by specifying a USER directive in the Dockerfile or container image definition and by configuring Kubernetes or the container runtime to reject containers attempting to run as root. Additionally, Linux capabilities should be dropped to the minimum set required for the application to function. In Kubernetes, PodSecurityAdmission or equivalent policy enforcement can be used to prevent privilege escalation and restrict privileged container deployments across the cluster.
How do you enforce read-only filesystems in containers, and what exceptions are typically needed?
Read-only root filesystems can be enforced through container runtime options or orchestrator-level configuration, such as setting readOnlyRootFilesystem to true in a Kubernetes security context. In practice, most applications require writable access to specific paths for temporary files, logs, or caches. These can be accommodated by mounting explicit tmpfs or emptyDir volumes at the required paths while keeping the rest of the filesystem immutable. This approach limits an attacker's ability to modify binaries or install tools if they gain code execution within the container.
How should seccomp and AppArmor or SELinux profiles be developed and applied for hardened containers?
A practical approach is to start with the default seccomp profile provided by Docker or the container runtime, which blocks a set of typically dangerous system calls while permitting common operations. For stricter hardening, custom profiles can be generated by running the application in a profiling mode that records the system calls and file accesses it actually uses, then building a profile that allows only those observed behaviors. These profiles should be tested thoroughly in staging environments, as overly restrictive profiles may cause application failures that are difficult to diagnose. AppArmor and SELinux profiles follow a similar development pattern, constraining file access, network activity, and capability usage at the kernel level.

Common misconceptions

Scanning a container image for vulnerabilities guarantees it is secure.
Vulnerability scanners rely on known CVE databases and typically detect issues in cataloged OS packages and popular library ecosystems. They may miss vulnerabilities in custom application code, logic flaws, misconfigurations, and zero-day exploits (false negatives). They can also flag packages that are present but whose vulnerable code paths are not reachable (false positives). Scanning is a necessary but insufficient component of container hardening.
Containers are inherently isolated and do not require additional hardening beyond the default runtime configuration.
Containers share the host kernel and, under default configurations, may retain elevated capabilities, broad system call access, or root-level privileges. Without explicit hardening measures such as dropping capabilities, applying seccomp profiles, and enforcing non-root execution, containers can present a significant attack surface.
Using a minimal base image alone constitutes sufficient container hardening.
While minimal base images reduce the attack surface by removing unnecessary packages, hardening also requires runtime security controls (least-privilege settings, mandatory access control profiles, network policies), image integrity verification, and ongoing vulnerability management across the image lifecycle.

Best practices

Start from a minimal or distroless base image and explicitly add only the dependencies your application requires, removing shells, package managers, and debugging tools from production images.
Configure containers to run as a non-root user, drop all Linux capabilities by default, and selectively add back only the specific capabilities the application needs.
Apply seccomp, AppArmor, or SELinux profiles tailored to each workload to restrict the system calls and file access patterns available to the container process.
Integrate image vulnerability scanning into CI/CD pipelines and container registries, and establish a process for triaging both false positives and genuine findings so that scan results remain actionable rather than ignored.
Enforce image signing and signature verification at admission time (for example, using policy controllers in Kubernetes) to prevent unsigned or tampered images from being deployed.
Implement network policies that default-deny all traffic and explicitly allow only required communication paths between containers and external services, limiting lateral movement potential.