This issue has been assessed as high severity. Review affected configurations immediately.
Why this guide
This is an evergreen hardening guide, not breaking news. Our search for cloud security items from the past 48 hours found nothing dated and openable as of 3 November 2026, so we are not forcing a news hook.
On EKS, the boundary between “a pod was compromised” and “an AWS account was compromised” is the IAM role trust policy. Sources we opened on 3 November 2026:
- AWS EKS User Guide, EKS Pod Identity
- AWS EKS User Guide, IAM roles for service accounts
- AWS EKS User Guide, Assign an IAM role to a Kubernetes service account
All three are AWS documentation, so every claim below attributed to them is single-vendor. The commands are untested in our lab and use placeholders. Statements marked “our assessment” are our own judgement.
What the documentation says
- Both IRSA and Pod Identity associate an IAM role with a Kubernetes service account so pods stop sharing the node role.
- Credential isolation only holds when access to the EC2 Instance Metadata Service (IMDS) is restricted. If IMDS is not restricted, containers can also reach the node IAM role and may reach roles of other pods on the same node. Pods with
hostNetwork: truealways have IMDS access. - AWS states that containers are not a security boundary and that node components such as
kubelet,kube-proxyand CSI drivers have extra Kubernetes API permissions. - Pod Identity uses the single principal
pods.eks.amazonaws.com. The documented trust policy allowssts:AssumeRoleandsts:TagSession, and AWS says session tags can be used in condition keys to restrict which service accounts, namespaces and clusters may use the role.
Our assessment: the Pod Identity trust policy shown in the docs is deliberately generic. Any association in any cluster in the account can point at a role that trusts that principal, so the role is only as tight as the conditions you add and who may create associations.
Audit 1: block pod access to IMDS
Check that nodes require IMDSv2 with a hop limit of 1, which stops containers from reaching the endpoint through the node’s network namespace:
aws ec2 describe-instances --filters "Name=tag:eks:cluster-name,Values=CLUSTER_NAME" \
--query "Reservations[].Instances[].[InstanceId,MetadataOptions.HttpTokens,MetadataOptions.HttpPutResponseHopLimit]" \
--output table
Anything showing optional or a hop limit above 1 needs a reason. Set it on a launch template, then roll the node group:
aws ec2 modify-instance-metadata-options --instance-id i-0123456789abcdef0 \
--http-tokens required --http-put-response-hop-limit 1
Test first: workloads that rely on node credentials or hostNetwork will break.
Audit 2: find IRSA roles with loose trust
List roles whose trust policy uses web identity federation, then inspect the conditions:
aws iam list-roles --query "Roles[].RoleName" --output text | tr '\t' '\n' | while read r; do
aws iam get-role --role-name "$r" --query Role.AssumeRolePolicyDocument --output json \
| jq -r --arg r "$r" '.Statement[] | select(.Action=="sts:AssumeRoleWithWebIdentity")
| "\($r)\t\(.Principal.Federated)\t\(.Condition // "NO CONDITION")"'
done
A trust policy for IRSA should pin both the audience and the exact service account. A pattern of this shape (placeholders) is the target:
{
"Effect": "Allow",
"Principal": {"Federated": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.REGION.amazonaws.com/id/OIDC_ID"},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.REGION.amazonaws.com/id/OIDC_ID:aud": "sts.amazonaws.com",
"oidc.eks.REGION.amazonaws.com/id/OIDC_ID:sub": "system:serviceaccount:NAMESPACE:SERVICE_ACCOUNT"
}
}
}
Flag any role with no sub condition, or with StringLike and a wildcard such as system:serviceaccount:*:*. Our assessment: such a role is assumable by any service account in the cluster.
Audit 3: review Pod Identity associations
aws eks list-pod-identity-associations --cluster-name CLUSTER_NAME
aws eks describe-pod-identity-association --cluster-name CLUSTER_NAME \
--association-id ASSOCIATION_ID
Per the AWS page, you can create an association for a namespace or service account name that does not yet exist in the cluster. It only works once someone creates them. Our assessment: treat unexpected associations pointing at privileged roles as a finding, because an attacker with namespace-create rights could later activate them.
Hardening steps
- Restrict IMDS (Audit 1) on every node group.
- Give each workload its own service account and role. Do not attach broad policies such as
AdministratorAccessors3:*on*. - Add
audandsubconditions to every IRSA trust policy. For Pod Identity, add session-tag conditions as described in the Service Authorization Reference linked from the AWS page. - Restrict who holds
eks:CreatePodIdentityAssociationandiam:PassRole. The AWS page states the creator needsiam:PassRole. - Alert on
AssumeRoleWithWebIdentityand EKS Auth calls from unexpected roles. AWS states CloudTrail records access events for both mechanisms. - Remove unused OIDC providers and associations from decommissioned clusters.
What we could not verify
- Exploitation in the wild: no evidence found as of 3 November 2026 in the three AWS pages we opened, which do not discuss attacks at all. This is not proof of absence.
- Exact Pod Identity session tag condition key names: not shown in the pages we opened. Take them from the AWS Service Authorization Reference.
- All commands: untested in our lab.