DEV Community

Jeff Tham
Jeff Tham

Posted on • Originally published at shieldly.io

Why Wildcards in AWS IAM Policies Are Dangerous (and How to Fix Them)

Originally published at shieldly.io/blog.

The asterisk is the single most overused character in AWS IAM. It is quick to type, it makes errors disappear, and it is the root cause of a huge share of real cloud breaches. There are three wildcards that matter most — in the Action, Resource, and Principal fields — and each one grants far more than most teams realize.

1. Action: * — Every Operation, Including Destructive Ones

"Action": "*" grants every API operation across every service. Even the narrower "s3:*" is dangerous: it bundles read, write, DeleteObject, DeleteBucket, and PutBucketPolicy — meaning a credential intended to upload a file can also wipe the bucket or rewrite its access policy.

{
  "Effect": "Allow",
  "Action": "*",
  "Resource": "*"
}
Enter fullscreen mode Exit fullscreen mode

This is administrator access by another name. If you see it outside a dedicated, tightly controlled admin role, treat it as a critical finding.

2. Resource: * — Across Every Object in the Account

"Resource": "*" applies the granted actions to every resource the service has. s3:GetObject on * can read every object in every bucket — not just the one the workload needs. Scope to explicit ARNs:

"Resource": "arn:aws:s3:::my-app-uploads/*"
Enter fullscreen mode Exit fullscreen mode

A few IAM and account-level actions genuinely require * because they have no resource ARN, but they are the exception. For the vast majority of policies, a real ARN belongs there.

3. Principal: * — Open to the Entire Internet

On resource-based policies (S3 bucket policies, KMS key policies, SQS, SNS, Lambda), "Principal": "*" means anyone — including anonymous, unauthenticated callers — unless a condition narrows it. This is how buckets end up publicly readable. If you must use it, always pair it with a strict condition such as aws:PrincipalOrgID or aws:SourceArn.

{
  "Effect": "Allow",
  "Principal": "*",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::my-bucket/*",
  "Condition": {
    "StringEquals": { "aws:PrincipalOrgID": "o-exampleorgid" }
  }
}
Enter fullscreen mode Exit fullscreen mode

How to Scope Wildcards Down

  • Enumerate the actions you actually call. Use CloudTrail or IAM Access Analyzer to see which operations the identity uses, then list only those.
  • Name your resources. Replace * with specific ARNs; use path prefixes where you need a group of objects.
  • Constrain principals with conditions. Never leave Principal: * unconditioned on a resource policy.
  • Catch them automatically. Wildcards reappear constantly as policies change. Run them through an AI-Powered IAM analyzer that flags every risky wildcard, explains the real-world exposure it creates, and proposes a scoped replacement.

Catch IAM risks automatically — paste a policy into Shieldly's free AI-Powered analysis. No signup, no credit card.

Top comments (0)