Your Cloud IAM Is Showing: Why Identity Misconfigurations Are the Skeleton Key Attackers Rely On
Here's a thing that happens constantly in cloud penetration tests: you get initial access through something boring — a leaked key in a public repo, a misconfigured S3 bucket, an exposed metadata endpoint — and then within an hour, you're looking at administrative access to the entire environment. Not because you found some exotic zero-day. Because somebody gave a Lambda function permissions it didn't need, or left a role that can call iam:PassRole attached to a resource that shouldn't have it.
Cloud IAM misconfigurations are the unglamorous, unsexy, consistently-exploitable path to full environment compromise. And despite years of guidance from AWS, Azure, GCP, and basically every security framework that exists, organizations keep making the same mistakes.
Let's get into the specifics.
Why IAM Is So Hard to Get Right
The problem isn't that cloud IAM is poorly designed. AWS IAM in particular is remarkably expressive — you can construct extremely granular permission sets that do exactly what you want. The problem is that expressiveness creates complexity, and complexity creates mistakes.
The other issue is velocity. Cloud environments are built fast. Developers need to ship. When a service account needs access to a resource at 11 p.m. before a launch, the path of least resistance is attaching a policy that's broader than it needs to be. That overpermissioned policy then lives in the environment for months or years, accumulating risk while nobody thinks about it.
And then there's the tooling gap. Most organizations have reasonable visibility into their network perimeter. They have firewalls, they have IDS, they have SIEM. But their IAM posture? It's sitting in a console that most of the security team doesn't log into regularly, with permissions that haven't been audited since the account was provisioned.
The AWS Misconfigurations That Keep Showing Up
A few patterns come up in almost every AWS engagement:
iam:PassRole and iam:CreateRole without resource constraints. These are the big ones. If an attacker can call iam:PassRole to a service like EC2 or Lambda, they can attach any role in the account — including one with admin permissions — to a resource they control, then assume that role. Combined with iam:CreateRole, they can manufacture their own escalation path from scratch. The fix is to restrict iam:PassRole to specific role ARNs using resource conditions. Most environments don't do this.
Wildcard permissions in inline policies. "Action": "*" and "Resource": "*" appear in production environments more often than they should. Sometimes it's a developer shortcut that never got cleaned up. Sometimes it's a Terraform module that shipped with permissive defaults. Either way, it's a complete bypass of the principle of least privilege.
Overpermissioned EC2 instance profiles. If an EC2 instance has an instance profile attached — and most do — an attacker with shell access to that instance inherits all of its IAM permissions. Instance profiles that include ec2:*, s3:*, or any IAM permissions are frequently the pivot point from "I have a shell on one box" to "I own the account."
Trust policy misconfigurations. Cross-account role assumption with overly broad trust policies is a classic. "Principal": "*" in a trust policy, or a trust policy that allows assumption from an entire AWS account rather than specific principals within it, opens the door to privilege escalation from anywhere that account is accessible.
Azure and GCP Have Their Own Flavors
Azure's RBAC model is conceptually similar to AWS IAM but has its own footguns. The most common one we see: subscription-level Owner or Contributor roles granted to service principals that only need access to a single resource group. Azure's role inheritance model means that permissions granted at the subscription level flow down to all resource groups and resources underneath it. An overpermissioned service principal at the subscription level is a skeleton key for the entire subscription.
Managed Identity misuse is another recurring issue. Managed Identities are great — they eliminate the need to manage credentials manually. But when a Managed Identity assigned to a low-privilege resource has been granted permissions that exceed what that resource needs, an attacker who compromises the resource inherits those permissions via the IMDS endpoint. Same pattern as EC2 instance profiles, different cloud.
In GCP, Workload Identity Federation misconfigurations are increasingly common as organizations migrate away from service account keys. Improperly scoped attribute conditions in Workload Identity pools can allow external principals to impersonate service accounts they shouldn't have access to. The GCP documentation on this is good, but the nuance of attribute mapping conditions is easy to get wrong.
GCP's default service accounts are also a persistent problem. The Compute Engine and App Engine default service accounts ship with Editor permissions at the project level. Editor is effectively admin for most practical purposes. If you're not explicitly disabling these accounts or restricting their permissions, they're a liability.
Scanning and Detection: What Most Teams Miss
Automatic IAM scanning is table stakes at this point. Tools like Prowler, ScoutSuite, and CloudSploit cover the obvious misconfigurations. But there are gaps.
Most automated scanners look for static misconfigurations — wildcard permissions, public access settings, missing MFA. What they often miss is privilege escalation paths that only become apparent when you analyze the combination of permissions across multiple policies. A principal that has iam:AttachUserPolicy and iam:CreatePolicy individually doesn't look alarming. Together, they're a full privilege escalation path.
Tools like Cloudsplaining (for AWS) and IAM Vulnerable (a deliberately misconfigured lab environment for practice) are specifically designed to surface these combinatorial escalation paths. PMapper is another excellent option — it builds a graph of IAM relationships and identifies the shortest path from any principal to admin. If your team isn't running something like this regularly, you have blind spots.
For detection, CloudTrail (AWS), Azure Activity Log, and GCP Cloud Audit Logs are your primary data sources. Key signals to alert on: AssumeRole calls from unexpected principals or regions, IAM policy modifications outside of approved change windows, and any call to iam:CreateAccessKey or iam:CreateLoginProfile on accounts other than the caller's own.
A Framework for Auditing Before Attackers Do
If you want to actually get ahead of this, here's a practical starting point:
-
Inventory all principals and their effective permissions. Not just what policies say — what the effective permissions are after policy evaluation. AWS IAM Access Analyzer can help with this. So can manual review using the policy simulator.
-
Run a privilege escalation analysis. Use PMapper or a similar tool to identify every path from any principal to admin. Treat each path as a finding that needs remediation.
-
Audit cross-account and cross-service trust relationships. Every role trust policy should be reviewed for overly broad principals. Every resource-based policy that grants cross-account access should be justified and documented.
-
Implement permission boundaries. AWS permission boundaries are underused and underappreciated. They cap the maximum permissions a principal can have regardless of what's attached to them — a powerful guardrail for developer environments where IAM changes happen frequently.
-
Establish a least-privilege enforcement cadence. AWS IAM Access Advisor and Azure's Access Review feature both show last-used permission data. Use this to identify and remove permissions that haven't been exercised in 90+ days.
Cloud IAM isn't a set-and-forget problem. It's a living, breathing attack surface that changes every time a developer spins up a new service or a Terraform module gets updated. Treat it that way, audit it continuously, and you'll stop being the low-hanging fruit that every red team finds in the first hour.