Amazon EKS — Production Security Checklist

2 minute read

Security in EKS spans AWS IAM, Kubernetes RBAC, network controls, encryption, and supply chain. Address each domain.


IAM & Authentication

  • Access entries or aws-auth configured — only required identities have cluster access
  • No wildcard system:masters — use granular RBAC roles instead
  • SSO integration — via AWS IAM Identity Center or OIDC provider
  • Cluster creator identity documented — stored securely as break-glass access
  • IRSA for all workloads that need AWS access — no long-lived credentials in pods
  • Node IAM role has minimal permissions — only EKS, ECR, and SSM policies
  • IMDSv2 enforced on all nodes — block IMDSv1 (token hop limit = 1)

RBAC

  • Namespace-scoped roles — use Role/RoleBinding, not ClusterRole for app teams
  • No default service account privileges — disable automountServiceAccountToken where not needed
  • RBAC audit — kubectl auth can-i --list --as=system:serviceaccount:default:default
  • Dedicated service accounts per workload — never share between applications

Pod Security

  • Pod Security Standards enforced — at least baseline on all namespaces
  • No privileged containers — securityContext.privileged: false
  • Read-only root filesystem — readOnlyRootFilesystem: true
  • Non-root user — runAsNonRoot: true, runAsUser: 1000
  • Drop all capabilities — drop: ["ALL"], add back only what’s needed
  • No hostNetwork, hostPID, hostIPC — unless absolutely necessary

Example secure pod spec:

securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  fsGroup: 1000
containers:
  - name: app
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop: ["ALL"]

Encryption

  • Secrets encryption at rest — EKS envelope encryption with KMS
  • EBS volumes encrypted — default encryption enabled in account or via StorageClass
  • ECR image encryption — KMS or AES-256
  • TLS in transit — all Service-to-Service communication over TLS (service mesh or app-level)
  • Rotate KMS keys — on schedule

Image Security

  • ECR image scanning enabled — basic or enhanced (Inspector)
  • Tag immutability enabled — prevent overwriting images
  • Only trusted registries allowed — OPA/Gatekeeper or Kyverno to enforce
  • No latest tag in production — always use specific image digests or version tags
  • Base images updated regularly — for OS-level CVE patches

Control Plane Logging

  • All log types enabled — api, audit, authenticator, controllerManager, scheduler
  • Logs sent to CloudWatch — with retention policy (e.g., 90 days)
  • CloudWatch alarms — on authentication failures and unauthorized API calls

Network Security

  • Security groups reviewed — cluster SG + node SGs follow least privilege
  • No 0.0.0.0/0 ingress on node security groups
  • Network policies enforced — default deny + explicit allow per namespace
  • VPC Flow Logs enabled — for network forensics

Validation Commands

# Check secrets encryption
aws eks describe-cluster --name my-cluster \
  --query 'cluster.encryptionConfig'

# Check control plane logging
aws eks describe-cluster --name my-cluster \
  --query 'cluster.logging.clusterLogging[?enabled==`true`].types[]'

# Check pod security standards
kubectl get namespaces -o jsonpath='{range .items[*]}{.metadata.name}: {.metadata.labels.pod-security\.kubernetes\.io/enforce}{"\n"}{end}'

# Check service accounts with automount
kubectl get serviceaccounts -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}: automount={.automountServiceAccountToken}{"\n"}{end}'

# Check ECR scanning
aws ecr describe-repositories --query 'repositories[*].{Name:repositoryName,Scanning:imageScanningConfiguration.scanOnPush}'

Updated: