Amazon EKS — Production Security Checklist
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
baselineon 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
latesttag 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}'