All 31 documented AWS IAM privilege-escalation paths
A path-by-path reference. Each entry names the exact IAM actions the escalation needs — cited to AWS's own documentation — the mechanism in one line, and how audytx catches it by reasoning about the whole resource graph rather than matching a single statement. The catalog follows the BishopFox iam-vulnerable corpus and the Rhino Security Labs escalation-methods research that named most of them.
What "privilege escalation" means in IAM
Every path here has the same shape: a principal is granted a permission that does not look like admin, but can be used to obtain admin.
A policy that lets a principal run iam:CreatePolicyVersion isn't labeled
"administrator" — but the principal can write a new default version of a policy it's already
attached to and grant itself *. A policy with iam:PassRole plus
lambda:CreateFunction lets the principal hand an admin role to a function it
writes and invoke it. The danger is never in one action's name; it's in what the action
reaches. That is exactly why single-resource pattern-matchers struggle here — they
can flag iam:PassRole everywhere (and drown you in noise) or stay quiet (and
miss the chain). Reasoning about the path is the only way to get both recall and precision.
- PassRole → Lambda
- PassRole → EC2
- PassRole → CloudFormation
- PassRole → Glue
- PassRole → SSM (run command)
- PassRole → Data Pipeline
- PassRole → SageMaker
- Service role → CodeBuild
- Service role → CodePipeline
- Service role → ECS task definition
- Service role → Fargate task
- Service role → Step Functions
- Service role → EventBridge
- AttachUserPolicy
- AttachGroupPolicy
- AttachRolePolicy
- PutUserPolicy
- PutGroupPolicy
- PutRolePolicy
- AddUserToGroup
- CreatePolicyVersion
- SetDefaultPolicyVersion
- CreateAccessKey
- CreateLoginProfile
- UpdateLoginProfile
- UpdateAssumeRolePolicy
- AdministratorAccess attach
- iam:* wildcard
- EC2 IMDSv1 SSRF
- Secrets Manager exfiltration
- sts:AssumeRole wildcard
The classic chain: iam:PassRole lets a principal hand an existing privileged role to a service it can launch, and the service runs code as that role. Passing a role is not itself admin — it becomes escalation when paired with a service-launch action, which is why audytx scores the pair, not the PassRole alone.
01PassRole → Lambda
Create a function with a privileged execution role, then invoke it — the function's code runs with the role's permissions.
02PassRole → EC2
Launch an EC2 instance with a privileged instance profile, then reach its credentials through the instance metadata service.
03PassRole → CloudFormation
Create or update a stack that CloudFormation deploys using a passed admin role, so the stack acts with those permissions.
04PassRole → Glue
Create a Glue job whose execution role is admin, then start it — the job's script runs as the role.
05PassRole → SSM (run command)
Run a command on an EC2 instance that already carries a privileged instance profile, executing as that role without launching anything new.
06PassRole → Data Pipeline
Create a pipeline whose activation runs tasks under a passed admin role.
07PassRole → SageMaker
Create a SageMaker training job (or notebook) with an admin execution role and read the role's credentials from inside it.
The same passing-a-role idea, through CI/CD and orchestration services whose task or build role is often over-privileged. Each runs attacker-supplied definition or build steps as the service role.
08Service role → CodeBuild
Create a build project with an admin service role and a buildspec that exfiltrates the role's credentials.
09Service role → CodePipeline
Create a pipeline whose stage runs with an admin role, driving escalation through the delivery flow.
10Service role → ECS task definition
Register a task definition that references an admin task role, then run it — the container acts as the role.
11Service role → Fargate task
Run a Fargate task with a privileged task role — no ALB or instance needed; the container gets the role directly.
12Service role → Step Functions
Create a state machine that runs with an admin role, executing steps under those permissions.
13Service role → EventBridge
Create a rule that targets a privileged compute resource, using a passed role to drive it on a schedule or event.
The most direct family: if a principal can attach a managed admin policy or write an inline one onto a user, group, or role it controls, it grants itself admin in a single call. All seven are named escalation methods in the Rhino catalog.
14AttachUserPolicy
Attach AdministratorAccess (or any admin managed policy) directly to a user the principal controls.
15AttachGroupPolicy
Attach an admin policy to a group the principal belongs to, inheriting admin.
16AttachRolePolicy
Attach an admin policy to a role the principal can assume.
17PutUserPolicy
Write an inline admin policy straight onto a user — no managed policy needed.
18PutGroupPolicy
Write an inline admin policy onto a group the principal is in.
19PutRolePolicy
Write an inline admin policy onto a role the principal can assume.
20AddUserToGroup
Add the principal's own user to an existing administrator group.
Escalation that never touches an admin policy by name: rewrite a policy the principal already holds, or mint fresh credentials for another principal that has more access.
21CreatePolicyVersion
Create a new version of a customer-managed policy the principal is already attached to, setting it as default with * permissions.
22SetDefaultPolicyVersion
Roll a policy's default pointer back to an older, more permissive version that already exists.
23CreateAccessKey
Mint a fresh access key for another user that has more privilege, then use it.
24CreateLoginProfile
Create a console password for a user that has no login profile yet, then sign in as them.
25UpdateLoginProfile
Reset an existing user's console password to one the attacker knows.
Rewrite who may assume a role, or hold a grant so broad it contains admin outright.
26UpdateAssumeRolePolicy
Rewrite a privileged role's trust policy to name the attacker's principal, then assume it. audytx models this against the full trust graph, not the role in isolation.
27AdministratorAccess attach
The blunt case: attaching the AWS-managed AdministratorAccess policy (or an equivalent *:* grant) directly to a principal.
28iam:* wildcard
A standalone iam:* grant contains every escalation method above at once — any IAM write becomes reachable.
Escalation reached through a resource rather than a bare IAM action — the case single-resource IAM scanners are structurally worst at, because the vulnerable link spans two resources.
29EC2 IMDSv1 SSRF
An internet-reachable instance carrying a privileged profile with IMDSv1 still enabled lets a server-side request forgery read the role's credentials from the metadata endpoint.
30Secrets Manager exfiltration
An unconstrained secretsmanager:GetSecretValue grant (resource *, no condition) lets a principal read every secret — including credentials for more privileged principals.
31sts:AssumeRole wildcard
A grant of sts:AssumeRole on resource * lets the principal assume any role whose trust policy allows it — the general case behind role chaining.
Why detecting these needs cross-resource reasoning
Most of these paths are invisible to a scanner that judges one resource at a time. The
iam:PassRole in path 01 is benign until you see the lambda:CreateFunction
beside it and the admin role it points at; the IMDSv1 setting in path 29 is only dangerous
because another resource exposes the instance and a third grants it a privileged profile.
audytx pre-computes the relationship graph — who can pass which role to what, which
principals can assume which roles, what's reachable from the internet — and scores each path
against it. That's how it reaches full recall on all 31 while keeping the lowest
false-positive count of any tool with full recall in the benchmark: the naive
PassRole flags that make other scanners noisy are the ones context proves
benign, and audytx suppresses them with the reason shown.
The engine, the trust-graph and attack-path reasoning, and the per-path detection live in the IAM skill; the mechanism is documented on the false-positives page, and the measured recall/precision comparison against Checkov, Trivy, and KICS is on the IAM security page and the benchmark.
Frequently asked questions
How many IAM privilege-escalation paths are there in AWS?
The widely-cited catalog documents 31 paths, drawn from the Rhino Security Labs escalation-methods research and packaged as one Terraform scenario per path in the BishopFox iam-vulnerable corpus. New variants surface as AWS adds services, but these 31 are the standard benchmark set. audytx detects all 31.
What is the iam:PassRole privilege-escalation risk?
iam:PassRole lets a principal hand an existing IAM role to an AWS service. On its own that's a normal, necessary permission — it becomes escalation when the principal can also launch a service that runs code (Lambda, EC2, ECS, Glue, CodeBuild, and more) and pass it a role more privileged than the principal itself. Groups A and B above are all PassRole variants. The fix is to scope PassRole to specific role ARNs, never *.
Does audytx detect all of them in Terraform?
Yes — on the BishopFox iam-vulnerable benchmark audytx reaches full recall across all 31 paths, at the highest precision of any tool that also reaches full recall. The measured comparison (KICS 3%, Trivy 0% on the same corpus) and reproduction steps are on the IAM security page and the benchmark.
How do I prevent IAM privilege escalation?
Scope iam:PassRole to explicit role ARNs; deny the IAM write actions (Attach*/Put*/Create*Policy*/AddUserToGroup) except on break-glass admin principals; enforce IMDSv2 on every instance profile; add conditions to sts:AssumeRole and secret-read grants instead of resource *; and scan Terraform in review so a new path is caught before it merges. audytx flags each of these paths on the pull request that introduces it.
Catch these on the pull request
Install the GitHub App and audytx reviews your next Terraform change for every path above — with the chain shown, and the benign PassRole grants suppressed. Free during the beta.