Amazon EKS Security Best Practices: Access, RBAC, Network Policies, and Secrets

A new EKS cluster is not secure by default. Locking it down means combining AWS-level controls (IAM, Access Entries, pod identity) with Kubernetes-level controls (RBAC, network policies, pod security) and operational hygiene (logging, patching, upgrades). This page covers all of those layers so you can move a cluster from “it works” to “it is production-ready.”

What “securing EKS” actually means

Analogy

Think of an EKS cluster like a large office building. The front door (cluster access) controls who gets in. The badge reader at each floor (RBAC) controls which rooms each person can enter. The locked filing cabinets (secrets encryption) protect sensitive documents. Security cameras (logging) record what happened. And the building’s maintenance contract (version upgrades) ensures the locks and systems stay in good working order. Skipping any one of these creates a real gap, regardless of how solid the others are.

EKS security is not one setting. It is a set of distinct layers, each addressing a different attack surface:

  • Cluster access controls who can authenticate and which AWS API actions they can take
  • Kubernetes RBAC controls what authenticated identities can do inside the cluster
  • Workload identity controls which AWS services individual pods can call
  • Network isolation controls which pods can communicate with which services
  • Secrets protection controls how sensitive values stored in Kubernetes are protected at rest
  • Pod and node hardening covers container privileges, image hygiene, and node patching
  • Logging and detection ensures you can see what happened and investigate problems
  • Upgrade hygiene keeps the cluster on a supported Kubernetes version with security patches applied

A gap at any layer can undermine the others. A pod with no Kubernetes permissions but a vulnerable image running as root can escape its container and access the host node. A developer who keeps their IAM role after leaving is an open door. This guide walks through each layer in order of impact.

Start here: highest-impact actions first

Where to start

If you have limited time, these are the highest-impact changes for most EKS clusters:

  • Switch to EKS Access Entries for cluster access management
  • Use IRSA or EKS Pod Identity so pods get their own narrow IAM roles
  • Apply namespace-scoped RBAC and remove any cluster-admin bindings for regular developers
  • Enable NetworkPolicies to restrict pod-to-pod traffic at service boundaries
  • Turn on EKS control plane audit logging before you need it
  • Run containers as non-root in production namespaces
  • Stay within the Kubernetes version support window
  • Audit IAM and RBAC access quarterly

How EKS security works: shared responsibility

AWS secures the control plane. The API server, etcd, scheduler, and controller manager are patched, replicated, and fully managed by AWS. Everything else is your responsibility.

LayerWhat it coversWho owns it
Kubernetes control planeAPI server, etcd, scheduler, controller managerAWS
Control plane accessWho can authenticate and what AWS API actions they can takeYou
Kubernetes RBACWhat authenticated users can do inside the clusterYou
Workload identityWhich AWS services individual pods can callYou
Network policiesWhich pods can talk to which services inside the clusterYou
Secrets protectionHow sensitive values are protected at restShared (AWS provides tools; you configure them)
Pod and node hardeningContainer privileges, image hygiene, node patchingYou
Logging and detectionAudit trails, control plane logs, runtime alertsYou (must be enabled)
Version managementKubernetes upgrades and add-on patchingYou (AWS executes, you initiate)
Common misconception

”Managed” in EKS means the control plane. It does not mean the cluster secures itself. RBAC, network policies, pod hardening, logging, and version upgrades remain your responsibility in every EKS mode, including Auto Mode.

Who this guidance is for

This page is for teams running real workloads on EKS who want to move from “cluster works” to “cluster is secure,” engineers taking a dev or staging cluster and making it production-ready, and anyone deciding what to lock down first.

If you are new to EKS, read Amazon EKS Overview first. If you need to understand how pods get network identity inside a cluster, EKS Networking Model is a useful companion.

1. Secure cluster access

When you create an EKS cluster, the IAM identity that created it automatically gets system:masters (cluster admin). All other IAM identities must be explicitly granted access.

EKS Access Entries (the modern default)#

Access Entries manage cluster access through the EKS API. No manual ConfigMap editing, no YAML formatting risk. Changes are atomic, and every modification is recorded in AWS CloudTrail.

# Create an access entry for a developer IAM role
aws eks create-access-entry \
  --cluster-name my-cluster \
  --principal-arn arn:aws:iam::123456789012:role/my-developer-role \
  --type STANDARD

