All posts
Kubernetes

EKS Security: The Production Hardening Checklist

By

January 8, 2025

9 min read

Kubernetes has a large attack surface. The checklist we work through before any EKS cluster goes to production.

EKS
Kubernetes
Security
AWS

Kubernetes has a significantly larger attack surface than running the same workload on ECS or Lambda. The API server, etcd, node metadata service, service accounts, and network policies all represent potential attack vectors. Most EKS clusters we review for the first time have at least one critical misconfiguration.

This is the checklist we use before any EKS cluster handles production traffic. It is not exhaustive — advanced hardening goes deeper — but it covers the controls that catch most real-world incidents.

1. Control plane access

  • API server endpoint: either disable the public endpoint entirely (force VPN/bastion access) or restrict it to a specific CIDR (your VPN or office IP range). Default public endpoint + no CIDR restriction means your API server is exposed to the entire internet.

  • Enable envelope encryption for Kubernetes Secrets: EKS stores Secrets in etcd; enabling KMS envelope encryption means a compromised etcd backup does not expose Secret values. Enable this at cluster creation — enabling later requires node rotation.

  • Enable control plane audit logging: CloudWatch Logs for the EKS control plane captures API server audit events. Essential for incident investigation and SOC 2 compliance.

  • Use IAM roles for kubectl access via EKS Access Entries: avoid static IAM users in aws-auth ConfigMap. EKS Access Entries (the newer API) are easier to manage and audit.

  • Enable OIDC provider: required for IRSA (IAM Roles for Service Accounts) — the mechanism for giving pods AWS credentials without long-lived keys.

2. Node-level security

  • Use EKS-optimized AMIs: AWS maintains EKS-optimized Amazon Linux 2023 and Bottlerocket AMIs with patched kernels and security configurations (it stopped publishing Amazon Linux 2 AMIs in November 2025, and EKS Auto Mode runs Bottlerocket for you). Karpenter defaults to these — verify this in your EC2NodeClass AMI selector.

  • Set EC2 instance metadata service (IMDS) hop limit to 1: the default hop limit of 2 allows pods to make requests to the instance metadata service (169.254.169.254), which could expose node-level IAM credentials. Set hop limit to 1 in your launch template or EC2NodeClass so only processes on the host (not in containers) can reach IMDS.

  • Harden node security groups: node security groups should only allow inbound from the control plane, from the load balancer, and from within the cluster. Deny all other inbound from the internet.

  • Enable EBS encryption for node volumes: all EKS node root volumes should use encrypted EBS. This is a one-line option in your launch template and protects data on terminated nodes.

  • Rotate node groups for OS patches: do not in-place patch nodes. Drain and terminate old nodes, launch new ones with updated AMIs. Karpenter's disruption feature makes this straightforward.

Want a second opinion on this for your system?

Book a free 30-minute call. You'll leave knowing what we'd do first and roughly what it costs, whether or not you hire us.

3. Workload isolation

  • Enforce Pod Security Standards: use the restricted or baseline standard via namespace labels (pod-security.kubernetes.io/enforce: restricted). Alternatively, use Kyverno policies for more granular control with better audit visibility.

  • Apply network policies per namespace: default-deny ingress and egress in each namespace, then allow only the specific traffic flows each service needs. Use Calico or the VPC CNI network policy support.

  • Disable automountServiceAccountToken where not needed: Kubernetes automatically mounts service account tokens into pods. If a workload does not need to call the Kubernetes API, set automountServiceAccountToken: false in the pod spec.

  • Set CPU and memory requests and limits on all pods: Karpenter bins pods based on requests — pods without requests cause unpredictable placement and can cause OOMKills. Limits prevent noisy neighbor issues.

  • No privileged containers except where explicitly required and reviewed: privileged containers have full host access. If a workload requires this (e.g., a CSI driver), it should be explicitly approved and audited.

