Container security on AWS comes down to hardening four layers: the image you build, the ECR registry you store it in, the runtime that runs it (ECS, EKS, or Fargate), and the IAM permissions that tie it all together. Get those four right and you have closed the gaps behind nearly every container incident on AWS. Most breaches here are not exotic exploits — they are an over-permissive role, an unscanned image, or a security group left wide open.
AWS operates a shared-responsibility model: AWS secures the underlying infrastructure, and you secure your configuration, images, and access. The container-specific work all sits on your side of that line.
Start with the image
Everything downstream inherits the image's problems, so it is the right place to start. An image on AWS should be built from a minimal, pinned base, run as a non-root user, and carry no baked-in secrets.
FROM public.ecr.aws/docker/library/python:3.12-slim@sha256:<digest>
RUN useradd --create-home appuser
USER appuser
COPY --chown=appuser:appuser . /app
Pin base images by digest so builds are reproducible. Pull base images from Amazon ECR Public or a trusted mirror rather than unauthenticated public sources, which reduces the odds of a poisoned upstream. And never put credentials in environment variables baked into the image — use AWS Secrets Manager or SSM Parameter Store and inject at runtime.
Scanning the image for known vulnerabilities is non-negotiable, because it inherits every CVE in its OS packages and dependencies. Software composition analysis maps that transitive tree; a tool such as our SCA product surfaces inherited risk you would otherwise miss.
Lock down ECR
Amazon Elastic Container Registry (ECR) is where your images live, and it has security features worth turning on:
- Enable scan-on-push. ECR can scan images automatically when they are pushed, either basic scanning or enhanced scanning powered by Amazon Inspector. Enhanced scanning also rescans existing images as new CVEs are published, which is the continuous coverage you actually need.
- Use private repositories with resource policies that grant pull access only to the roles that need it. A public ECR repo holding a proprietary image is a leak waiting to happen.
- Enable tag immutability so a tag cannot be silently overwritten with different content. This makes your deployments auditable.
- Set lifecycle policies to expire old, unscanned, or untagged images so stale vulnerable artifacts do not linger.
Combined with image signing, these turn ECR from a passive store into an enforcement point.
Runtime: ECS, EKS, and Fargate
How you run containers on AWS changes your security model.
Fargate removes the host from your responsibility — AWS manages the underlying compute, so you cannot (and do not need to) patch a node OS. This eliminates a whole class of host-level findings, which is why Fargate is often the more secure default for teams without deep Kubernetes expertise.
ECS on EC2 and EKS give you more control and more responsibility. You own the node OS patching, the kubelet configuration, and the cluster hardening. For EKS specifically, the controls that matter most:
- Enable the EKS control plane audit logs and ship them to CloudWatch.
- Use IAM Roles for Service Accounts (IRSA) so each pod gets only the permissions it needs, rather than inheriting the node's role.
- Apply network policies to segment pod-to-pod traffic, and use security groups for pods where supported.
- Run an admission controller that rejects images from unapproved registries or those failing policy.
- Do not run privileged containers, and drop unnecessary Linux capabilities.
# EKS pod security context: non-root, no privilege escalation
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
IAM is where the real damage happens
The single most impactful control on AWS is least-privilege IAM. A compromised container with an over-broad task role or node role can pivot across your account; a compromised container with a tightly scoped role can barely move.
The failure mode is depressingly common: a task role granted s3:* on * "to make it work," never tightened. When that container is breached, the attacker gets every bucket in the account. Scope task roles to the specific ARNs and actions each service needs.
For EKS, IRSA is the mechanism that makes this practical — each service account maps to an IAM role, so a pod cannot borrow another workload's permissions or the node's. Avoid attaching broad policies to the node instance role, because every pod on that node inherits them absent IRSA.
The misconfigurations that actually cause incidents
If you audit for nothing else, audit for these, because they account for the overwhelming majority of real-world container incidents on AWS:
- Over-permissive IAM roles on tasks, pods, or nodes.
- Security groups open to
0.0.0.0/0on ports that should be internal. - Unscanned or stale images with known critical CVEs running in production.
- Secrets baked into images or passed as plaintext environment variables.
- Containers running as root or privileged without need.
None of these require a sophisticated attacker. They require an attacker who runs a scanner and waits for one of them to appear, which is why continuous configuration monitoring beats point-in-time review. The Academy covers building these checks into a pipeline so they are enforced rather than hoped for.
Tie it together with continuous monitoring
Point-in-time hardening decays. A role gets loosened for a hotfix, an image goes stale as new CVEs land, a security group opens for a debug session and never closes. Continuous scanning of both your image inventory and your AWS configuration is what catches that drift before an attacker does. Amazon Inspector, GuardDuty, and Security Hub cover parts of this natively; pair them with dependency scanning so the software layer is watched alongside the infrastructure.
FAQ
Is Fargate more secure than EKS?
Fargate removes host and node OS management from your responsibility, eliminating a class of patching and node-hardening risks, which makes it a safer default for teams without Kubernetes depth. EKS offers more control but hands you more to secure. Neither removes the need for image scanning and least-privilege IAM.
Does ECR scan images automatically?
ECR supports scan-on-push in both basic mode and enhanced mode powered by Amazon Inspector. Enhanced scanning also continuously rescans stored images as new vulnerabilities are published, which is what you want since unchanged images become vulnerable over time.
What is the most common cause of AWS container breaches?
Misconfiguration, not exotic exploits. Over-permissive IAM roles, security groups open to the internet, and unscanned images with known critical CVEs cause the majority of real incidents. Fixing those three closes most of your exposure.
How do I give a pod on EKS least-privilege AWS access?
Use IAM Roles for Service Accounts (IRSA), which maps a Kubernetes service account to a scoped IAM role. This gives each pod only the permissions it needs instead of inheriting the broad node instance role, containing the blast radius if a pod is compromised.