Back to Blog
June 27, 2026

How to Check an AWS IAM Policy for Risks (Free, No Signup)

Most risky AWS access is technically valid. IAM does not error on an over-broad policy, so the danger slips past terraform apply and human review alike. You do not need an account or any credentials to catch the common cases though — here is the checklist we use, and free tools that run entirely in your browser to flag each pattern.

1. Permission policies: wildcards and escalation

On an identity or resource policy, scan for the patterns that quietly grant far more than intended:

  • Wildcard actions. Action: "*" or service:* (for example s3:* when you only call s3:GetObject).
  • Privilege-escalation actions. iam:PassRole, iam:CreatePolicyVersion, iam:AttachUserPolicy, iam:UpdateAssumeRolePolicy and similar let a principal grant itself more. See the IAM privilege escalation reference for each path.
  • NotAction with Allow. This permits everything you did not list — usually far broader than intended.
  • Wildcard resources. Resource: "*" where specific ARNs would do.

Paste a policy into the free IAM Policy Linter and it flags all of these instantly, with no signup.

2. Trust policies: who can assume the role

A role's trust policy is evaluated independently of its permissions, so an over-broad principal silently widens who can step into that access. Check for a Principal: "*" with no condition, an entire account trusted for third-party access without an sts:ExternalId (the confused deputy problem), and service principals missing an aws:SourceArn guard. The Trust Policy Explainer spells out exactly who can assume the role and flags these gaps. Background: what a trust policy is.

3. S3 bucket policies: public exposure

Public buckets remain one of the most common cloud data leaks. A bucket policy with Principal: "*" and no condition exposes the bucket to the internet; public write or s3:* is worse. The S3 Bucket Policy Checker tells you what a policy grants and whether it is public. Note that account-level Block Public Access can override a public-looking policy, so keep it enabled unless you genuinely need public access.

4. CloudFormation templates: IAM at the source

Most IAM reaches production through infrastructure-as-code, so the cheapest place to catch an over-permissioned role is the template itself. Scan for inline policies with Action: "*" or service wildcards, roles attaching AdministratorAccess, and AssumeRolePolicyDocument trust blocks with a wildcard principal. The CloudFormation IAM Checker extracts every IAM resource from a JSON template and flags these in one pass.

5. ARNs: know what you're actually granting access to

Every Resource field is an ARN with a fixed structure — partition, service, region, account ID, and resource. A wrong or wildcarded field here undermines an otherwise tight policy: a wildcard account ID matches resources in every account, not just yours, and a malformed ARN can silently fail to match anything (making a Deny statement useless) or match more than intended. The ARN Parser & Explainer breaks down any ARN field-by-field and flags these cases.

6. Reviewing policy changes: what actually got added

A one-line diff in a pull request can hide a large permission increase — appending iam:PassRole to an existing Action array looks trivial in a text diff but can be the difference between a scoped role and a full privilege-escalation path. The IAM Policy Diff tool compares two policy versions and lists exactly what was added or removed, calling out privilege-sensitive additions separately so they don't slip through review.

7. Right-sizing an over-broad role

Roles accumulate permissions faster than they shed them — a role granted s3:* "to get something working" rarely gets tightened afterward. CloudTrail already has the answer: it records every API call the role actually made. The CloudTrail Policy Generator takes a sample of events and generates a minimal policy scoped to exactly what was used — a starting point for tightening, not a final answer.

8. Policy size limits: a different kind of risk

A customer-managed policy is capped at 6,144 characters (inline policies at 2,048 / 10,240 / 5,120 for a user / role / group), measured after whitespace is stripped. Teams that don't check this ahead of time often hit the limit mid-incident and split a policy under time pressure — a bad time to make access-control decisions. The Policy Size Calculator checks a policy against all four limits before it becomes a problem.

When to go deeper than a checklist

Static checks catch the obvious cases, but real escalation is often an interactionbetween permissions that are individually fine — PassRole plus a compute service, or a chain across roles. That needs reasoning about the whole policy in context. Shieldly's AI-Powered analyzer reads the full document, explains why each finding matters in plain English, and returns the tightened policy. It is free to try with no signup, and ships as a web app, CLI, VS Code extension, GitHub Action, and @shieldly/cdk-guard construct so you can run the same check in a pull request.

Analyze a policy with AI — free

Paste an IAM, trust, or CloudFormation policy and get AI-Powered findings plus the fix in seconds. No signup, no AWS credentials.

Amazon Web Services (AWS) is a trademark of Amazon.com, Inc. Shieldly is not affiliated with, endorsed by, or sponsored by Amazon Web Services.