Join our Newsletter — 33% off our NHI Course
Home› Guides› How to find AWS IAM policies with wildcard…
Guide Identity & Access Management (IAM)

How to find AWS IAM policies with wildcard actions: Find, rank and replace them safely

PDF for newsletter subscribers · free to read online

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 11 November 2026 13 min read
On this page

Wildcard actions such as "Action": "*", "s3:*" or an Allow with NotAction grant every matching API call a service offers, and most AWS accounts hold more of them than anyone has reviewed. They usually start as a quick fix during a build and stay because nothing breaks. This runbook shows how to find every IAM policy with wildcard actions in an account or an AWS Organization using read-only sources AWS provides: the account authorisation details export, AWS Config managed rules, Security Hub controls IAM.1 and IAM.21, and IAM Access Analyzer policy checks. It then covers how to rank what you find, replace wildcards with generated least privilege policies, and roll back through policy versions if something breaks. It is for cloud security and platform engineers who own IAM hygiene. For the policy model itself, see the AWS IAM Policies and Roles Guide.

This is an independent guide from NHI Mgmt Group, based on AWS's public documentation as of November 2026. It is not sponsored or reviewed by AWS. Product features change, so confirm settings against AWS's current documentation.

Key takeaways

  • Look for four shapes, not one. Full wildcard *, service wildcard service:*, partial wildcards such as iam:*AccessKey*, and Allow with NotAction, which allows everything not listed.
  • The managed rules miss inline policies. AWS Config rules iam-policy-no-statements-with-admin-access and iam-policy-no-statements-with-full-access (Security Hub IAM.1 and IAM.21) evaluate customer managed policies only, so inline policies need your own scan.
  • Only the default version counts. A managed policy can hold several versions; only the one with IsDefaultVersion true is in effect, but old versions are one API call from being restored.
  • Rank by who holds it and what the service is. iam:*, sts:*, kms:*, iam:PassRole with Resource: "*", and anything on a role an EC2 instance, Lambda function or CI pipeline can assume come first.
  • Replace with evidence, roll back with versions. Access Analyzer policy generation drafts a policy from up to 90 days of CloudTrail activity; ship it as a new default version so the previous version is the rollback.

When you need this

  • Audit or compliance finding: Security Hub IAM.1 (High) or IAM.21 (Low) failing, or an assessor asking for evidence of least privilege under NIST SP 800-53 AC-6.
  • After a credential exposure: when an access key or role session leaks, the blast radius is whatever its policies allow. A wildcard turns a contained leak into account takeover. The Capital One breach showed how much data a single over-permissioned role on one instance can reach.
  • Before tightening guardrails: introducing service control policies, permission boundaries or a new account structure goes better when you know which principals rely on broad grants.
  • Machine identity reviews: roles for workloads, pipelines and AI agents are the principals most likely to carry wildcards and least likely to have a human owner watching them.

What counts as a wildcard action

AWS documents that the * and ? wildcards can match all actions of a service ("s3:*") or part of an action name: "iam:*AccessKey*" matches CreateAccessKey, DeleteAccessKey, ListAccessKeys and UpdateAccessKey. Action names and prefixes are case insensitive, so IAM:listaccesskeys equals iam:ListAccessKeys and your scanner must normalise case. Because a wildcard matches whatever actions a service offers when the request is evaluated, actions AWS adds later are covered too, a point that follows from how matching works rather than one AWS states on the page.

PatternExampleWhat it grantsFlagged byDefault priority
Full wildcard"Action": "*" with "Resource": "*"Administrator access to the accountConfig iam-policy-no-statements-with-admin-access; Security Hub IAM.1 (High)Critical
Service wildcard"ec2:*", "iam:*"Every action in that serviceConfig iam-policy-no-statements-with-full-access; Security Hub IAM.21 (Low)Critical for iam, sts, kms, organizations, lambda; high otherwise
Allow with NotAction"Effect": "Allow", "NotAction": "iam:*"Every action in every service except those listedSecurity Hub IAM.21 (for NotAction: service:*); your own scanCritical
Wildcard in service name"s*:Get*"Matching actions across several servicesAccess Analyzer suggestion "Wildcard in service name"High
Partial action wildcard"s3:Get*", "iam:*AccessKey*"A family of actions, sometimes including sensitive onesNot flagged by IAM.21 (prefix with suffixed wildcard passes)Medium; high when it includes write or credential actions
PassRole on any role"iam:PassRole" with "Resource": "*"Ability to hand any role to a serviceAccess Analyzer security warning "Pass role with star in resource"Critical

AWS describes NotAction with Allow as matching all services and actions not explicitly listed, and warns it can grant more than intended. Treat it as a wildcard. Deny with NotAction is different: it grants nothing and is a common guardrail pattern, so exclude it from findings.

Before you start

