The Attack Surface of Containers
Containers give you process isolation, not security isolation. A misconfigured container can expose the host kernel, leak secrets, or become a pivot point for lateral movement. Understand the attack surface first:
- Container images - Vulnerable libraries, hardcoded credentials, unnecessary tools
- Container runtime - Vulnerabilities that allow breakouts
- Orchestrator misconfigurations (Kubernetes RBAC, network policies) - Expose services, grant excessive permissions
- Supply chain - Compromised base images or dependencies
- Secrets - Baked into images or environment variables that any process can access
Security requires defense in depth across the entire lifecycle: build, ship, run.
Image security
Use minimal base images
Every additional package in a container image is a potential vulnerability. Prefer minimal base images:
| |
Distroless images contain only your application and its runtime dependencies — no shell, no package manager, no unnecessary binaries. This dramatically reduces the attack surface.
Multi-stage builds
Multi-stage builds let you compile in one stage and copy only the final artifact to a minimal runtime image:
| |
The build tools, source code, and intermediate files never make it into the final image.
Never run as root
Running containers as root means a container escape gives the attacker root on the host. Always specify a non-root user:
| |
In Kubernetes, enforce this with Pod Security Standards (more on this below).
Secure vs. insecure Dockerfile comparison
Here is a side-by-side comparison of common mistakes versus secure practices:
| |
| |
Key differences: minimal base image, multi-stage build, no secrets in the image, non-root user, only necessary ports exposed, health check included.
Image scanning with Trivy
Trivy is an open-source vulnerability scanner that checks container images, filesystems, and IaC configurations. Integrate it into your CI pipeline to catch vulnerabilities before deployment.
Basic image scan
| |
Scanning in CI/CD
Add Trivy to your pipeline so that no image with critical vulnerabilities reaches production:
| |
Scanning IaC and filesystems
Trivy goes beyond container images:
| |
Runtime security with Falco
While scanning catches vulnerabilities at build time, Falco monitors containers at runtime. It uses kernel-level instrumentation to detect suspicious behavior:
- Unexpected shell spawns inside containers.
- Processes reading sensitive files (
/etc/shadow,/etc/passwd). - Outbound network connections to unexpected destinations.
- Privilege escalation attempts.
Example Falco rules
| |
Deploy Falco as a DaemonSet in your Kubernetes cluster to get visibility into runtime behavior across all nodes.
Kubernetes security
Pod Security Standards
Kubernetes Pod Security Standards define three levels of restriction:
- Privileged — Unrestricted (for system-level workloads only).
- Baseline — Prevents known privilege escalations.
- Restricted — Heavily restricted, following security best practices.
Apply them at the namespace level:
| |
NetworkPolicies
By default, all pods in Kubernetes can communicate with each other. NetworkPolicies let you restrict traffic:
| |
This policy ensures the API pod only receives traffic from the frontend and only sends traffic to the database.
RBAC
Follow the principle of least privilege. Avoid giving cluster-admin to service accounts. Create specific roles:
| |
Regularly audit RBAC bindings with tools like kubectl-who-can or rbac-tool.
Secrets management
Never store secrets in container images, environment variables in plain Dockerfiles, or version control. Instead:
- Use Kubernetes Secrets (encrypted at rest with KMS).
- Use external secrets managers: HashiCorp Vault, AWS Secrets Manager, Azure Key Vault.
- Use the External Secrets Operator to sync secrets from external providers into Kubernetes.
- Rotate secrets regularly and audit access.
Supply chain security
Signed images
Sign your container images with cosign (part of the Sigstore project) and verify signatures before deployment:
| |
SBOM (Software Bill of Materials)
Generate an SBOM for every image so you can quickly check whether a newly disclosed CVE affects your running containers:
| |
Container security checklist
Use this checklist to assess your container security posture:
- Base images are minimal (distroless or Alpine).
- Multi-stage builds are used to exclude build tools.
- Containers run as non-root users.
- Images are scanned for vulnerabilities in CI/CD.
- No secrets are stored in images or plain environment variables.
- Kubernetes Pod Security Standards are enforced.
- NetworkPolicies restrict pod-to-pod communication.
- RBAC follows least privilege.
- Runtime security monitoring is in place (Falco or equivalent).
- Images are signed and signatures are verified before deployment.
- SBOMs are generated and stored for all production images.
- Secrets are managed through an external secrets manager.
- Image pull policies are set to
Alwaysfor mutable tags. - Regular security audits and penetration tests are conducted.
Conclusion
Container security is an ongoing practice, not a one-time task. Start with basics: minimal images, non-root users, scanning. Then layer on runtime monitoring, network policies, supply chain verification, and automated enforcement. Each layer shrinks the blast radius and moves you closer to actual security.