Articles / Over-Permissioned Roles and Privilege Escalation Paths
Cloud · Privilege Escalation

Over-Permissioned Roles and Privilege Escalation Paths

A cloud attacker who lands on a low-privilege role does not go looking for an admin password. They go looking for a path — a chain of individually mundane permissions that adds up to "become admin." Privilege escalation in the cloud is not a single flaw; it is a graph problem, and over-permissioned roles are the edges that connect a foothold to the crown jewels.

Cloud IAM is expressive by design. You can grant an identity the ability to create roles, attach policies, launch compute, update functions, or pass a role to a service. Each of those is legitimate and necessary somewhere. The trouble is that several of them are also escalation primitives: give an identity the right one, and it can grant itself more than it started with — no exploit required, just the permissions you already assigned.

The primitives attackers hunt for

Low-privilege rolethe footholdEscalation primitiveiam:PassRole + launchDeploy Lambda / EC2running as that roleAdmin roleassumedAny API, any resourceOne permission toomany opens the wholepath
Escalation is a graph: one mundane permission chains a foothold to admin.

Automated tools and red teams map these paths as a matter of routine. A few of the most common in AWS, with direct analogues in Azure and GCP:

  • iam:PassRole + a compute service. If an identity can pass a privileged role and launch an EC2 instance, Lambda, or ECS task, it can run code as that role and inherit its power.
  • Policy manipulation. iam:PutUserPolicy, iam:AttachRolePolicy, or the ability to create a new policy version lets an identity write itself an admin grant directly.
  • Function and instance takeover. Permission to update an existing Lambda's code, or to run commands via SSM on a running instance, hands the attacker whatever role that resource already holds.
  • Trust-policy edits. Rewriting a role's trust relationship to trust the attacker's principal turns a role they can see into a role they can assume.
  • Credential creation. Making new access keys for another user, or resetting a login profile, is escalation dressed up as routine administration.
Escalation via PassRole — the attacker never touched an admin accountiam:PassRole(admin-role) + lambda:CreateFunction + lambda:InvokeFunction → deploy a function that runs as admin-role → call any API as admin
Why it matters: The dangerous grant is rarely labelled "admin." It is a narrow-looking permission whose combination with others opens a path — which is exactly why manual policy review keeps missing it.

Why humans miss these paths

A reviewer reads one policy at a time and asks "is this reasonable?" — and each grant, in isolation, usually is. Escalation lives in the graph: the join between this role's iam:PassRole and that role's permissions, across trust relationships and group memberships you were not looking at together. The number of possible paths grows with every identity and policy, which is why escalation analysis is a job for tooling, not eyeballs.

Cutting the paths

  • Map paths, don't just review policies. Tools like open-source IAM path analyzers and provider access analyzers enumerate who-can-reach-what and surface the dangerous joins.
  • Constrain the escalation primitives. Scope iam:PassRole to specific roles, restrict policy-writing actions to a break-glass identity, and separate who can deploy code from whose role that code runs as.
  • Cap with permission boundaries and SCPs. Even if a policy is over-broad, a boundary can prevent an identity from ever reaching admin.
  • Alert on the escalation itself. New trust-policy edits, policy attachments, and access-key creation are high-signal CloudTrail events worth paging on.
  • Re-test after every change. A path closed today reopens the moment someone attaches a convenient managed policy tomorrow.

Over-permissioned roles are the connective tissue of cloud breaches: the initial access is almost never the interesting part, the escalation path is. Finding those paths before an attacker does means seeing your permissions as a graph, continuously — and that starts with knowing every identity you have. You can't defend what you haven't discovered.

Test for it — in practice
  • Pick a low-privilege role and skim it for the escalation primitives — iam:PassRole paired with a compute launch, policy-writing actions, or trust-policy edits — that let it grant itself more than it started with.
  • Ask whether anything caps that role with a permission boundary or SCP, or whether its attached policy is the only limit.

One role you can reason about by hand; enumerating the full escalation graph across every identity is what our assessment runs for you.

Keep reading
Secrets Management in the Cloud: KMS, Secret Stores, and Rotation