aws-eks-pod-exec-execute-as
Exec into a running pod (via cluster-admin or direct pods/exec RBAC) inherits the pod's mounted IRSA or Pod Identity token, executing as the pod's IAM role. Cites container-chains cluster-rbac-exec; dedupes on (CanExecuteAs, principal, role).
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?pod) ==
KubernetesWorkload
node_type(?iam_role) in [MachineIdentity, Role]
?pod has a mounted IRSA or Pod Identity token (automountServiceAccountToken:true or IRSA projected volume, or Pod Identity agent endpoint reachable)
emit
| source type | Identity |
|---|---|
| target type | Identity |
| source | ?principal |
| target | ?iam_role |
| permissions | eks:DescribeCluster |
| conditions | service_state |
| state logic | ACTIVE when the pod's IRSA or Pod Identity credential is mounted/reachable (projected token volume present, or Pod Identity agent on node reachable at 169.254.170.23). CONDITIONAL(service_state) if automountServiceAccountToken=false AND no IRSA projected volume AND no Pod Identity association — then exec yields OS access but not the IAM credential. Inherit weakest from CanExecuteCommand. This dedupes with container-chains cluster-rbac-exec on (CanExecuteAs, ?principal, ?iam_role): cite, do not double-count weight. |
Narrative
{principal.name} can exec into pod {pod.name} (CanExecuteCommand via k8s pods/exec). The pod runs as {iam_role.name} (IRSA or Pod Identity); the projected token or agent endpoint credential is readable from inside the container, so {principal.name} executes as {iam_role.name}.
Raw rule rules/derived/aws/eks.yaml
id: aws-eks-pod-exec-execute-as
emits: CanExecuteAs
description: Exec into a running pod (via cluster-admin or direct pods/exec RBAC) inherits the pod's mounted
IRSA or Pod Identity token, executing as the pod's IAM role. Cites container-chains cluster-rbac-exec;
dedupes on (CanExecuteAs, principal, role).
match:
- - principal: null
- CanExecuteCommand
- pod: null
- - pod: null
- ExecutesAs
- iam_role: null
where:
- node_type(?pod) == KubernetesWorkload
- node_type(?iam_role) in [MachineIdentity, Role]
- ?pod has a mounted IRSA or Pod Identity token (automountServiceAccountToken:true or IRSA projected volume,
or Pod Identity agent endpoint reachable)
emit:
source_type: Identity
target_type: Identity
source: ?principal
target: ?iam_role
permissions:
- eks:DescribeCluster
conditions:
- service_state
state_logic: "ACTIVE when the pod's IRSA or Pod Identity credential is mounted/reachable (projected\
\ token volume present, or Pod Identity agent on node reachable at 169.254.170.23). CONDITIONAL(service_state)\
\ if automountServiceAccountToken=false AND no IRSA projected volume AND no Pod Identity association\
\ \u2014 then exec yields OS access but not the IAM credential. Inherit weakest from CanExecuteCommand.\
\ This dedupes with container-chains cluster-rbac-exec on (CanExecuteAs, ?principal, ?iam_role): cite,\
\ do not double-count weight."
confidence: min(contributing_confidences)
derived_from:
- <CanExecuteCommand edge_id>
- <ExecutesAs edge_id>
- 'container-chains: cluster-rbac-exec'
- 'can-execute-as: execute-as-via-command'
false_positive_note: "Dedupes with container-chains cluster-rbac-exec on (CanExecuteAs, ?principal,\
\ ?iam_role) \u2014 emit once, do not double-count weight. The service_state gate (whether the pod's\
\ token is mounted and accessible) matters: a pod with automountServiceAccountToken:false and no IRSA\
\ projected volume and no Pod Identity agent reachability gives OS access but not the IAM credential\
\ -> CONDITIONAL(service_state). On Fargate pods, only IRSA/Pod Identity apply (no node IMDS). Scope\
\ exec to the pod's actual namespace/name \u2014 cluster-admin reaches all, but a namespace-scoped\
\ pods/exec grant only reaches pods in that namespace. The escalation consequence is produced by can-control\
\ escalate-via-execute-as off this CanExecuteAs \u2014 cite, do not duplicate."
narrative: '{principal.name} can exec into pod {pod.name} (CanExecuteCommand via k8s pods/exec). The
pod runs as {iam_role.name} (IRSA or Pod Identity); the projected token or agent endpoint credential
is readable from inside the container, so {principal.name} executes as {iam_role.name}.'