# Associate a scoped policy (read-only within the production namespace)
aws eks associate-access-policy \
  --cluster-name my-cluster \
  --principal-arn arn:aws:iam::123456789012:role/my-developer-role \
  --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy \
  --access-scope '{"type":"namespace","namespaces":["production"]}'

aws-auth ConfigMap (legacy background)#

The aws-auth ConfigMap in kube-system was the original mechanism. Many older clusters still use it. It works, but a single YAML formatting error makes the ConfigMap invalid and locks all non-creator users out of the cluster with no simple recovery path.

# Legacy approach: use Access Entries for new clusters
apiVersion: v1
kind: ConfigMap
metadata:
  name: aws-auth
  namespace: kube-system
data:
  mapRoles: |
    - rolearn: arn:aws:iam::123456789012:role/my-developer-role
      username: developer
      groups:
        - developer-group
Access Entries vs aws-auth ConfigMap
Access Entriesaws-auth ConfigMap
Managed viaEKS API or ConsoleManual YAML in kube-system
CloudTrail auditableYesNo
Risk of lockoutVery low (atomic API)Real (YAML formatting errors)
Recommended forAll new clustersExisting clusters only

Least privilege and break-glass access#

Developers should not have eks:* permissions on production clusters at the IAM level. Reserve cluster-admin access for a dedicated break-glass IAM role that requires explicit approval to assume. It should not be part of any developer’s everyday role.

2. Give pods narrow AWS permissions

Common security mistake

Attaching a broad IAM role to a node group means every pod on those nodes inherits the node’s permissions. A compromised pod then has access to every AWS service the node can reach: S3 buckets, DynamoDB tables, SSM parameters, all of it.

The right approach is IAM Roles for Service Accounts (IRSA) or EKS Pod Identity. Both give individual pods their own narrow IAM role, scoped to exactly what that workload needs.

With IRSA, you associate a Kubernetes service account with an IAM role. Only pods using that service account assume that role. Everything else on the node gets nothing.

# Annotate the service account with the IAM role it should assume
kubectl annotate serviceaccount my-app-sa \
  -n production \
  eks.amazonaws.com/role-arn=arn:aws:iam::123456789012:role/my-app-s3-read-role

EKS Pod Identity (newer) associates pod identity through the EKS API directly, without the OIDC setup that IRSA requires. Both approaches achieve the same isolation goal.

The key rule: node IAM roles should only have permissions needed to function as EKS nodes. AWS service permissions belong on the pod, not the node.

3. Use Kubernetes RBAC correctly

RBAC governs what authenticated identities can do inside the cluster. There are four object types:

  • Role grants permissions within a single namespace
  • ClusterRole grants permissions cluster-wide, or defines a reusable permission set
  • RoleBinding binds a Role (or ClusterRole) to a user, group, or service account within a namespace
  • ClusterRoleBinding binds a ClusterRole cluster-wide

Here is a developer who needs read access to pods and logs in production:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: developer-read
  namespace: production
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-read-binding
  namespace: production
subjects:
- kind: User
  name: developer
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: developer-read
  apiGroup: rbac.authorization.k8s.io
Do not do this

Giving all developers ClusterRoleBinding with cluster-admin grants full control over the entire cluster: delete all pods, modify RBAC, read every Secret. Reserve cluster-admin for a dedicated break-glass role. Use namespace-scoped Roles for day-to-day work.

4. Limit network reachability

Analogy

Without network policies, your cluster pods are like offices in a building where every room has unlocked doors and anyone can walk into any other room. Network policies are the locks on those doors — you decide which rooms can connect to which, and everything else stays blocked by default.

By default, every pod in a Kubernetes cluster can talk to every other pod. Kubernetes NetworkPolicy objects restrict this.

What enforces NetworkPolicy in EKS#

The Amazon VPC CNI plugin has supported Kubernetes NetworkPolicy enforcement natively since late 2023. For most EKS workloads, you no longer need a separate CNI plugin just to apply basic ingress and egress rules.

For more advanced use cases (L7 policies, mutual TLS between pods, complex multi-tenant policy models), tools like Calico or Cilium provide richer policy primitives beyond the standard NetworkPolicy API.

A basic policy allowing only the frontend namespace to reach a backend API:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: web-api-ingress
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: web-api
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: frontend
    ports:
    - protocol: TCP
      port: 8080

Without this policy, web-api pods accept traffic from any pod in the cluster. With it, only pods in frontend can reach port 8080.

Private API endpoint access#