SourceCoversGapsPermission or cost
aws iam get-account-authorization-detailsUsers, groups, roles with inline policies, attached managed policies, and every managed policy version with its documentOne account per call; documents are URL-encoded in the API responseiam:GetAccountAuthorizationDetails; free
AWS Config managed rulesDefault version of customer managed policies, re-evaluated on changeNo inline or AWS managed policies; not available in every RegionAWS Config recording of AWS::IAM::Policy; Config rule evaluation charges
Security Hub IAM.1, IAM.21Same rules surfaced as findings across accountsSame gaps; both run with excludePermissionBoundaryPolicy set to trueSecurity Hub with the standard enabled
aws accessanalyzer validate-policyAny policy document you pass, including inline policies and draftsOne document per callSee AWS pricing for Access Analyzer
aws accessanalyzer check-access-not-grantedProves a document does not grant up to 100 listed sensitive actionsAnswers yes or no per documentCharged per check; see AWS pricing

Run discovery from a read-only role, ideally one assumed into every member account from a security tooling account. Keep remediation behind a separate role that needs approval. Agree with the account owners which services are on your critical list before you rank anything.

Step-by-step

Steps 1 to 5 are read-only. Step 6 changes permissions but is reversible through policy versions.

  1. Export every policy in the account.
    aws iam get-account-authorization-details --output json > authz-<account-id>.json
    The output has UserDetailList, GroupDetailList, RoleDetailList (with RolePolicyList inline policies, AttachedManagedPolicies, InstanceProfileList and RoleLastUsed) and Policies, where each managed policy has a PolicyVersionList. Use --filter LocalManagedPolicy to limit it to customer managed policies, or --filter Role for roles. The CLI paginates automatically; the API returns IsTruncated and Marker, and AWS notes it can return fewer items than requested even when more exist. Policy documents are URL-encoded under RFC 3986 in the API response, so decode them if your tool has not.
  2. Scan statements for the six patterns. For each policy document (inline, and the managed version where IsDefaultVersion is true), normalise Statement and Action to lists, lower-case the action strings, and flag any Allow statement where an action contains * or ?, or where NotAction appears. Record the policy name or ARN, the statement Sid or index, the matched pattern, the Resource value and any Condition. Scan non-default versions separately and report them as a lower priority list: they are not in effect, but an identity with iam:SetDefaultPolicyVersion can restore one.
  3. Turn on the managed rules for continuous coverage. Deploy IAM_POLICY_NO_STATEMENTS_WITH_ADMIN_ACCESS and IAM_POLICY_NO_STATEMENTS_WITH_FULL_ACCESS as AWS Config managed rules (or enable Security Hub, which runs them as IAM.1 and IAM.21). Both evaluate on configuration change against AWS::IAM::Policy. The full access rule passes ec2:Describe* and fails ec2:*, so it will not catch partial wildcards. Read results with:
    aws configservice describe-compliance-by-config-rule --config-rule-names <rule-name>
    aws configservice get-compliance-details-by-config-rule --config-rule-name <rule-name> --compliance-types NON_COMPLIANT
  4. Validate each flagged document with Access Analyzer. Pass the document to policy validation to get AWS's own security warnings with line and column locations:
    aws accessanalyzer validate-policy --policy-document file://policy.json --policy-type IDENTITY_POLICY
    Findings come back as ERROR, SECURITY_WARNING, WARNING or SUGGESTION, each with an issueCode and a learnMoreLink. Security warnings such as "Pass role with star in resource" go straight to the top of the queue.
  5. Prove which sensitive actions are reachable and rank. For each document, test a fixed list of high-risk actions:
    aws accessanalyzer check-access-not-granted --policy-document file://policy.json \
      --access actions="iam:PassRole","iam:CreateAccessKey","iam:AttachRolePolicy","sts:AssumeRole","kms:Decrypt" \
      --policy-type IDENTITY_POLICY
    FAIL means the policy might allow at least one of them, and reasons names the statement. Join the result with who holds the policy: aws iam list-entities-for-policy --policy-arn <arn> for managed policies, the owning principal for inline ones. A wildcard on a role in an instance profile, a Lambda execution role or a CI federation role outranks the same wildcard on an unused test user.
  6. Replace wildcards with generated or hand-written least privilege. For roles with activity, start Access Analyzer policy generation, which reads up to 90 days of CloudTrail events from an existing trail and drafts a policy with action-level detail for supported services and service-level detail for others. Note that iam:PassRole is not tracked and must be added by hand, and data events get no action-level detail. Review the draft, scope resources where the actions support resource-level permissions, then publish it as a new default version:
    aws iam create-policy-version --policy-arn <arn> --policy-document file://scoped.json --set-as-default
    For inline policies, export the current document first, then use aws iam put-role-policy (or put-user-policy, put-group-policy) with the scoped version. Where a broad service grant is genuinely needed, keep the wildcard but add Resource ARNs and Condition keys, and record the exception.

Verify it worked

  • Rule results: the Config rules and Security Hub IAM.1 and IAM.21 findings move to compliant or passed after the next change-triggered evaluation.
  • Re-scan: a new authorisation details export shows no unexcepted wildcard statements in default versions or inline policies.
  • Checks pass: check-access-not-granted returns PASS for the sensitive action list on every remediated document.
  • No breakage: CloudTrail shows no rise in AccessDenied errors from the affected principals over a full business cycle, including month-end and batch jobs.

