Home / Blog / How to Find and Fix Over-Permissive IAM Roles in AWS (2026 Guide)

How to Find and Fix Over-Permissive IAM Roles in AWS (2026 Guide)

Published July 6, 2026 · Sovereign Observer Team
Quick answerTo find over-permissive IAM roles, look for policies that grant Action "*" or Resource "*" and for anything attached to the AWS-managed AdministratorAccess policy. Use IAM Access Analyzer’s unused-access findings and the service-last-accessed report to see which permissions a role has actually used. To fix them, replace wildcards with the specific actions and resource ARNs the workload needs — Access Analyzer can generate a least-privilege policy from CloudTrail history. A CSPM tool flags over-permissive roles continuously and shows which ones are reachable from the internet.

Why are over-permissive IAM roles so dangerous?

Because IAM is the real perimeter in the cloud. A misconfigured security group exposes one service; an over-permissive role exposes everything that role can touch. When an attacker phishes a credential, exploits an SSRF on an EC2 instance, or pops a leaked access key, the blast radius is defined entirely by what that identity is allowed to do.

The problem is that permissions only ever ratchet up. Someone grants s3:* to “unblock” a deploy, or attaches AdministratorAccess “just for now,” and it’s never walked back. Over months, most of a role’s permissions go unused — but every one of them is still available to an attacker who lands on it.

How do I find over-permissive roles in the console?

  1. Open IAM → Access Analyzer and enable an unused access analyzer (free). It flags unused roles, unused permissions, and unused access keys across the account — the fastest way to see where privilege has drifted.
  2. In IAM → Policies, filter to customer-managed policies and open each one’s JSON. Anything with "Action": "*" or "Resource": "*" is a wildcard to justify or remove.
  3. Check who holds admin: open the AWS-managed AdministratorAccess policy and review its Entities attached tab. Every human and role there can do anything in the account.

Caveat: this is one account, reviewed by hand, once. With multiple accounts — most organizations — you repeat it forever, and drift reappears the week after you finish. That’s the gap automation fills.

How do I check roles with the AWS CLI?

Two questions matter: which policies grant wildcards, and which permissions a role has actually used.

# who is attached to AdministratorAccess?
aws iam list-entities-for-policy \
  --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

# read a customer-managed policy document
aws iam get-policy-version \
  --policy-arn arn:aws:iam::ACCOUNT_ID:policy/POLICY_NAME \
  --version-id v1

# which services has this role actually used? (least-privilege evidence)
aws iam generate-service-last-accessed-details --arn ROLE_ARN
aws iam get-service-last-accessed-details --job-id JOB_ID

If the service-last-accessed report shows a role has touched three services in the last year but its policy grants twenty, you have your list to trim. Treat any policy statement with "Action": "*" and "Resource": "*" together as effectively admin, regardless of what the role was named for.

How do I fix an over-permissive role?

In order of preference:

  1. Scope actions and resources. Replace the wildcard with the specific actions and resource ARNs the workload needs:
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject"],
      "Resource": "arn:aws:s3:::app-uploads/*"
    }
    not "Action": "s3:*" on "Resource": "*".
  2. Generate a policy from real usage. IAM Access Analyzer can build a least-privilege policy from the role’s CloudTrail history, so you scope to what was actually called instead of guessing. Review it, then apply it as a new version.
  3. Add guardrails you can’t accidentally exceed. Attach a permissions boundary to roles so even a broad inline policy can’t grant more than the boundary allows, and prefer short-lived role sessions over long-lived access keys.

Roll changes out behind a test — over-tightening a production role breaks deploys. Trim, deploy to staging, watch for AccessDenied in CloudTrail, then promote.

How do I keep roles least-privilege over time?

Point-in-time cleanups decay as fast as you finish them. Three durable controls:

Sovereign Observer does the detective and pipeline layers out of the box, and goes one step further: it shows which over-permissive roles are actually reachable — chained from internet exposure through to your data in an attack path — so you fix the role that matters first, not the alphabetical one.

Frequently asked questions

What counts as an over-permissive IAM policy?

Any policy that grants more than the workload needs. The clearest red flags are Action "*" and Resource "*" (effectively admin), broad service wildcards like s3:* or ec2:*, and the AWS-managed AdministratorAccess policy attached to roles that only do one job.

How do I know which permissions a role actually uses?

Use the IAM service-last-accessed report (aws iam generate-service-last-accessed-details, then get-service-last-accessed-details) to see which services a role has called and when. IAM Access Analyzer can also generate a least-privilege policy from the role’s CloudTrail activity.

Will tightening an IAM role break my application?

It can if you over-trim. Scope changes based on real usage data, roll them out to staging first, and watch CloudTrail for AccessDenied errors before promoting to production. A permissions boundary lets you cap privilege without immediately rewriting every policy.

Is this a problem on Azure and GCP too?

Yes, with different names: over-privileged Azure role assignments and GCP IAM bindings with broad roles like Owner or Editor. The failure mode (privilege granted and never walked back) and the fix (scope to least privilege, monitor continuously) are identical.

See your cloud the way an attacker does

Connect AWS, Azure, or GCP with a read-only role and get prioritized findings in minutes — no sales call.