4. IAM and credentials

  • Use IRSA or EKS Pod Identity for AWS access: never mount long-lived AWS credentials as Kubernetes Secrets or environment variables. IRSA scopes credentials to a specific namespace and service account. EKS Pod Identity (the newer approach) is simpler to configure.

  • Scope service account tokens to namespace: IRSA trust policies should specify the exact namespace and service account name — not a wildcard. Overly broad trust allows privilege escalation.

  • Audit unused service accounts quarterly: service accounts accumulate. Remove service accounts that are no longer referenced by any workload, and audit associated IAM role policies for unused permissions.

  • Use Secrets Manager or Parameter Store for application secrets: Kubernetes Secrets are base64-encoded, not encrypted, by default. Mount secrets from Secrets Manager via the Secrets Store CSI Driver rather than native Kubernetes Secrets.

  • Rotate all credentials on node recycle: any credentials that were ever present on a node (even via IMDS) should be rotated after the node is terminated. This is generally automatic with IRSA but verify your rotation procedures.

5. Image supply chain

  • ECR lifecycle policies: automatically remove untagged images older than 7 days and limit the number of tagged images per repository. Stale images accumulate quickly and waste storage and scanning resources.

  • Enable ECR enhanced scanning on push: ECR enhanced scanning (powered by Snyk) scans images for OS and programming language vulnerabilities on push and daily. Configure alerts for critical and high findings.

  • Sign images with Cosign: sign your production images with Cosign (Sigstore) and enforce signature verification via a Kyverno policy. This prevents deploying tampered or unverified images.

  • Kyverno policy to require signed images in production: block any deployment to production namespaces that does not reference a Cosign-signed image. This is enforced at admission time.

  • Restrict container registries to ECR only: use an admission webhook or Kyverno policy to deny pods that reference images from public registries (docker.io, gcr.io) in production namespaces.

6. Runtime detection

  • Falco for runtime syscall monitoring: Falco monitors Linux system calls and alerts on suspicious behavior — unexpected shell execution in a container, unexpected network connections, privilege escalation attempts. Run as a DaemonSet.

  • AWS GuardDuty EKS Protection: GuardDuty analyzes EKS audit logs for malicious API activity — reconnaissance, privilege escalation attempts, and known attack patterns. Enable in all accounts running EKS clusters.

  • Alert on kubectl exec to production pods: kubectl exec bypasses your normal deployment workflow and is frequently used by attackers. Alert on this in your SIEM or via CloudWatch Logs Insights on the EKS audit log.

  • Privileged container admission alert: even if your policy allows privileged containers in some cases, alert every time a privileged container is admitted to production. This should be rare and always intentional.

The audit table

Control Area

Check

Priority

Tool

Control plane

Public API endpoint restricted or disabled

Critical

EKS cluster config

Control plane

Envelope encryption for Secrets (KMS)

High

EKS cluster config

Control plane

Audit logging to CloudWatch Logs

High

EKS logging config

Control plane

OIDC provider enabled

High

EKS OIDC config

Nodes

IMDS hop limit = 1

Critical

Launch template / EC2NodeClass

Nodes

EKS-optimized AMI (not custom)

High

EC2NodeClass AMI selector

Nodes

EBS volume encryption

High

Launch template

Workloads

Pod Security Standards enforced

High

Namespace labels / Kyverno

Workloads

Network policies (default deny)

High

Calico / VPC CNI

Workloads

Resource requests and limits on all pods

Medium

Kyverno policy / LimitRange

IAM

IRSA or Pod Identity for all AWS access

Critical

IRSA / EKS Pod Identity

Images

ECR enhanced scanning enabled

High

ECR settings

Images

Registry restricted to ECR (production)

Medium

Kyverno policy

Runtime

GuardDuty EKS Protection enabled

High

GuardDuty

Runtime

Falco DaemonSet deployed

Medium

Helm chart

hoolco Monthly Review

Once a month: what changed in tech that month and what it means for you, from cloud and AI to security and the tools you build with. Every item links to its source. No sales pitch, unsubscribe in one click.

As of January 8, 2025. Provided as is, for general information, and accurate to the best of our knowledge on the date shown. Not legal, compliance, tax, financial or other professional advice. Prices, limits and vendor services change; check current vendor documentation before relying on anything here. Terms of use.