Most cloud breaches don't start with a zero-day. They start with an identity that can do far more than it should. Here are five IAM misconfigurations I look for first, with AWS examples (the same ideas apply to Azure and Google Cloud), how to find them and how to fix them.
1. Wildcard actions on wildcard resources
{ "Effect": "Allow", "Action": "s3:*", "Resource": "*" } This grants every S3 action on every bucket: read, write, delete, and change bucket policies.
Find it: search policies for "Action": "*", "service:*" and "Resource": "*". IAM Access Analyzer can generate a policy from actual CloudTrail activity so you can see what a role really uses.
Fix it: list specific actions on specific ARNs:
{ "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "arn:aws:s3:::reports/*" } 2. iam:PassRole on everything
{ "Effect": "Allow", "Action": "iam:PassRole", "Resource": "*" } PassRole lets an identity attach a role to a compute resource it launches. If it can pass any role, it can launch something with an admin role and inherit those powers. This is one of the most common privilege-escalation paths.
Fix it: restrict Resource to the exact role ARNs needed, and add a condition such as iam:PassedToService.
3. Long-lived access keys
Static keys leak through repositories, CI logs and laptops.
Find it:
aws iam generate-credential-report aws iam get-credential-report --query Content --output text | base64 -d | cut -d, -f1,9,10,11 Fix it: prefer roles and short-lived credentials: SSO for humans, instance and workload roles for services, and OpenID Connect federation for CI pipelines. Rotate or delete what remains.
4. Unused and orphaned identities
Former employees, test users and roles nobody remembers creating are free footholds.
Find it: the credential report's "last used" fields and IAM's last-accessed data per service.
Fix it: disable, then delete after a review period. Automate deprovisioning from your HR or identity provider.
5. Over-trusting role trust policies
{ "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "sts:AssumeRole" } A role that anyone can assume (or any account in a broad organisation) is effectively public.
Fix it: name exact principals, and require an ExternalId for third-party access.
Make it a routine
- Run IAM Access Analyzer continuously and review external-access findings.
- Review privileged roles quarterly.
- Alert on
CreateAccessKey,AttachRolePolicyandPutRolePolicyin CloudTrail.
I teach these patterns for free in the identity lessons at CoreQ Academy, and you can practise them in the IAM Defender game.
I'm Sean Ofodile, a cybersecurity leader, founder of Quantum Core Services and CIO of Seenu.io, an early-stage social discovery startup. I teach free cybersecurity classes at CoreQ Academy and on YouTube as Professor Sean Ofodile, and was featured on 11Alive in Atlanta with the Seenu team.
