Amazon EKS Security
Supported Versions: Amazon EKS 1.31, 1.32, 1.33 Last Updated: July 3, 2026
To securely run workloads on Amazon EKS (Elastic Kubernetes Service), you need to understand and implement various security layers and best practices. This document covers key concepts, components, and best practices for strengthening the security of your EKS cluster.
Table of Contents
- EKS Security Overview
- Latest Security Trends (2023)
- IAM and Authentication
- OIDC Provider Deep Dive
- EKS Pod Identity
- Cluster Endpoint Access Control
- Network Security
- Pod Security
- Bottlerocket and Read-Only OS
- IAM Permission Boundaries
- Encryption and Secrets Management
- Compliance and Auditing
- Security Monitoring and Detection
- EKS Security Best Practices
- EKS Security Considerations for Financial Services
EKS Security Overview
Amazon EKS combines the security features of AWS and Kubernetes to provide a multi-layered security architecture. EKS security consists of the following key areas:
- Shared Responsibility Model: AWS manages the security of the EKS control plane, while customers are responsible for the security of worker nodes, containers, and applications.
- Infrastructure Security: Network infrastructure security including VPC, subnets, and security groups
- Cluster Security: Kubernetes API server access control, RBAC, and service accounts
- Workload Security: Container image security, runtime security, and network policies
EKS Security Architecture
Latest Security Trends (2023)
The latest trends and recommendations in the Kubernetes and EKS security domain are as follows:
1. Zero Trust Architecture
Moving away from traditional perimeter-based security models, this approach does not trust any access by default and continuously verifies it.
Implementing Zero Trust in EKS:
- Service Mesh: mTLS communication between services using Istio or AWS App Mesh
- IAM Roles for Service Accounts (IRSA): Fine-grained permission management
- Network Policies: Default deny policies that allow only necessary communication
- OPA/Gatekeeper: Policy-based access control
- AWS Security Hub: Continuous security posture monitoring
2. Supply Chain Security
As software supply chain attacks increase, security of the entire pipeline from container images to deployment has become important.
Key implementation methods:
- Adopt SLSA (Supply-chain Levels for Software Artifacts) framework
- Image signing and verification: Cosign, Notary v2
- SBOM (Software Bill of Materials) generation and management: Syft, Grype
- Image scanning: Amazon ECR image scanning, Trivy, Clair
- GitOps security: Signed commits, secure pipelines
3. Runtime Security and Threat Detection
As container runtime security becomes important, the following technologies are gaining attention:
- eBPF-based security monitoring: Cilium, Falco
- AWS GuardDuty EKS Protection: Runtime threat detection
- Kubernetes Audit log analysis: CloudWatch Logs Insights
- Anomaly behavior detection: Amazon Detective
- Container escape prevention: gVisor, Kata Containers
4. Policy as Code
An approach to managing security policies as code to improve consistency and automation:
- OPA (Open Policy Agent): General-purpose policy engine
- Kyverno: Kubernetes-native policy management
- AWS Config: Compliance monitoring
- Terraform Sentinel: IaC policy enforcement
- AWS CloudFormation Guard: IaC policy validation
IAM and Authentication
EKS Authentication Mechanisms
Amazon EKS provides the following authentication mechanisms:
- AWS IAM Authenticator: Authenticates to the Kubernetes API server using AWS IAM credentials.
- OIDC Provider Integration: Integrates with external OIDC providers (e.g., Active Directory, Okta, Auth0) to manage user authentication.
- IAM Roles for Service Accounts: Links AWS IAM roles to Kubernetes service accounts so pods can securely access AWS services.
IAM Roles and Policy Configuration
EKS Cluster Role
Minimum permissions required when creating an EKS cluster:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"eks:CreateCluster",
"eks:DescribeCluster",
"eks:UpdateClusterConfig",
"eks:DeleteCluster"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PassedToService": "eks.amazonaws.com"
}
}
}
]
}EKS Access Entry
EKS Access Entry is a new method that replaces the aws-auth ConfigMap for managing IAM user and role access to EKS clusters. Access Entry provides the following benefits:
- Improved stability as an AWS-managed solution
- Management through declarative API
- Version control and audit capabilities
- Separation of node IAM role and user/role access management
# Enable Access Entry for the cluster
aws eks update-cluster-config \
--name my-cluster \
--region us-west-2 \
--access-config authenticationMode=API_AND_CONFIG_MAP
# Create Access Entry for IAM role
aws eks create-access-entry \
--cluster-name my-cluster \
--principal-arn arn:aws:iam::123456789012:role/DevTeamRole \
--username dev-team \
--kubernetes-groups dev-team
# Create Access Entry for IAM user
aws eks create-access-entry \
--cluster-name my-cluster \
--principal-arn arn:aws:iam::123456789012:user/admin \
--username admin \
--kubernetes-groups system:masters
# List Access Entries
aws eks list-access-entries --cluster-name my-clusterNote: EKS Access Entry was introduced in 2023 and provides a more stable and easier to manage method than the aws-auth ConfigMap. Existing clusters can migrate to a hybrid mode that supports both methods.
IRSA (IAM Roles for Service Accounts)
IRSA allows you to link AWS IAM roles to Kubernetes service accounts so pods can securely access AWS services.
IRSA Setup Steps
- Create an OIDC provider for the EKS cluster:
eksctl utils associate-iam-oidc-provider --cluster my-cluster --approve- Create IAM role and policy:
eksctl create iamserviceaccount \
--name s3-reader \
--namespace default \
--cluster my-cluster \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
--approve- Associate the service account with a pod:
apiVersion: v1
kind: Pod
metadata:
name: s3-reader
spec:
serviceAccountName: s3-reader
containers:
- name: app
image: amazonlinux:2
command: ['sh', '-c', 'aws s3 ls']OIDC Provider Deep Dive
OpenID Connect (OIDC) is the foundation of IAM Roles for Service Accounts (IRSA) in EKS. Understanding how OIDC works helps you troubleshoot authentication issues and implement secure workload identity patterns.
OIDC Trust Relationship Mechanics
When you create an EKS cluster, AWS automatically creates an OIDC provider endpoint. This endpoint serves as an identity provider that AWS STS trusts to authenticate Kubernetes service accounts.
The trust relationship works as follows:
- EKS issues OIDC tokens to pods via projected service account tokens
- The token contains claims about the pod's identity (namespace, service account name)
- AWS STS validates the token against the OIDC provider's public keys
- If valid, STS issues temporary AWS credentials
STS AssumeRoleWithWebIdentity Flow
Token Exchange Mechanism
The projected service account token is a JWT (JSON Web Token) with the following structure:
{
"aud": ["sts.amazonaws.com"],
"exp": 1234567890,
"iat": 1234567800,
"iss": "https://oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE",
"kubernetes.io": {
"namespace": "default",
"pod": {
"name": "my-pod",
"uid": "1234-5678-9012-3456"
},
"serviceaccount": {
"name": "my-service-account",
"uid": "abcd-efgh-ijkl-mnop"
}
},
"sub": "system:serviceaccount:default:my-service-account"
}Key claims:
- iss: The OIDC provider URL (must match the IAM trust policy)
- sub: The subject (service account identifier)
- aud: The audience (must include
sts.amazonaws.comfor AWS)
OIDC Endpoint Verification
Verify your cluster's OIDC configuration:
# Get OIDC provider URL
aws eks describe-cluster \
--name my-cluster \
--query "cluster.identity.oidc.issuer" \
--output text
# Example output: https://oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE
# List OIDC providers in your account
aws iam list-open-id-connect-providers
# Get OIDC provider details
aws iam get-open-id-connect-provider \
--open-id-connect-provider-arn arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLEJWKS URI and Token Validation
The JWKS (JSON Web Key Set) endpoint provides public keys for token validation:
# Fetch JWKS from OIDC provider
OIDC_URL=$(aws eks describe-cluster --name my-cluster --query "cluster.identity.oidc.issuer" --output text)
curl -s "${OIDC_URL}/.well-known/openid-configuration" | jq .
# Get the JWKS directly
curl -s "${OIDC_URL}/keys" | jq .The JWKS response contains RSA public keys used to verify token signatures:
{
"keys": [
{
"kty": "RSA",
"kid": "key-id-1",
"use": "sig",
"alg": "RS256",
"n": "base64-encoded-modulus",
"e": "AQAB"
}
]
}EKS Pod Identity
EKS Pod Identity is a newer authentication mechanism that simplifies how pods access AWS services. It provides advantages over IRSA while maintaining strong security guarantees.
Advantages over IRSA
| Feature | IRSA | EKS Pod Identity |
|---|---|---|
| Setup Complexity | Requires OIDC provider + IAM role per SA | Simpler Pod Identity Association |
| IAM Role Reuse | One role per service account | Same role across clusters/accounts |
| Session Tags | Limited | Full support for ABAC |
| Cross-Account | Complex trust policies | Simplified with associations |
| Credential Rotation | Token-based, short-lived | Managed by Pod Identity Agent |
| Troubleshooting | Complex token validation | Simpler debugging |
Pod Identity Agent Mechanics
The EKS Pod Identity Agent runs as a DaemonSet on your nodes and handles credential distribution:
Pod Identity Association Setup
Using eksctl:
# Create Pod Identity Association
eksctl create podidentityassociation \
--cluster my-cluster \
--namespace default \
--service-account-name my-app-sa \
--role-arn arn:aws:iam::123456789012:role/MyAppRoleUsing AWS CLI:
# First, create the IAM role with Pod Identity trust policy
cat > trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
EOF
aws iam create-role \
--role-name MyAppRole \
--assume-role-policy-document file://trust-policy.json
# Attach required policies
aws iam attach-role-policy \
--role-name MyAppRole \
--policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
# Create the Pod Identity Association
aws eks create-pod-identity-association \
--cluster-name my-cluster \
--namespace default \
--service-account my-app-sa \
--role-arn arn:aws:iam::123456789012:role/MyAppRoleIRSA to Pod Identity Migration Procedure
Step-by-step migration from IRSA to Pod Identity:
- Install Pod Identity Agent (if not already installed):
aws eks create-addon \
--cluster-name my-cluster \
--addon-name eks-pod-identity-agent \
--addon-version v1.0.0-eksbuild.1- Update IAM role trust policy to support both IRSA and Pod Identity:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/EXAMPLE"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-west-2.amazonaws.com/id/EXAMPLE:sub": "system:serviceaccount:default:my-app-sa"
}
}
},
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}- Create Pod Identity Association:
aws eks create-pod-identity-association \
--cluster-name my-cluster \
--namespace default \
--service-account my-app-sa \
--role-arn arn:aws:iam::123456789012:role/MyAppRole- Test the new authentication by restarting pods:
kubectl rollout restart deployment my-app -n default- Remove IRSA annotations after verifying Pod Identity works:
kubectl annotate serviceaccount my-app-sa \
-n default \
eks.amazonaws.com/role-arn-- Clean up IRSA trust policy from IAM role (optional, after full migration).
Pod Identity Architecture Diagram
Cluster Endpoint Access Control
EKS cluster endpoint access control determines how users and workloads can reach the Kubernetes API server. Proper configuration is essential for security.
Public/Private/Public+Private Endpoint Configuration
EKS supports three endpoint access configurations:
| Configuration | Public Endpoint | Private Endpoint | Use Case |
|---|---|---|---|
| Public Only | Enabled | Disabled | Development, testing |
| Private Only | Disabled | Enabled | High-security production |
| Public + Private | Enabled | Enabled | Balanced security and convenience |
Public Only (default):
- API server accessible from the internet
- Nodes communicate over the internet
- Simplest setup but least secure
Private Only:
- API server only accessible from within VPC
- Requires VPN, Direct Connect, or bastion host for kubectl access
- Nodes communicate over private network
- Most secure option
Public + Private:
- API server accessible from both internet and VPC
- Nodes communicate over private network (more efficient)
- Good balance of security and usability
CIDR Restriction Settings
When using public endpoint, restrict access to specific IP ranges:
# Update cluster to restrict public access
aws eks update-cluster-config \
--name my-cluster \
--resources-vpc-config \
endpointPublicAccess=true,\
endpointPrivateAccess=true,\
publicAccessCidrs="10.0.0.0/8","203.0.113.0/24"Using eksctl:
# cluster-config.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: my-cluster
region: us-west-2
vpc:
clusterEndpoints:
publicAccess: true
privateAccess: true
publicAccessCIDRs:
- 10.0.0.0/8 # Internal corporate network
- 203.0.113.0/24 # Office IP rangePrivate Cluster Operation Patterns
Operating a private-only EKS cluster requires network connectivity solutions:
Pattern 1: VPN Access
# Create Client VPN endpoint
aws ec2 create-client-vpn-endpoint \
--client-cidr-block 10.100.0.0/16 \
--server-certificate-arn arn:aws:acm:us-west-2:123456789012:certificate/abc123 \
--authentication-options Type=certificate-authentication,MutualAuthentication={ClientRootCertificateChainArn=arn:aws:acm:us-west-2:123456789012:certificate/xyz789} \
--connection-log-options Enabled=false \
--vpc-id vpc-12345678Pattern 2: Transit Gateway
Pattern 3: Bastion Host with SSM
# Bastion host deployment for kubectl access
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubectl-bastion
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: kubectl-bastion
template:
metadata:
labels:
app: kubectl-bastion
spec:
serviceAccountName: kubectl-bastion-sa
containers:
- name: bastion
image: amazon/aws-cli:latest
command: ["sleep", "infinity"]
resources:
requests:
memory: "256Mi"
cpu: "100m"Access via SSM Session Manager:
# Start SSM session to bastion pod's node
aws ssm start-session --target i-1234567890abcdef0
# Or use kubectl exec through SSM
aws ssm start-session \
--target i-1234567890abcdef0 \
--document-name AWS-StartPortForwardingSession \
--parameters '{"portNumber":["443"],"localPortNumber":["6443"]}'Endpoint Access Control Configuration Example
Complete example for a production-ready private cluster:
# Create cluster with private endpoint only
eksctl create cluster \
--name production-cluster \
--region us-west-2 \
--vpc-private-subnets subnet-private1,subnet-private2,subnet-private3 \
--without-nodegroup
# Update to private-only endpoint
aws eks update-cluster-config \
--name production-cluster \
--resources-vpc-config \
endpointPublicAccess=false,\
endpointPrivateAccess=true
# Verify endpoint configuration
aws eks describe-cluster \
--name production-cluster \
--query "cluster.resourcesVpcConfig.{PublicAccess:endpointPublicAccess,PrivateAccess:endpointPrivateAccess,PublicCIDRs:publicAccessCidrs}"Required VPC endpoints for private clusters:
# Create required VPC endpoints
for service in ec2 ecr.api ecr.dkr s3 logs sts elasticloadbalancing autoscaling; do
aws ec2 create-vpc-endpoint \
--vpc-id vpc-12345678 \
--service-name com.amazonaws.us-west-2.${service} \
--subnet-ids subnet-private1 subnet-private2 \
--security-group-ids sg-12345678
doneCustomer-Routed Control Plane Egress (June 2026)
Announced: June 18, 2026 · Source
Previously, when the EKS Kubernetes API server needed to reach external endpoints (admission webhooks, private OIDC providers, aggregated API servers), that egress traffic left through an AWS-managed path. With Customer-Routed Control Plane Egress, you can route this control plane egress traffic directly through your own VPC instead.
Supported traffic:
- Admission webhook calls (OPA/Gatekeeper, Kyverno)
- Private OIDC provider access
- Aggregated API server access (e.g., Metrics Server, custom APIs)
Key characteristics:
- Because control plane egress traverses the customer VPC, you can implement a data perimeter and monitor/inspect traffic within your own network
- Enforceable at the organization level using the
eks:controlPlaneEgressModeIAM condition key in an SCP - Can be applied to existing clusters, no additional cost, available in all regions
# Enable customer-routed control plane egress on a cluster
aws eks update-cluster-config \
--name my-cluster \
--resources-vpc-config controlPlaneEgressMode=CUSTOMER_ROUTED// SCP example: enforce customer-routed egress mode
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RequireCustomerRoutedControlPlaneEgress",
"Effect": "Deny",
"Action": [
"eks:CreateCluster",
"eks:UpdateClusterConfig"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"eks:controlPlaneEgressMode": "CUSTOMER_ROUTED"
}
}
}
]
}Network Security
Security Groups
You can use AWS security groups to control network traffic to nodes and pods in your EKS cluster.
Cluster Security Group
The EKS cluster security group allows communication between the control plane and worker nodes:
- Port 443 (HTTPS): Cluster API server communication
- Port 10250: kubelet API
- Port range 1025-65535: Inter-node communication
Node Security Group
Recommended security group configuration for worker nodes:
- Inbound: Allow traffic from cluster security group
- Outbound: Allow all traffic (can be restricted as needed)
Network Policies
You can use Kubernetes network policies to control communication between pods. In EKS, you can implement network policies through network plugins such as Amazon VPC CNI, Calico, and Cilium.
Default Deny Policy Example
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- EgressAllow Policy Example for Specific Applications
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-allow
namespace: default
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080VPC Endpoints
Use VPC endpoints for private access to AWS services to securely access AWS services without going through an internet gateway.
Recommended VPC endpoints for EKS clusters:
- com.amazonaws.region.ecr.api
- com.amazonaws.region.ecr.dkr
- com.amazonaws.region.s3
- com.amazonaws.region.logs
- com.amazonaws.region.sts
Pod Security
Pod Security Standards (PSS)
Pod Security Standards, introduced in Kubernetes 1.23, provide a built-in mechanism for restricting the security context of pods. You can apply the following levels of PSS in EKS:
- Privileged: No restrictions
- Baseline: Prevent known privilege escalation
- Restricted: Apply strong security restrictions
Example of applying PSS to a namespace:
apiVersion: v1
kind: Namespace
metadata:
name: secure-ns
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restrictedSecurity Context
You can configure security context at the pod and container level to restrict privileges:
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: secure-container
image: nginx
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALLOPA Gatekeeper and Kyverno
You can apply security policies across the cluster using policy engines like OPA Gatekeeper or Kyverno.
Kyverno Policy Example - Prevent Privileged Containers
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-privileged-containers
spec:
validationFailureAction: enforce
rules:
- name: privileged-containers
match:
resources:
kinds:
- Pod
validate:
message: "Privileged containers are not allowed"
pattern:
spec:
containers:
- name: "*"
securityContext:
privileged: falseBottlerocket and Read-Only OS
Bottlerocket is a purpose-built, security-focused operating system designed specifically for running containers. It provides enhanced security through its minimal footprint and immutable design.
Bottlerocket Characteristics
API-Based Configuration:
- No SSH access by default
- Configuration changes through API (apiclient)
- Settings persisted across reboots
- Changes validated before application
# Example: Configure Bottlerocket settings via user data
[settings.kubernetes]
cluster-name = "my-cluster"
api-server = "https://EXAMPLE.gr7.us-west-2.eks.amazonaws.com"
cluster-certificate = "BASE64_ENCODED_CERT"
[settings.kubernetes.node-labels]
"node.kubernetes.io/os" = "bottlerocket"
[settings.kubernetes.node-taints]
"bottlerocket" = "true:NoSchedule"Automatic Updates:
- Wave-based update deployment
- Automatic rollback on failure
- Configurable update windows
# Configure update settings
[settings.updates]
targets-base-url = "https://updates.bottlerocket.aws/"
version-lock = "1.15.%" # Lock to specific minor versionSELinux Enforcement
Bottlerocket runs SELinux in enforcing mode by default:
- Process Isolation: Containers cannot access host resources
- File System Protection: Strict access controls on system files
- Network Isolation: Controlled network access between processes
SELinux provides mandatory access control that prevents:
- Container escape attacks
- Privilege escalation
- Unauthorized file access
dm-verity (Root Filesystem Integrity)
dm-verity provides cryptographic verification of the root filesystem:
Key benefits:
- Tamper Detection: Any modification to system files is detected
- Boot-Time Verification: System integrity verified before containers start
- Read-Only Root: Root filesystem mounted read-only
Immutable Infrastructure Strategy
Bottlerocket enables a true immutable infrastructure approach:
- No In-Place Updates: Replace nodes instead of patching
- Consistent State: Every node starts from a known-good image
- Audit Trail: All changes tracked through AMI versions
- Fast Recovery: Roll back by launching previous AMI
Implementation pattern:
# Node group with Bottlerocket
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: secure-cluster
region: us-west-2
managedNodeGroups:
- name: bottlerocket-ng
instanceType: m5.large
desiredCapacity: 3
amiFamily: Bottlerocket
bottlerocket:
settings:
kubernetes:
node-labels:
os: bottlerocket
host-containers:
admin:
enabled: false # Disable admin container for productionUsing Bottlerocket with EKS Managed Node Groups
Complete setup for Bottlerocket managed node groups:
# Create managed node group with Bottlerocket
aws eks create-nodegroup \
--cluster-name my-cluster \
--nodegroup-name bottlerocket-nodes \
--node-role arn:aws:iam::123456789012:role/EKSNodeRole \
--subnets subnet-1 subnet-2 subnet-3 \
--ami-type BOTTLEROCKET_x86_64 \
--instance-types m5.large \
--scaling-config minSize=2,maxSize=10,desiredSize=3 \
--update-config maxUnavailable=1Using eksctl with advanced configuration:
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: production-cluster
region: us-west-2
managedNodeGroups:
- name: bottlerocket-workers
instanceType: m5.xlarge
minSize: 3
maxSize: 20
desiredCapacity: 5
amiFamily: Bottlerocket
volumeSize: 100
volumeType: gp3
volumeEncrypted: true
iam:
attachPolicyARNs:
- arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
- arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
- arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
bottlerocket:
settings:
kubernetes:
node-labels:
workload-type: general
os: bottlerocket
node-taints:
- key: "CriticalAddonsOnly"
value: "true"
effect: "NoSchedule"
kernel:
sysctl:
"net.core.somaxconn": "32768"
"net.ipv4.tcp_max_syn_backlog": "32768"
host-containers:
admin:
enabled: false
control:
enabled: trueIAM Permission Boundaries
IAM Permission Boundaries provide a mechanism to set the maximum permissions that an IAM entity can have, regardless of what policies are attached to it.
Permission Boundary Concept
The effective permissions are the intersection of identity-based policies and permission boundaries:
Effective Permissions = Identity Policy ∩ Permission BoundaryExample scenario:
- Identity policy allows:
s3:*,ec2:*,rds:* - Permission boundary allows:
s3:*,ec2:Describe* - Effective permissions:
s3:*,ec2:Describe*
SCP (Service Control Policy) Usage
SCPs provide guardrails at the AWS Organizations level:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyEKSClusterDeletion",
"Effect": "Deny",
"Action": "eks:DeleteCluster",
"Resource": "*",
"Condition": {
"StringNotLike": {
"aws:PrincipalArn": "arn:aws:iam::*:role/EKSAdminRole"
}
}
},
{
"Sid": "RequireIMDSv2",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringNotEquals": {
"ec2:MetadataHttpTokens": "required"
}
}
},
{
"Sid": "DenyPublicEKSEndpoint",
"Effect": "Deny",
"Action": "eks:UpdateClusterConfig",
"Resource": "*",
"Condition": {
"Bool": {
"eks:endpointPublicAccess": "true"
}
}
}
]
}Least Privilege IAM Policy Patterns
Best practices for EKS IAM policies:
Pattern 1: Namespace-Scoped Permissions
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowNamespaceOperations",
"Effect": "Allow",
"Action": [
"eks:DescribeCluster",
"eks:ListClusters"
],
"Resource": "*"
},
{
"Sid": "AllowSpecificClusterAccess",
"Effect": "Allow",
"Action": [
"eks:AccessKubernetesApi"
],
"Resource": "arn:aws:eks:us-west-2:123456789012:cluster/production-cluster",
"Condition": {
"StringEquals": {
"eks:namespaces": ["team-a", "team-a-staging"]
}
}
}
]
}Pattern 2: Resource-Based Restrictions
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowECRPull",
"Effect": "Allow",
"Action": [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:BatchCheckLayerAvailability"
],
"Resource": "arn:aws:ecr:us-west-2:123456789012:repository/approved-*"
},
{
"Sid": "AllowECRAuth",
"Effect": "Allow",
"Action": "ecr:GetAuthorizationToken",
"Resource": "*"
}
]
}Pattern 3: Condition-Based Access
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3AccessWithTags",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::app-bucket/*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/Environment": "${aws:PrincipalTag/Environment}"
}
}
}
]
}EKS Node Role Permission Boundary Example
Apply permission boundaries to EKS node roles to limit blast radius:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowEKSNodeOperations",
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeVolumes",
"ec2:DescribeNetworkInterfaces",
"ec2:AttachVolume",
"ec2:DetachVolume",
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
},
{
"Sid": "DenyPrivilegedActions",
"Effect": "Deny",
"Action": [
"iam:*",
"organizations:*",
"account:*",
"eks:DeleteCluster",
"eks:UpdateClusterConfig",
"ec2:DeleteVpc",
"ec2:DeleteSubnet",
"ec2:DeleteSecurityGroup"
],
"Resource": "*"
},
{
"Sid": "AllowSecretsInNamespace",
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "arn:aws:secretsmanager:*:*:secret:/eks/production/*"
}
]
}Apply the boundary to the node role:
# Create permission boundary
aws iam create-policy \
--policy-name EKSNodePermissionBoundary \
--policy-document file://node-permission-boundary.json
# Apply boundary to node role
aws iam put-role-permissions-boundary \
--role-name EKSNodeRole \
--permissions-boundary arn:aws:iam::123456789012:policy/EKSNodePermissionBoundary
# Verify boundary is applied
aws iam get-role --role-name EKSNodeRole --query "Role.PermissionsBoundary"Proactive Governance with 7 New IAM Condition Keys (April 2026)
Announced: April 20, 2026 · Source
Amazon EKS added seven new IAM condition keys that let you enforce policy-based, proactive governance at cluster creation and update time. These conditions can be applied to the CreateCluster, UpdateClusterConfig, UpdateClusterVersion, and AssociateEncryptionConfig APIs, and integrated with AWS Organizations SCPs.
| Condition Key | Purpose |
|---|---|
eks:endpointPublicAccess / eks:endpointPrivateAccess | Enforce use of the private endpoint |
eks:encryptionConfigProviderKeyArns | Require KMS-based secrets encryption |
eks:kubernetesVersion | Restrict cluster creation/upgrade to approved Kubernetes versions |
eks:controlPlaneScalingTier | Restrict the control plane scaling tier |
eks:deletionProtection | Enforce cluster deletion protection |
eks:zonalShiftEnabled | Control whether zonal shift is enabled |
// SCP example: require private endpoint and KMS encryption
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RequirePrivateEndpointAndKmsEncryption",
"Effect": "Deny",
"Action": [
"eks:CreateCluster",
"eks:UpdateClusterConfig"
],
"Resource": "*",
"Condition": {
"Bool": {
"eks:endpointPublicAccess": "true"
}
}
},
{
"Sid": "RequireEncryptionConfig",
"Effect": "Deny",
"Action": "eks:CreateCluster",
"Resource": "*",
"Condition": {
"Null": {
"eks:encryptionConfigProviderKeyArns": "true"
}
}
},
{
"Sid": "RestrictKubernetesVersion",
"Effect": "Deny",
"Action": [
"eks:CreateCluster",
"eks:UpdateClusterVersion"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"eks:kubernetesVersion": ["1.32", "1.33"]
}
}
}
]
}Encryption and Secrets Management
EKS Encryption Options
etcd Encryption
EKS encrypts Kubernetes secrets stored in etcd by default. You can use AWS KMS for an additional layer of encryption:
eksctl create cluster --name my-cluster --region us-west-2 --encryption-provider-config-key arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890abAWS Secrets Manager and Parameter Store Integration
You can use External Secrets Operator or AWS Secrets and Configuration Provider (ASCP) to mount secrets stored in AWS Secrets Manager or Parameter Store to Kubernetes pods.
Install External Secrets Operator
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets -n external-secrets --create-namespaceDefine SecretStore and ExternalSecret
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: aws-secretsmanager
spec:
provider:
aws:
service: SecretsManager
region: us-west-2
auth:
jwt:
serviceAccountRef:
name: external-secrets-sa
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-credentials
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secretsmanager
kind: SecretStore
target:
name: db-credentials
data:
- secretKey: username
remoteRef:
key: db-credentials
property: username
- secretKey: password
remoteRef:
key: db-credentials
property: passwordSOPS (Secrets OPerationS)
You can use Mozilla SOPS to securely store and manage encrypted secrets in Git repositories.
SOPS Installation and Usage
# Install SOPS
brew install sops
# Encrypt secrets using AWS KMS key
sops --encrypt --aws-profile default --kms arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab secrets.yaml > secrets.enc.yaml
# Decrypt encrypted secrets
sops --decrypt secrets.enc.yamlCompliance and Auditing
EKS Audit Logging
You can enable EKS control plane audit logs to record all API calls made in the cluster:
aws eks update-cluster-config \
--region us-west-2 \
--name my-cluster \
--logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'AWS Config Rules
You can use AWS Config to monitor the compliance status of your EKS cluster:
- eks-cluster-logging-enabled
- eks-cluster-oldest-supported-version
- eks-endpoint-no-public-access
- eks-secrets-encrypted
AWS Security Hub Integration
You can use AWS Security Hub to centrally manage and monitor the security posture of your EKS cluster. Security Hub checks compliance against industry standards such as the CIS Kubernetes Benchmark.
Security Monitoring and Detection
GuardDuty EKS Protection
You can enable Amazon GuardDuty EKS Protection to detect potential security threats in your EKS cluster:
aws guardduty update-detector \
--detector-id 12abc34d567e8fa901bc2d34e56789f0 \
--features '[{"Name": "EKS_RUNTIME_MONITORING", "Status": "ENABLED"}]'AWS Security Hub
You can use AWS Security Hub to centrally manage and monitor the security posture of your EKS cluster:
aws securityhub enable-security-hub
aws securityhub batch-enable-standards --standards-subscription-requests '[{"StandardsArn":"arn:aws:securityhub:us-west-2::standards/aws-foundational-security-best-practices/v/1.0.0"}]'Falco
You can use Falco to perform runtime security monitoring and anomaly detection:
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm install falco falcosecurity/falco --namespace falco --create-namespaceFalco rule example:
- rule: Terminal shell in container
desc: A shell was spawned by a pod in the container
condition: container and shell_procs and not container_entrypoint
output: Shell spawned in a container (user=%user.name pod=%k8s.pod.name container=%container.name shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline)
priority: WARNINGEKS Security Best Practices
Cluster Security Hardening
- Maintain Latest Kubernetes Version: Regularly upgrade EKS cluster to latest version to apply security patches
- Use Private API Endpoint: Restrict access to API server from public internet
- Apply Principle of Least Privilege: Apply principle of least privilege to IAM roles and RBAC
- Restrict Security Groups: Configure security groups to allow only necessary ports
- Implement Network Policies: Apply network policies to restrict communication between pods
Node and Container Security
- Use Latest AMI: Use EKS-optimized AMI with latest security patches
- Scan Container Images: Use ECR image scanning or tools like Trivy for vulnerability scanning
- Use Immutable Infrastructure: Create new node groups and delete old node groups when updating nodes
- Run Containers as Non-Root User: Run containers as non-root user to limit privileges
- Use Read-Only Filesystem: Mount container root filesystem as read-only when possible
Continuous Security Monitoring
- Enable Audit Logging: Enable EKS control plane audit logs
- Enable GuardDuty EKS Protection: Enable GuardDuty EKS Protection for runtime security monitoring
- Security Hub Integration: Use AWS Security Hub for centralized security posture management
- Regular Security Assessments: Perform regular security assessments based on CIS Kubernetes Benchmark
- Establish Incident Response Plan: Establish and test security incident response plan for EKS cluster
EKS Security Considerations for Financial Services
Additional security requirements to consider when using EKS in the financial services industry:
Regulatory Compliance
- PCI DSS: PCI DSS requirements compliance for workloads processing card payment data
- GDPR/CCPA: Compliance with data protection regulations for personally identifiable information (PII)
- Financial Regulations: Compliance with domestic financial regulatory requirements (e.g., Financial Supervisory Service guidelines)
Data Security
- Encryption in Transit: Encrypt all network communications using TLS 1.2 or higher
- Data at Rest Encryption: Encrypt data at rest using AWS KMS
- Data Classification: Classify data by sensitivity and apply appropriate security controls
- Data Access Logging: Detailed logging and monitoring for all sensitive data access
High Availability and Disaster Recovery
- Multi-AZ Deployment: Deploy EKS cluster across multiple availability zones
- Disaster Recovery Plan: Establish disaster recovery plan including regular backups and recovery testing
- Business Continuity: Define RTO (Recovery Time Objective) and RPO (Recovery Point Objective) appropriate for financial services
EKS Security Architecture Example for Financial Services
Conclusion
Amazon EKS security is implemented through a multi-layered defense strategy. You can securely operate your EKS cluster through strong authentication and authorization via IAM and RBAC, network security through network policies and security groups, workload security through Pod Security Standards and security context, and integration with various AWS security services.
In industries with strict regulations such as financial services, additional security controls and compliance requirements should be considered. It is important to maintain the security posture of your EKS environment through regular security assessments, vulnerability scanning, and continuous monitoring.
References
- Amazon EKS Security Best Practices
- Kubernetes Security Best Practices
- CIS Kubernetes Benchmark
- AWS Security Hub
- Amazon GuardDuty
- Amazon EKS Customer-Routed Control Plane Egress (2026-06-18)
- Amazon EKS New IAM Condition Keys (2026-04-20)
Quiz
To test what you learned in this chapter, try the topic quiz.