By default, the EKS API server is publicly accessible (protected by IAM and TLS, but reachable from any IP). As part of defense in depth, switch to private-only endpoint access or enable IP allowlisting. See Private EKS Clusters for the configuration details and trade-offs.

5. Protect secrets and sensitive data

How EKS handles Secrets today#

EKS encrypts all etcd data at rest using AWS-managed keys by default. This includes Kubernetes Secrets. In practice: someone who gains direct access to etcd storage cannot read raw unencrypted Secret values.

What this does not protect: a user or service account with sufficient Kubernetes API permissions can still kubectl get secret and read the value. Encryption at rest is one layer. Kubernetes RBAC controls who can actually access Secrets through the API.

Customer-managed KMS encryption#

If you want envelope encryption with a key you control (so you can audit usage, rotate it on your schedule, and revoke access by disabling the key), enable it explicitly:

aws eks create-cluster \
  --name my-cluster \
  --kubernetes-version 1.30 \
  --encryption-config '[{"resources":["secrets"],"provider":{"keyArn":"arn:aws:kms:us-east-1:123456789012:key/my-key-id"}}]'

For existing clusters, add encryption configuration via the AWS Console or CLI. New Secrets are encrypted with the KMS key once enabled; existing Secrets must be re-applied. See AWS KMS Overview for key management concepts.

Beyond Kubernetes Secrets#

For sensitive values like database passwords and API keys, consider reading Managing Secrets in Kubernetes on AWS. That page covers using AWS Secrets Manager with the External Secrets Operator or the CSI Secrets Store driver, which pull values directly from Secrets Manager at runtime and avoid storing sensitive data in Kubernetes Secrets entirely.

6. Harden pods, nodes, and images

Quick wins

These three changes cover the majority of pod-level risk for most teams: run as non-root, drop all Linux capabilities you do not need, and use read-only filesystems where your app allows it.

Run containers as non-root#

Most public container images default to running as root (UID 0). In production, set a non-root user explicitly:

securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  runAsGroup: 3000

Drop unnecessary Linux capabilities#

Containers start with a default set of Linux capabilities. Drop everything and add back only what your application actually needs:

securityContext:
  capabilities:
    drop:
      - ALL
    add:
      - NET_BIND_SERVICE  # only if your app binds to ports below 1024

Use read-only filesystems where possible#

Prevent a compromised container from writing to disk:

securityContext:
  readOnlyRootFilesystem: true

Use Kubernetes emptyDir volumes for directories that genuinely need write access (temp files, caches).

Apply Kubernetes Pod Security Standards#

Pod Security Standards (PSS) define three levels enforced at the namespace level. Apply them via namespace labels:

kubectl label namespace production \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/warn=restricted \
  pod-security.kubernetes.io/audit=restricted
  • Privileged has no restrictions (system workloads only)
  • Baseline blocks the most dangerous configurations while staying compatible with most apps
  • Restricted requires non-root, drops capabilities, and enforces strong hardening

Node patching and image hygiene#

AWS publishes updated EKS-optimized AMIs regularly. For managed node groups, roll out AMI updates on a regular schedule rather than waiting for a critical CVE to force a rushed update. See EKS Managed Node Groups for how rolling AMI updates work.

For container images: scan for known vulnerabilities using Amazon ECR’s built-in image scanning. Pin image tags to specific digests rather than :latest. Rebuild and redeploy images regularly to pick up base image security updates. The Amazon ECR Overview covers image scanning and lifecycle policies.

7. Turn on logs, audit trails, and detections

Securing a cluster is not just about prevention. It is also about having the data to detect problems when they happen and investigate them afterwards.

EKS control plane logging#

EKS can send control plane logs to CloudWatch. These are disabled by default. Enable them for production clusters:

aws eks update-cluster-config \
  --name my-cluster \
  --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'
The audit log matters most

The audit log type records every request to the Kubernetes API server: who made it, what resource was accessed, and whether it was allowed or denied. Without it, you have no visibility into what happened in your cluster. Enable it before you have an incident, not after.

CloudTrail#

All AWS-level EKS actions (creating clusters, modifying Access Entries, updating node groups) are recorded in AWS CloudTrail. This is your audit trail at the AWS layer. Ensure CloudTrail is enabled in the account and that logs are retained in a bucket you control.

Application and node logs#

For container application logs and forwarding to CloudWatch, see Logging in Kubernetes on AWS with Fluent Bit. For metrics, Container Insights, and alerting, see Monitoring EKS Clusters.

Security detections#

