PassRole & escalation paths
The permission combinations that become admin.
Most real AWS privilege escalation is not a single over-broad policy — it is a set of individually-reasonable permissions that compose into "become admin". The reviewer’s job is to spot those combinations. iam:PassRole is the one at the center of most of them.
Why PassRole is an escalation primitive
PassRole does nothing on its own, which is why it slips through reviews. But paired with a service that runs code under a role — lambda:CreateFunction, ec2:RunInstances, ecs:RunTask, glue, codebuild — it lets a principal hand a more powerful role to something they control and inherit its permissions. If a low-privilege identity can pass an admin role to a Lambda it creates and invoke it, that identity is now admin.
# DANGEROUS: pass ANY role to ANY service.{ "Effect": "Allow", "Action": "iam:PassRole", "Resource": "*" }# SAFE: pass only a specific, low-privilege role, only to the intended service.{"Effect": "Allow","Action": "iam:PassRole","Resource": "arn:aws:iam::222222222222:role/app-task-role","Condition": { "StringEquals": { "iam:PassedToService": "ecs-tasks.amazonaws.com" } }}
The other escalation paths to hunt
Beyond PassRole, watch for identity-policy self-edits: iam:CreatePolicyVersion or SetDefaultPolicyVersion (rewrite a policy attached to you), iam:AttachUserPolicy / PutUserPolicy (grant yourself more), iam:UpdateAssumeRolePolicy (add yourself to a role’s trust), and iam:CreateAccessKey on another user. Run the policy simulator and Access Analyzer’s unused-access findings to surface these reachable paths before an attacker does — and constrain any of these actions with tight resource scoping and conditions.