EKSKubernetesSecurity

AWS EKS Security: Hardening Kubernetes Clusters on AWS

Vigilare Engineering

Platform Team · January 11, 2026 · 10 min read

EKS security requires attention at multiple layers simultaneously: AWS account level (IAM roles for service accounts, VPC configuration), Kubernetes level (RBAC, pod security, network policies), and container level (image security, runtime policies). A security gap at any layer can undermine the others — perfect network segmentation with overly permissive pod service accounts still allows a compromised pod to make unauthorized AWS API calls.

This guide covers the high-priority security configurations for each layer, with emphasis on the AWS-specific controls that differentiate EKS from other Kubernetes deployments.

IAM Roles for Service Accounts (IRSA)

The most important EKS-specific security feature: IAM Roles for Service Accounts (IRSA) allows Kubernetes service accounts to assume IAM roles, giving pods fine-grained AWS permissions without node-level credentials. Before IRSA, the common approach was attaching IAM permissions to the EC2 node role — meaning every pod on the node had the same AWS permissions, regardless of what the pod needed.

With IRSA, each deployment or pod specification references a Kubernetes service account that's annotated with an IAM role ARN. Pods using that service account receive short-lived credentials for the annotated role through the projected service account token mechanism. The IAM role's trust policy restricts assumption to the specific service account and namespace:

{
  "Effect": "Allow",
  "Principal": {"Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/XXXXXXXXXX"},
  "Action": "sts:AssumeRoleWithWebIdentity",
  "Condition": {
    "StringEquals": {
      "oidc.eks.us-east-1.amazonaws.com/id/XXXXXXXXXX:sub": "system:serviceaccount:production:order-processing-sa",
      "oidc.eks.us-east-1.amazonaws.com/id/XXXXXXXXXX:aud": "sts.amazonaws.com"
    }
  }
}

This trust policy allows only the order-processing-sa service account in the production namespace to assume the role. Other pods in the cluster using different service accounts cannot assume this role.

Kubernetes RBAC and Least Privilege

EKS uses Kubernetes RBAC for cluster-level authorization. Key security principles:

No cluster-admin for regular workloads: Service accounts and user roles should have the minimum Kubernetes permissions needed. ClusterAdmin grants access to every Kubernetes resource in the cluster — reserve it for the few users who genuinely need full cluster management access.

Namespace isolation: Use separate namespaces for different workloads, with RBAC roles scoped to the appropriate namespace. A service account that can list pods in the production namespace shouldn't have the same permission in other namespaces.

Audit RBAC regularly: Run kubectl get clusterrolebindings,rolebindings -A periodically to review what permissions are granted at the cluster and namespace level. Tools like rbac-lookup and kubectl-who-can simplify RBAC auditing.

Pod Security Controls

Kubernetes Pod Security Admission (PSA) enforces security policies at the pod level. Configure the restricted profile for namespaces running untrusted or user-provided workloads; baseline for most production workloads; privileged only for system-level components that genuinely need privileged access.

The restricted PSA profile prevents running as root, prevents privilege escalation, requires read-only root filesystems, and limits Linux capabilities. These restrictions eliminate entire classes of container escape vulnerabilities without requiring detailed knowledge of each specific attack vector.

Network Policies

Without Kubernetes NetworkPolicies, all pods in a cluster can communicate with each other regardless of namespace. Enable a CNI plugin that supports NetworkPolicy (Calico, Cilium, or the AWS VPC CNI with network policy support) and define policies that restrict pod-to-pod communication to explicitly allowed paths.

A default deny-all policy for a namespace, combined with specific allow policies for required communication paths, implements the principle of least privilege at the network layer within the cluster:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: production
spec:
  podSelector: {}
  policyTypes: [Ingress]

This policy denies all inbound traffic to pods in the production namespace. Add specific NetworkPolicy resources to allow traffic from the load balancer, from specific pods in specific namespaces, and for inter-service communication. Each allowed path is explicitly documented in the NetworkPolicy resource.

Image Security with ECR and Inspector

Container images are a significant supply chain risk — base images with unpatched CVEs, compromised dependencies, and secrets baked into image layers. Use Amazon ECR with AWS Inspector scanning enabled to scan all pushed images for vulnerabilities. Configure Inspector to block deployments of images with critical vulnerabilities by integrating scan results with your CI/CD pipeline's image acceptance criteria.

Enable ECR image scanning on push for all repositories. Review findings in the ECR console or via the Inspector API. Set up EventBridge notifications for HIGH and CRITICAL findings on production image repositories so your team is alerted when vulnerabilities are detected in images that may already be running in production.

GuardDuty EKS Protection

GuardDuty's EKS Protection analyzes Kubernetes API server audit logs for suspicious activity. Enable both EKS Audit Log Monitoring and EKS Runtime Monitoring for production clusters. Runtime monitoring requires the GuardDuty security agent deployed as an EKS Add-on — it observes runtime behavior within running containers and can detect container escape attempts, process injection, and unusual file system access. See the GuardDuty setup guide for enabling EKS protection.

Related Reading

FAQ

Should I use managed node groups or self-managed nodes?

Managed node groups are generally preferable from a security perspective — AWS handles node OS updates, security patches, and lifecycle management. Self-managed nodes require you to manage all of this manually, which creates more opportunity for drift and missed patches. Use managed node groups unless you have specific requirements that only self-managed nodes can meet (custom AMIs, specific kernel configurations, etc.).

How do I handle secrets in Kubernetes pods?

Use AWS Secrets Manager or SSM Parameter Store with the Secrets Store CSI Driver for Kubernetes. The CSI driver mounts secrets from AWS Secrets Manager as volumes in pods, removing the need to store secrets in Kubernetes Secrets objects (which are base64-encoded, not encrypted at rest by default). The mounting is controlled by IRSA — the pod must have IAM permissions to access the specific secrets it needs.

What's the blast radius if a pod is compromised in an EKS cluster?

With proper controls (IRSA for minimal AWS permissions, NetworkPolicies restricting pod-to-pod communication, Pod Security Admission preventing privilege escalation), the blast radius is limited to: the specific AWS resources the pod's IRSA role can access, the other pods in the cluster that the NetworkPolicy allows the compromised pod to reach, and the Kubernetes resources the pod's service account has RBAC permissions to modify. Without these controls, a compromised pod can potentially access all AWS resources on the node role, reach any other pod in the cluster, and modify any Kubernetes resource the default service account can access.

Protect your AWS accounts before it's too late

Vigilare monitors your AWS accounts for suspension risks — billing anomalies, IAM issues, GuardDuty findings, and more — and alerts you before AWS takes action.

Written by Vigilare Engineering

Platform Team