aws-eks-pod-identity-association
An EKS Pod Identity Association (eks:CreatePodIdentityAssociation) links a Kubernetes namespace:ServiceAccount pair to an IAM role. Pods running as that SA receive IAM credentials from the eks-pod-identity-agent at 169.254.170.23. Whoever can create or modify this association can reroute which IAM role any pod in that namespace:SA binding runs as.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
WorkloadIdentity, ServiceAccount]
?ksa is linked via an EKS Pod Identity Association (eks:DescribePodIdentityAssociation)
node_type(?iam_role) in [Role, MachineIdentity]
?iam_role trust policy trusts pods.eks.amazonaws.com with sts:AssumeRoleWithWebIdentity
exists TrustsExternalIdentity(?iam_role -> ?ksa) backed by the Pod Identity trust
emit
| source type | WorkloadIdentity |
|---|---|
| target type | Role |
| source | ?ksa |
| target | ?iam_role |
| permissions | sts:AssumeRoleWithWebIdentity |
| conditions | trust_condition service_state |
| state logic | ACTIVE when the Pod Identity association is in effect (eks-pod-identity-agent DaemonSet running on the node) and the IAM role trust includes pods.eks.amazonaws.com. The trust condition pin is namespace:SA-scoped — ACTIVE for any pod in the specified namespace running as the specified SA. CONDITIONAL(service_state) if the Pod Identity agent DaemonSet is not installed/running on the target nodes. BLOCKED if the association is deleted or the role trust does not permit pods.eks.amazonaws.com. Cites container-chains workload-identity-federates and federation-chains federation-maps-to-identity for the CanEnter*/CanImpersonate roll-ups. |
Narrative
Kubernetes ServiceAccount {ksa.name} (namespace {ksa.namespace}) is linked via a Pod Identity Association to IAM role {iam_role.name}. The eks-pod-identity-agent delivers credentials at 169.254.170.23 to any pod running as {ksa.name}; executing code in such a pod grants credentials for {iam_role.name} (federation-chains rolls up account foothold and impersonation).
Raw rule rules/derived/aws/eks.yaml
id: aws-eks-pod-identity-association
emits: CanFederateAs
description: An EKS Pod Identity Association (eks:CreatePodIdentityAssociation) links a Kubernetes namespace:ServiceAccount
pair to an IAM role. Pods running as that SA receive IAM credentials from the eks-pod-identity-agent
at 169.254.170.23. Whoever can create or modify this association can reroute which IAM role any pod
in that namespace:SA binding runs as.
match:
- - ksa: null
- ExternalIdentityMapsTo
- iam_role: null
where:
- node_type(?ksa) in [WorkloadIdentity, ServiceAccount]
- ?ksa is linked via an EKS Pod Identity Association (eks:DescribePodIdentityAssociation)
- node_type(?iam_role) in [Role, MachineIdentity]
- ?iam_role trust policy trusts pods.eks.amazonaws.com with sts:AssumeRoleWithWebIdentity
- exists TrustsExternalIdentity(?iam_role -> ?ksa) backed by the Pod Identity trust
emit:
source_type: WorkloadIdentity
target_type: Role
source: ?ksa
target: ?iam_role
permissions:
- sts:AssumeRoleWithWebIdentity
conditions:
- trust_condition
- service_state
state_logic: "ACTIVE when the Pod Identity association is in effect (eks-pod-identity-agent DaemonSet\
\ running on the node) and the IAM role trust includes pods.eks.amazonaws.com. The trust condition\
\ pin is namespace:SA-scoped \u2014 ACTIVE for any pod in the specified namespace running as the specified\
\ SA. CONDITIONAL(service_state) if the Pod Identity agent DaemonSet is not installed/running on the\
\ target nodes. BLOCKED if the association is deleted or the role trust does not permit pods.eks.amazonaws.com.\
\ Cites container-chains workload-identity-federates and federation-chains federation-maps-to-identity\
\ for the CanEnter*/CanImpersonate roll-ups."
confidence: min(contributing_confidences)
derived_from:
- ?ksa ExternalIdentityMapsTo ?iam_role (Pod Identity Association)
- ?iam_role TrustsExternalIdentity ?ksa (pods.eks.amazonaws.com trust)
- 'container-chains: workload-identity-federates'
- 'federation-chains: federation-maps-to-identity'
false_positive_note: "Dedupes with container-chains workload-identity-federates on (CanFederateAs, ?ksa,\
\ ?iam_role) \u2014 emit once. The CanEnterAccount / CanImpersonate roll-ups are federation-chains'\
\ \u2014 never re-derive here. Pod Identity requires the eks-pod-identity-agent DaemonSet on each\
\ node (addon: eks-pod-identity-agent); without it the association has no effect -> CONDITIONAL(service_state).\
\ The agent endpoint is 169.254.170.23 (not 169.254.169.254 IMDS); Fargate pods with Pod Identity\
\ are supported and have no IMDS exposure. An attacker who gains eks:CreatePodIdentityAssociation\
\ can reroute the SA->role mapping to a different role they control \u2014 model this separately via\
\ aws-eks-create-pod-identity-association-redirect."
narrative: Kubernetes ServiceAccount {ksa.name} (namespace {ksa.namespace}) is linked via a Pod Identity
Association to IAM role {iam_role.name}. The eks-pod-identity-agent delivers credentials at 169.254.170.23
to any pod running as {ksa.name}; executing code in such a pod grants credentials for {iam_role.name}
(federation-chains rolls up account foothold and impersonation).