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.

derived aws emits CanFederateAs

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'ksa': None} ExternalIdentityMapsTo {'iam_role': None}

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 typeWorkloadIdentity
target typeRole
source?ksa
target?iam_role
permissionssts:AssumeRoleWithWebIdentity
conditionstrust_condition service_state
state logicACTIVE 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).
move · open · esc close