Rollback and common errors

SituationFix
A workload fails after a new managed policy versionaws iam set-default-policy-version --policy-arn <arn> --version-id <previous>; the old version is still stored
LimitExceeded on create-policy-versionA managed policy keeps at most five versions; delete the oldest non-default version with delete-policy-version after exporting it
An inline policy change breaks a jobRe-apply the exported original with put-role-policy; inline policies have no version history, so the export is your only rollback
Generated policy is missing actionsThe CloudTrail window missed rare paths, iam:PassRole or data events; add them from the failing AccessDenied event
Policy generation will not startTrails created by AWS Control Tower are not supported because the logs sit in the log archive account; use a trail Access Analyzer can read
Wildcard is in an AWS managed policyYou cannot edit it; detach it and attach a scoped customer managed policy instead

Choosing the right approach

A single account with a few hundred policies can be covered by the export and a short script on a weekly schedule at no cost. An AWS Organization should rely on Security Hub IAM.1 and IAM.21 for customer managed policies across every account and Region, add the authorisation details scan for inline policies, and run Access Analyzer validation in the pipeline so new wildcards are caught in pull requests rather than in production. Where teams deploy through infrastructure as code, fixing the template is the real remediation: a console fix will be overwritten on the next deploy.

Decide on exceptions explicitly. Break-glass administrator roles and the roles your landing zone uses legitimately hold "*"; tag them, protect them with MFA, session policies or SCP conditions, and exclude them from the KPI rather than leaving them as permanent red findings. For the wider set of reduction techniques, see the Least Privilege Techniques Guide, and for preventive guardrails the AWS Organizations and SCPs Guide.

Where identity fits

Wildcards matter most on non-human identities. A role assumed by an EC2 instance, a Lambda function, a container task or a GitHub Actions workflow runs unattended, its credentials can be taken from the workload, and nobody notices extra permissions until they are used. Prioritise roles whose trust policy names a service principal or an OIDC provider, and check whether the same role also holds iam:PassRole or iam:*, which makes a wildcard an escalation path. See How to Find IAM Privilege Escalation Paths in AWS and How to Find ec2 instance profiles with admin rights.

Common failure patterns

  • Trusting a green IAM.21: the control passes s3:Get* and ignores inline policies, so a clean dashboard can hide broad grants.
  • Scanning only the default version: a stored older version with "*" is restored by anyone with iam:SetDefaultPolicyVersion, a known escalation path.
  • Missing NotAction: a scanner that only looks for * in Action misses Allow plus NotAction, which is often broader.
  • Fixing the console, not the code: the next pipeline run reapplies the wildcard from the template.
  • Removing a wildcard from a dormant role first: effort goes to principals that pose little risk while active workload roles keep "*". Rank by use and exposure.
  • Leaked keys on a broad policy: in the LLMjacking campaigns, stolen cloud credentials were used to call AI services their owners never meant to expose; how far such a credential reaches depends on the policies behind it.

Metrics

MetricTarget
Security Hub IAM.1 failed findingsZero outside documented break-glass exceptions
Policies with service wildcards on critical services (iam, sts, kms, organizations)Zero
Inline policies with wildcard actionsFalling each month
Workload roles with iam:PassRole on "*"Zero
Pull requests blocked by Access Analyzer security warningsTracked; rising at first, then falling
Rollbacks after remediationLow and explained

Framework mapping

FrameworkReferenceRelevance
NIST SP 800-53 Rev 5AC-6 Least Privilege; AC-6(5) Privileged Accounts; AC-6(7) Review of User PrivilegesRemove broad grants and review them on a schedule
NIST CSF 2.0PR.AA-05Access permissions defined, reviewed and following least privilege
MITRE ATT&CKT1078.004 Cloud Accounts; T1098.003 Additional Cloud RolesWildcards widen what valid cloud credentials can do and let attackers grant themselves roles
AWS Security HubIAM.1, IAM.21Native detective controls for customer managed policies

Practitioner checklist

  • Export authorisation details from every account and scan inline and default managed versions.
  • Flag full, service, partial and service-name wildcards, Allow with NotAction, and PassRole on "*".
  • Enable Config rules or Security Hub IAM.1 and IAM.21 for continuous coverage.
  • Validate flagged documents with Access Analyzer and test a fixed sensitive action list.
  • Rank by principal type, use and service; workload roles first.
  • Replace with generated policies as new default versions; export inline policies before editing.
  • Fix the infrastructure as code template, not just the live policy.
  • Tag and document exceptions; add validation to the deployment pipeline.

Standards and references

Related NHI Mgmt Group resources: How to find unused AWS IAM roles and access keys · IAM Access Analyzer Guide · Top 10 AWS IAM Mistakes · Least Privilege Techniques Guide

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 11 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.