Infrastructure & systems
Heuristic12 minOver-privileged IAM Role
A cloud identity — a role, user or service account — is granted far more permission than its job requires, often through wildcard actions or resources, so a single compromise of that identity becomes broad account access and any mistake it makes has an outsized blast radius.
Classification
- Domain
- Infrastructure & systems
- ROOTVIEL support
- Heuristic — Pattern/presence detection, without a provenance or proof oracle.
- Analysis family
- infra
- CWE
- CWE-269, CWE-732
- OWASP
- A05:2021
Definition
An over-privileged IAM role is a cloud identity whose attached permissions exceed what its workload actually needs to function. The textbook form is a policy that grants a wildcard action on a wildcard resource — effectively "do anything to anything" — but it also includes narrower-looking grants that still bundle dangerous abilities: passing any role, modifying identity policies, reading all secrets, or administering the whole account. The identity works fine; the problem is everything else it is also allowed to do.
This is a violation of least privilege: improper, overly broad permission assignment. It is dangerous not on its own but as a multiplier — every other weakness (a compromised instance, a leaked key, a confused-deputy call, a container escape) inherits the full authority of whatever identity it reaches. A tightly scoped role turns many incidents into contained ones; an over-privileged role turns one incident into account takeover.
Context
Over-privilege accumulates wherever permissions are granted under time pressure and never pruned: a role built by copying a managed admin policy to "unblock" a deploy, a service account reused across unrelated functions, or a wildcard added during debugging and left in place. Cloud environments make broad grants easy to write and hard to notice, and permissions tend to ratchet up — rarely down — over a system’s life.
- ▸Workload roles granted a managed administrator policy because scoping the exact permissions was tedious.
- ▸Policies using Action: "*" or Resource: "*" instead of the specific calls and ARNs a task needs.
- ▸Roles that can pass any role (iam:PassRole on *) or edit identity policies, enabling self-escalation.
- ▸Shared service accounts reused across many functions, so each inherits the union of all their permissions.
Technical fundamentals
Cloud authorization is the set of permissions attached to an identity, evaluated per request. The security property that matters is least privilege: the granted set should be the smallest that lets the workload do its job. The gap between granted and needed permissions is pure risk — it buys no functionality and only enlarges what a compromise or a mistake can touch.
Some permissions are escalation primitives: the ability to pass roles, attach or edit policies, create access keys for other identities, or assume other roles lets a modestly privileged identity become a highly privileged one. So "over-privileged" is not only about raw breadth; a small policy containing one escalation primitive can be as dangerous as a wildcard. Policy text is static and declarable, which makes broad patterns (wildcards, known escalation actions) detectable by reading it — but whether a given grant is actually excess depends on what the workload truly uses, which requires either knowledge of the workload or observed usage data.
- Least privilege
- The principle that an identity should hold only the permissions its function requires, and no more.
- Wildcard grant
- A policy statement using Action: "*" and/or Resource: "*", granting a broad, unscoped set of abilities.
- Privilege-escalation primitive
- A permission that lets an identity grant itself more — e.g. iam:PassRole, attaching policies, creating keys, or assuming other roles.
- Used-vs-granted gap
- The difference between permissions an identity has and the ones it actually exercises; a large gap is the signal of over-privilege.
Root cause
The root cause is broad permission assignment — granting authority the workload does not need, usually because scoping to the exact set is more work than reaching for a wildcard or a managed admin policy, and because an over-broad grant produces no error that would prompt tightening it. The permission set is wrong at rest, independent of whether it is ever abused.
A structural contributor is the asymmetry of feedback: too few permissions breaks the workload loudly and gets fixed immediately; too many permissions breaks nothing and is invisible until a compromise exploits them. Without a periodic right-sizing process driven by observed usage, roles drift broad and stay broad.
How the exposure works, step by step
- 1A workload is assigned a role far broader than it needs — a wildcard policy or a managed admin policy.
- 2An attacker compromises something that can use that identity: the instance it runs on, a leaked key, an SSRF reaching the metadata endpoint, or the application itself.
- 3They assume or use the role and enumerate its permissions, discovering the broad grant.
- 4They exercise permissions the workload never used — reading all secrets, creating new admin identities, or passing a privileged role to a resource they control.
- 5Using an escalation primitive, they consolidate into durable, account-wide administrative control far beyond the original foothold.
Had the role been scoped to the handful of calls the workload actually makes, step 4 would have failed closed, containing the incident to the original foothold.
Vulnerable configuration
A synthetic, illustrative policy attached to a workload that only needs to read objects from one bucket, but is granted everything.
synthetic IAM policy (JSON) — do not deploy; illustrates the flaw{ "Version": "2012-10-17", "Statement": [ { "Sid": "DoAnything", "Effect": "Allow", "Action": "*", // every action in the account "Resource": "*" // on every resource }, { "Sid": "PassAnyRole", "Effect": "Allow", "Action": "iam:PassRole", // escalation primitive, unscoped "Resource": "*" } ] } /* The workload only ever calls s3:GetObject on one bucket. Everything else here is pure, unused blast radius. */
Hardened configuration
The hardened policy grants exactly the action the workload uses, on exactly the resource it uses, and nothing else. No wildcards, no PassRole, no escalation primitives.
synthetic IAM policy (JSON) — least privilege{ "Version": "2012-10-17", "Statement": [ { "Sid": "ReadReportsBucketOnly", "Effect": "Allow", "Action": ["s3:GetObject"], // only what it uses "Resource": "arn:aws:s3:::acme-reports/*" // only the one bucket } ] } /* No wildcards, no PassRole, no identity-management actions. A compromise of this identity can read one bucket's objects — nothing more. */
Limit of the fix: scoping a role shrinks its blast radius but does not patch the path that reaches it — a leaked key or SSRF to the metadata endpoint is still a problem, just a smaller one now. Right-sizing should be driven by observed usage (access-analyzer / last-accessed data), because guessing the needed set risks either breakage or quietly leaving a wildcard in.
Impact
- ▸Account takeover: a compromised over-privileged identity, especially with an escalation primitive, leads to full administrative control.
- ▸Mass data exposure: broad read permissions let an attacker harvest every bucket, secret and database the account holds.
- ▸Blast-radius amplification: every other weakness that reaches this identity inherits its full authority.
- ▸Persistence: permissions to create identities or keys let an attacker establish durable, hard-to-evict access.
Detection
Static policy analysis flags the obvious patterns — Action: "*", Resource: "*", unscoped iam:PassRole, and known escalation actions — as a presence signal directly from the policy text. The stronger signal is the used-versus-granted gap: cloud providers expose last-accessed and access-analyzer data showing which granted permissions an identity never actually exercises, which turns "this looks broad" into "these specific permissions are unused and removable". A wildcard is a reliable red flag, but deciding a particular narrow grant is excess generally requires usage data or knowledge of the workload, not pattern matching alone.
Where ROOTVIEL fits
This entry is reference material. ROOTVIEL’s verified, execute-and-prove engine is built for AI/agentic and Web3 findings, where it runs a candidate attack in a sandbox and a deterministic verifier settles whether it is real. IAM right-sizing is outside that proven surface; ROOTVIEL does not operate a verified engine for infrastructure vulnerabilities.
Support: heuristic. Matching wildcard actions, wildcard resources and known escalation primitives in policy text is honest presence/pattern detection. But a wildcard is a signal, not proof: whether a role is truly over-privileged depends on what the workload uses, and whether an attacker can reach and abuse it depends on the rest of the environment. Beyond "this policy contains a broad or escalation-prone grant", the finding is educational unless demonstrated with usage data or in an authorized environment.
Mitigation
Grant the smallest permission set that works, and drive right-sizing with observed usage rather than guesswork.
- ▸Preventive: write policies that name specific actions and specific resource ARNs; avoid Action: "*" and Resource: "*" for workload roles.
- ▸Preventive: treat escalation primitives (iam:PassRole, policy attachment, key creation, role assumption) as high-risk; scope them tightly or remove them.
- ▸Preventive: give each workload its own role; do not reuse one broad service account across unrelated functions.
- ▸Detective: use last-accessed and access-analyzer data to find and remove permissions the identity never exercises; review periodically.
- ▸Corrective: when a compromise is suspected, rotate the identity’s credentials, revoke sessions, and prune the role to least privilege before reuse.
Verifying the mitigation
Verify by checking both that the workload still functions on the reduced policy and that the removed permissions are genuinely gone. Confirm no wildcard or escalation primitive remains, re-run access-analyzer to confirm the used-versus-granted gap is small, and in an authorized test confirm the identity can no longer perform a previously allowed broad action. State the result as "the role is scoped to its observed usage and no escalation primitive remains".
A clean result means the policy matches current observed usage, not that it is minimal forever — a new feature may need more, and someone may re-add a wildcard later. Re-verify on policy changes and keep the usage review recurring.
Common mistakes
- ▸Attaching a managed administrator policy to "unblock" a deploy and never scoping it down.
- ▸Leaving Action: "*" or iam:PassRole on * in place because nothing broke.
- ▸Reusing one broad service account across many workloads so each inherits all permissions.
- ▸Right-sizing by guesswork instead of observed last-accessed/access-analyzer data.
- ▸Focusing only on wildcards while ignoring a narrow policy that still contains an escalation primitive.
References
- [1]OWASP Top 10 — A05:2021 Security Misconfiguration
- [2]MITRE CWE-269 (Improper Privilege Management)
- [3]MITRE CWE-732 (Incorrect Permission Assignment for Critical Resource)
- [4]NIST SP 800-53 Rev. 5 — AC-6 Least Privilege
- [5]CIS Benchmarks (cloud identity foundations) — overview
References point to public, well-known technical sources for further study.
Related articles
Often ships the broad role as part of the same template.
Privileged ContainerThe container analogue of unnecessary authority.
Confused DeputyAbuses a privileged identity’s authority on the attacker’s behalf.
Broken Access Control & AuthorityThe same over-permission theme at the application layer.
