AWS IAM Access Analyzer misses toxic permission combos
AWS IAM Access Analyzer checks resource-based policies for unintended external access. It does not check whether a single role can chain its own permissions into full account takeover. That gap matter

AWS IAM Access Analyzer checks resource-based policies for unintended external access. It does not check whether a single role can chain its own permissions into full account takeover. That gap matters more as AWS environments grow, because the tool many teams treat as their IAM safety net was never built to catch privilege escalation paths.
Access Analyzer launched at AWS re:Invent 2019, according to Plerion, as a way to flag resources shared outside an AWS account or organization. It's genuinely good at that narrow job. The trouble starts when teams assume it does more, like spotting toxic combinations of permissions that let a low-privilege user become an admin.
This article walks through where Access Analyzer's blind spots actually are, why they exist, and what to run alongside it to close the gap.
What Access Analyzer Actually Checks
Access Analyzer works by comparing resource policies (S3 buckets, KMS keys, IAM roles, Lambda functions, and similar) against a zone of trust you define, usually your account or organization. If a policy grants access to something outside that zone, it generates a finding.
That is a policy analysis problem, not a permission graph problem. Access Analyzer looks at one resource's policy in isolation. It does not simulate what happens when permission A on one role combines with permission B on another to create a path an attacker could walk from low privilege to full control.
This distinction explains almost every limitation covered below. The tool answers "is this resource exposed externally?" It does not answer "can any identity in my account escalate its own privileges?"
The Temporal Blind Spot
One of the more surprising gaps is time-based. According to a deep dive on IAM Access Analyzer, the tool only evaluates permissions for identities that existed for the entire period it's tracking.
That means a role created five minutes ago will not show up correctly in the analysis window Access Analyzer uses to generate certain findings, particularly around unused access. If your CI/CD pipeline spins up temporary roles for deployments, or your team provisions roles on demand for contractors, those identities can operate for a while before the analyzer has enough history to flag them properly.
In fast-moving environments this is not a minor edge case. Auto-scaling groups, ephemeral Lambda execution roles, and short-lived federated sessions are common in modern AWS accounts. Each one can carry excess permissions during the exact window when Access Analyzer has the least visibility into them.
Practical impact:- New roles tied to infrastructure-as-code deployments may run unaudited for days
- Contractor or temp-access roles often get deleted before the tracking window catches up
- Auto-scaling roles that live only for the duration of a job may never register at all
Toxic Permission Combos That Slip Through
This is the core problem with treating Access Analyzer as a full IAM security tool. It checks policies individually. It does not model attack paths.
Consider a role with s3:* and a separate, seemingly unrelated grant of iam:*. Neither permission alone triggers an external-access finding, because neither necessarily exposes anything outside your account. But according to a guide on building least-privilege roles with Access Analyzer, that pairing creates a huge amount of unnecessary attack surface. Someone with iam:* can create a new admin user or attach an admin policy to their own role. Combined with s3:*, they can also exfiltrate or tamper with any bucket in the account.
Other combinations that routinely escape detection:
iam:PassRolepluslambda:CreateFunction: lets a user create a Lambda function, pass it a highly privileged execution role, then invoke it to run code with that role's permissions.iam:PassRoleplusec2:RunInstances: same escalation pattern, but through an EC2 instance profile instead of Lambda.iam:CreatePolicyVersion: lets a user rewrite the permissions of a policy they're already attached to, effectively self-granting admin.sts:AssumeRoleon a wildcard resource: quietly grants the ability to assume any role in the account that trusts the calling principal, including roles created after the policy was written.
None of these are exotic. They show up in real environments because permissions accumulate over time, and nobody sits down to ask "what can these grants do in combination?" Access Analyzer was not designed to ask that question either.
Detection vs Prevention: What the Tool Is Actually For
It's worth being precise about what Access Analyzer does well. It detects certain classes of misconfiguration after they exist. According to Plerion's documentation on the service, it does not stop those misconfigurations from happening in the first place.
That's a meaningful limitation for teams that treat a clean Access Analyzer dashboard as proof their IAM setup is safe. A finding only appears once a resource policy has already granted unintended access. There is no gate that blocks a risky policy from being attached to a role during deployment, unless you build that gate yourself using access previews or custom policy checks.
Access previews help here, but only partially. According to AWS's own guidance on prioritizing Access Analyzer findings, previews let you validate public and cross-account access before you deploy a policy change. That's useful, but it still requires someone to manually run the preview and interpret the result. It is not an automatic blocker in your deployment pipeline.
Error Findings vs Security Findings: A Common Point of Confusion
Access Analyzer produces two different categories of output, and teams frequently conflate them. Security findings relate to unintended external or public access on a resource policy. Error findings relate to policy syntax problems, like referencing a deleted role or malformed JSON.
An error finding is not a security signal. A policy that references a role which no longer exists will generate an error finding, but that says nothing about whether the policy, as written, is dangerous. Teams that triage findings without distinguishing the two categories waste time chasing syntax cleanup while missing genuinely risky access grants sitting in the same list.
The $1,000-a-Month Mistake
Detection gaps aren't just a security abstraction, they cost real money. According to a documented case published on Dev.to, a team relying on IAM Access Analyzer missed an overprovisioning mistake that quietly added roughly $1,000 per month in unnecessary cloud spend.
The pattern is familiar to anyone who has audited a mature AWS account: overly broad permissions let services or automation provision resources nobody intended to keep running, and nothing in the IAM tooling flagged the excess access as a cost risk, because cost was never something Access Analyzer was built to evaluate. It checks for unintended access, not unintended spend.
This case is a useful reminder that IAM misconfigurations don't only lead to breaches. They also lead to shadow infrastructure, orphaned resources, and bills nobody can explain three months later.
| Issue type | Access Analyzer catches it? |
|---|---|
| Public S3 bucket | Yes |
| Cross-account role trust | Yes |
| Privilege escalation via iam:PassRole | No |
| Overprovisioning leading to cost overrun | No |
| Newly created role with excess access | *Delayed |
This shows where the tool's detection coverage stops and where compensating controls need to start.
Cross-Service Permission Chains and the Confused Deputy Problem
A related blind spot involves what security researchers call the confused deputy problem: a service with legitimate, broad permissions gets tricked into performing an action on behalf of an attacker who has no direct access to the underlying resource.
In AWS terms, this often shows up when a Lambda function or EC2 instance has a role with more access than the workload actually needs, and that role's trust policy doesn't restrict who can invoke or assume it tightly enough. An attacker who compromises the application layer, not the IAM layer, can ride that overprivileged role to reach resources they could never touch directly.
Access Analyzer's resource-policy focus means it can miss this entirely. The S3 bucket policy might look fine in isolation. The IAM role attached to the compute resource sitting next to it might be the actual problem, and that role's excess permissions won't generate an external-access finding unless the role itself is shared outside the trust zone.
Building Compensating Controls Beyond Access Analyzer
Given these gaps, organizations that rely on Access Analyzer alone are leaving real risk unmanaged. According to research on IAM weaknesses published on Medium, many organizations struggle to identify and remove over-permissioned users specifically because they lack tooling and regular audit discipline beyond the built-in AWS console tools.
Here's a more complete approach:
- Run a dedicated privilege escalation scanner. Open-source tools like PMapper or third-party CSPM products build a graph of who can assume what, and specifically test for known escalation chains like
iam:PassRolepluslambda:CreateFunction. - Audit
iam:*andsts:AssumeRolegrants separately. Anywhere these appear alongside another broad service permission, treat it as a manual review item regardless of what Access Analyzer reports. - Use access previews before every policy change, not just at initial rollout, and make the review a required step rather than an optional one.
- Set a recurring audit cadence. Quarterly reviews of IAM policies catch drift that accumulates between deployments, especially in accounts with many contributors.
- Track cost anomalies alongside IAM changes. A sudden bill increase is sometimes the fastest signal that a permission change went further than intended.
CI/CD Integration: Catching Misconfigurations Before They Ship
The most effective fix for Access Analyzer's detection-not-prevention limitation is to move policy checks earlier, into the pipeline, rather than relying on post-deployment scans.
A simple example using a policy linter as a pre-merge check:
name: iam-policy-check
on:
pull_request:
paths:
- "infra/iam/**"
jobs:
scan-policies:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run policy linter
run: |
pip install parliament-cli
for f in infra/iam/*.json; do
parliament --file "$f"
doneThis catches obvious problems, like wildcard actions on wildcard resources, before a human even reviews the pull request. Pair it with an access preview call in a later pipeline stage to validate the policy against your live account before it merges to production.
Scaling: Why the Gap Widens in Large Environments
Detection gaps compound as an AWS footprint grows. A single account with a handful of roles is easy to reason about by hand. An organization with dozens of accounts, hundreds of roles, and constant infrastructure-as-code churn cannot rely on manual review to catch escalation paths, and Access Analyzer's per-resource-policy model doesn't scale to answer "what's the worst thing any identity in this org can do?"
The temporal tracking limitation gets worse too. In large organizations, roles are created and destroyed constantly by automation. That means a larger share of the account's total identities are, at any given moment, sitting in the blind spot where Access Analyzer hasn't accumulated enough history to evaluate them properly.
This is the argument for treating Access Analyzer as one input among several, not the final word on IAM risk. It is a solid tool for its actual job: catching resource policies that grant unintended external access. Teams that need to answer harder questions about privilege escalation, cross-service chains, and cost-driving overprovisioning need to add tooling that was purpose-built for those questions.
FAQ
Q: Does IAM Access Analyzer detect privilege escalation paths?A: Not directly. It evaluates resource policies for unintended external access, not combinations of permissions across roles that allow one identity to escalate its own privileges.
Q: What's the difference between an error finding and a security finding in Access Analyzer?A: An error finding flags a syntax or reference problem in a policy, like pointing to a deleted role. A security finding flags actual unintended access. They require different responses, and confusing them wastes review time.
Q: Why do newly created IAM roles sometimes get missed?A: Access Analyzer needs a role to exist for its full tracking window to evaluate certain findings accurately, particularly unused access findings. Roles created recently fall into a temporary blind spot until enough history accumulates.
Q: Should organizations stop using Access Analyzer given these gaps?A: No. It still does its core job well and costs nothing extra to enable. The fix is adding complementary tools for escalation-path detection and treating Access Analyzer as one layer, not the entire IAM security program.
Takeaways
- Enable Access Analyzer across every region and account, it's free coverage for a real class of problem: unintended external access.
- Do not assume a clean Access Analyzer report means your IAM setup is safe from privilege escalation.
- Specifically audit for known escalation pairs:
iam:PassRolewithlambda:CreateFunctionorec2:RunInstances, and anyiam:*grant sitting next to broad data-access permissions. - Add a dedicated escalation-path scanner, like PMapper, to your regular review cadence.
- Move policy validation into CI/CD so risky grants get caught before merge, not after deployment.
- Watch for cost anomalies as a secondary signal that an IAM change went further than intended.
Sources
Researched from the following. Figures and claims were current when this piece was written and may have moved since.
- AWS IAM Access Analyzer Deep Divehidekazu-konishi.com
- Ensure that IAM Access analyzer is enabled for all regionsplerion.com
- Weaknesses in AWS IAM: An In-depth Explorationmedium.com
- Building Least-Privilege IAM Roles with IAM Access Analyzerthehiddenport.dev
- How to prioritize IAM Access Analyzer findingsaws.amazon.com
- IAM Access Analyzer Lied to Us: The $1,000/Month Overprovisioning Mistakedev.to
Comments