AWS Security Hub aggregates findings from GuardDuty, Inspector, and other sources into a single view. GuardDuty has EKS-specific threat detection: it identifies anomalous API server activity, suspicious pod launches, and privilege escalation patterns using the Kubernetes audit log as input. No additional agents required.

8. Keep the cluster current

Running an end-of-life Kubernetes version means no security patches for the control plane or for EKS-optimized AMIs. This is a real risk, not a theoretical one.

EKS version lifecycle#

EKS supports each Kubernetes version for approximately 14 months under standard support. After that, extended support is available for roughly 12 additional months at an extra cost per cluster per hour. Extended support gives teams time to migrate. It is not a long-term solution.

After extended support ends, AWS will auto-upgrade clusters to the next supported version. A forced upgrade is rarely the right time to discover breaking changes.

Do not rely on forced upgrades

Teams that wait until AWS forces an upgrade tend to discover incompatibilities at the worst possible time. Track version support dates, start planning an upgrade at least two months before the standard support window closes, and test add-ons for compatibility with the target version before touching production.

# Check your current cluster version
aws eks describe-cluster --name my-cluster --query 'cluster.version'

EKS only supports upgrading one minor version at a time. If you are on 1.27 and want to reach 1.30, you must go through 1.28 and 1.29 first. For the full upgrade process and pre-upgrade checklist, see Upgrading EKS Clusters Safely.

Common mistakes

  1. Giving all developers cluster-admin. cluster-admin grants complete control: delete all pods, modify RBAC, read every Secret. Use namespace-scoped Roles for day-to-day work. Reserve cluster-admin for a dedicated break-glass role, not everyday developer IAM roles.
  2. Using broad node IAM roles for pod AWS access. A node-level IAM role that can access all S3 buckets means every pod on that node can too. Use IRSA or EKS Pod Identity to give individual pods only the permissions they need.
  3. No network policies in production. The default allow-all pod networking is fine for development. In production, a compromised pod can reach every other service in the cluster. Add NetworkPolicies at service boundaries as a baseline.
  4. No EKS audit logging. Without control plane logging enabled, you have no visibility into API server activity. You will not know who deleted a deployment, which pod tried to read a secret it should not, or what triggered a cluster change. Enable audit logging before you need it.
  5. Ignoring the version lifecycle. Teams routinely discover they are running an end-of-support version when AWS starts sending forced-upgrade warnings. Plan upgrades proactively.
  6. Containers running as root with no capability drops. Most images default to root. A container breakout from a root process with full Linux capabilities is far more damaging than one from a non-root process. Set runAsNonRoot: true and drop all capabilities for production workloads.
  7. Stale RBAC and IAM entries. Access accumulates silently. Engineers leave teams, projects get deprecated. Audit cluster access quarterly and remove anything no longer needed.

Frequently asked questions

Is aws-auth ConfigMap still the best way to manage EKS access?

No. EKS Access Entries are the modern default. Access Entries manage cluster access through the EKS API, so changes are atomic and show up in CloudTrail. The aws-auth ConfigMap still works, but a single YAML formatting error can lock all non-creator users out of the cluster with no easy recovery. For new clusters, use Access Entries.

Do I need both RBAC and IAM in EKS?

Yes, they serve different purposes. IAM controls whether an identity can authenticate to the cluster and what AWS API actions it can perform. Kubernetes RBAC controls what authenticated identities can do inside the cluster. A user with full IAM access but no RBAC permissions cannot list pods or read secrets, and vice versa.

Are Kubernetes Secrets encrypted by default in EKS?

EKS encrypts all etcd data at rest using AWS-managed keys by default, which includes Secrets. If you want envelope encryption with a customer-managed KMS key (so you control key policy and audit key usage), you need to enable it explicitly at cluster creation or add it later. This is recommended for production workloads handling sensitive data.

Do I need network policies if I already use security groups?

They address different layers. Security groups control traffic between AWS resources at the VPC level. Kubernetes NetworkPolicies control pod-to-pod traffic inside the cluster, regardless of which node pods run on. For production clusters, you typically want both: security groups for external boundaries, NetworkPolicies for internal isolation between services.

How often should I review or upgrade an EKS cluster?

Review access, RBAC bindings, and IAM roles quarterly. Access accumulates and stale entries are a real risk. For version upgrades, EKS standard support runs approximately 14 months per version. Plan upgrades at least two months before the standard support window closes to avoid rushed migrations under pressure.

Last verified: 4 April 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.