Join our Newsletter — 33% off our NHI Course
Home› Guides› Wildcard Trust Check: Find AWS Roles Anyone Can…
Guide Cloud & Workload Identity

Wildcard Trust Check: Find AWS Roles Anyone Can Assume

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

An IAM role whose trust policy names a wildcard principal, an OIDC provider without a subject condition or a SAML provider without attribute conditions can be assumed by identities you never approved. This guide is a focused check for those shapes only: how to find them across every account, how to tell a genuine exposure from a policy that is restricted by conditions, how to fix each one without breaking a pipeline or a sign-in flow, and how to keep them from coming back. It is for cloud security engineers, platform teams and identity teams. Reviewing named third-party accounts, external IDs and service principal source conditions is covered in How to review AWS cross-account trust policies for confused deputy; this page does not repeat it.

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

  • "*" and {"AWS": "*"} mean the same thing: AWS documents both forms as granting access to all principals, including anonymous ones, and strongly recommends against a wildcard in a role trust policy because it lets other principals become a principal in your account.
  • A federated trust is only as narrow as its conditions: the provider ARN in the Principal element says which issuer to believe, not which subject; without sub, aud or SAML attribute conditions every identity that issuer can mint is trusted.
  • AWS enforces the subject check for some providers only: IAM rejects GitHub trust policies without a usable token.actions.githubusercontent.com:sub and HCP Terraform policies that do not evaluate app.terraform.io:sub, but other OIDC issuers and SAML providers rely on you.
  • Access Analyzer finds reachability, your parser finds shape: run both, because an external access finding tells you a role is reachable from outside the zone of trust, while a policy parse tells you why and which condition is missing.
  • Fix by narrowing, then verify with CloudTrail: pin the subject or attribute that the legitimate caller already presents, confirm its AssumeRole events still succeed, and only then remove the old statement.

The three trust shapes this check targets

Risk comes from a Principal that does not identify a bounded set of callers and a Condition block that does not bound it either.

ShapeWhat the trust policy looks likeWho can assume the roleSeverity before conditions
Wildcard AWS principal"Principal": "*" or "Principal": {"AWS": "*"} with action sts:AssumeRoleAny IAM principal in any AWS account whose own identity policy allows the callCritical
OIDC provider without subject restriction"Principal": {"Federated": "arn:aws:iam::ACCOUNT:oidc-provider/ISSUER"} with sts:AssumeRoleWithWebIdentity and only an aud check, or no conditionAny token the issuer will sign for that audience, which for a multi-tenant SaaS issuer can include other customersCritical for shared issuers, high for issuers you run
Built-in OIDC provider without conditions"Federated" set to accounts.google.com, graph.facebook.com, www.amazon.com or cognito-identity.amazonaws.comAny user of that public identity provider, or any identity pool user, depending on the providerCritical
SAML provider without attribute conditions"Principal": {"Federated": "arn:aws:iam::ACCOUNT:saml-provider/NAME"} with sts:AssumeRoleWithSAML and no condition, or only SAML:audAny user your IdP will issue an assertion for that names the roleHigh: bounded by your IdP's role assignment, so the IdP becomes the only control

Two details from the AWS Principal element reference shape the parser. First, you cannot use a wildcard to match part of a principal name or ARN, so a pattern such as arn:aws:iam::*:role/ci is not valid in Principal and scoping must happen in conditions such as aws:PrincipalArn. Second, "Service": "*" is not allowed, so service principal grants are out of scope here. AWS also notes that AssumeRoleWithSAML does not require AWS credentials, and the same is true of AssumeRoleWithWebIdentity: the caller only needs a token or assertion, so a missing condition is reachable from the internet, not just from other AWS accounts.

Step 1: Collect every trust policy in every account

  1. Use a read-only audit role: deploy a role with iam:GetAccountAuthorizationDetails, iam:ListRoles, iam:GetRole, iam:ListOpenIDConnectProviders, iam:GetOpenIDConnectProvider, iam:ListSAMLProviders and iam:GetSAMLProvider to every account through your account baseline.
  2. Export roles with trust policies: aws iam get-account-authorization-details --filter Role returns each role's AssumeRolePolicyDocument along with attached and inline permission policies.
  3. Export the providers: record each OIDC provider's URL and client ID list (audiences) and each SAML provider's name and creation date. AWS documents that the token's aud claim must match an audience registered on the provider, that a provider can carry up to 100 audiences, and that if a token carries both aud and azp, STS uses azp as the audience.
  4. Normalise statements: one row per Allow statement with account, role name, role path, principal type, principal value, action, every condition operator and key, and whether the statement is Allow or Deny. A Deny with StringNotEquals on aws:PrincipalOrgID can make a broad Allow safe.

Step 2: Flag the shapes with clear rules

Apply these rules to the normalised table. Each names the condition keys, from the AWS condition key references, that turn a match into an acceptable trust.

RuleMatchesAccept only if a condition restricts it withDo not accept
W1 wildcard principalPrincipal "*" or AWS "*", action sts:AssumeRole, sts:TagSession or sts:SetSourceIdentityStringEquals on aws:PrincipalOrgID, ForAnyValue:StringLike on aws:PrincipalOrgPaths, StringEquals on aws:PrincipalAccount, or ArnEquals on aws:PrincipalArn naming specific rolesaws:SourceIp alone, aws:UserAgent, tag keys the caller can set, StringLike values that are themselves "*"
F1 custom OIDC, no subjectFederated oidc-provider ARN, sts:AssumeRoleWithWebIdentityBoth ISSUER:aud and ISSUER:sub (or the issuer's documented immutable claims) with StringEquals, or StringLike with a bounded prefixaud only; sub with a leading wildcard; sub equal to "*"
F2 built-in OIDCFederated accounts.google.com, graph.facebook.com, www.amazon.com, cognito-identity.amazonaws.comProvider aud (Google client ID, Cognito identity pool ID) plus sub, or amr for CognitoNo condition at all; Cognito amr allowing unauthenticated where guest access was not designed
S1 SAML, no attributesFederated saml-provider ARN, sts:AssumeRoleWithSAMLSAML:aud for console roles plus at least one identity attribute such as saml:sub, saml:iss, saml:namequalifier or a group attributeNo condition; SAML:aud only on a role that grants administrative permissions

Why aws:SourceIp is not enough for W1

AWS's own note on changing a trust principal to "*" suggests limiting access through a Condition such as specific IP addresses. Treat that as a minimum, not as acceptance. The global condition key reference states that aws:SourceIp works only for public IP ranges and is not present when the request comes through a VPC endpoint, so an IP condition can fail open or closed depending on network path, and it says nothing about which account the caller belongs to. An organisation key does.

Reading OIDC subject conditions

  • GitHub Actions: AWS documents that IAM checks token.actions.githubusercontent.com:sub is present and not solely a wildcard or null when the trust policy is created or updated, and fails the request otherwise. Older policies and values such as repo:OrgName/* still need review. AWS warns that if sub is not limited to your organisation or repository, GitHub Actions from organisations outside your control can assume the role. See the GitHub Actions OIDC Federation Hardening Guide.
  • HCP Terraform: AWS states that roles for the app.terraform.io provider must evaluate app.terraform.io:sub, that IAM returns an error on save if they do not, and that STS denies authorisation requests from roles that do not. Still check the value: a wildcard at organisation level trusts every workspace.
  • Other issuers: for GitLab, Buildkite, CircleCI, self-hosted Kubernetes issuers and any other OIDC provider, nothing in IAM stops you saving an aud-only policy. These are where F1 findings concentrate. See How to audit AWS IAM Roles Anywhere and OIDC identity providers for the per-issuer claim names.
  • Operators: StringLike with repo:org/* is a bounded prefix; StringLike with *:ref:refs/heads/main is not, because the organisation part is open. Flag any value that starts with a wildcard.

Reading SAML conditions

The AWS SAML role guide shows console roles using StringEquals on SAML:aud set to the sign-in endpoint, and says that for programmatic roles you must specify at least one attribute so the role is limited to a subset of users. Note the condition key reference: saml:aud comes from the assertion's Recipient field, not its Audience field, so it confirms where the assertion is being presented, not who the user is. A role trusted with only SAML:aud is therefore available to anyone your IdP is willing to send with that role in the assertion. Accept that for low-privilege roles where IdP assignment is the deliberate control; flag it on any role with write or administrative permissions.

Step 3: Confirm reachability with IAM Access Analyzer

  • External access analyzer: create one with the organisation as the zone of trust in the delegated administrator account. AWS states that for IAM roles Access Analyzer analyses trust policies and generates findings for roles that an entity outside the zone of trust can access, and that because roles are global the finding appears in each enabled Region. Deduplicate by role ARN.
  • What a finding does and does not tell you: AWS says the analyser considers only condition keys that external users cannot directly influence or that are otherwise impactful to authorisation, does not examine access logs, and errs towards a false positive when it cannot fully decide. So a W1 statement restricted by aws:PrincipalOrgID should not produce a finding, while an F1 or S1 trust to a provider in your account may still show as external because the federated identities are outside the organisation by definition. Use findings to prioritise, and your rule table to explain.
  • Pre-deployment check: run aws accessanalyzer check-no-public-access with resource type AWS::IAM::AssumeRolePolicyDocument against any new or changed trust policy in CI. AWS lists that resource type for CheckNoPublicAccess, and charges per custom policy check, so run it on changed policies rather than the whole estate on every build. See the IAM Access Analyzer Guide.

Step 4: Check whether the open trust has been used

A wildcard trust that nobody has exercised is a configuration finding. One that has been exercised by an unknown account is an incident. Separate them before anyone edits a policy.

ShapeCloudTrail event (sts.amazonaws.com)Fields to readEscalate when
W1AssumeRoleuserIdentity.accountId, userIdentity.arn, sourceIPAddress, requestParameters.roleArn, recipientAccountIdCalling account is not in your organisation or vendor register
F1, F2AssumeRoleWithWebIdentityuserIdentity.identityProvider, userIdentity.userName (the token subject), requestParameters.roleArn, sourceIPAddressSubject names a repository, project or user that is not yours
S1AssumeRoleWithSAMLuserIdentity.principalId, userIdentity.userName, requestParameters.principalArn, requestParameters.roleArnA user outside the group that should hold the role, or a SAML provider ARN you do not recognise
Change trackingUpdateAssumeRolePolicy, CreateRole, CreateOpenIDConnectProvider, CreateSAMLProvider (iam.amazonaws.com)userIdentity, requestParameters.policyDocumentA trust widened outside a change window

Also read GetRole's RoleLastUsed and the permission policies: a W1 role that reads one bucket is a different priority from one with iam:PassRole. Use from an account or subject you cannot explain is an incident: investigate before editing the policy. MITRE ATT&CK tracks adding or widening trust as T1484.002 Trust Modification and use of the resulting session as T1078.004 Cloud Accounts.

Step 5: Remediate each shape

W1: replace the wildcard

  1. From Step 4, list the accounts and role ARNs that actually assumed the role in your look-back period.
  2. If they are all in your organisation, keep "Principal": {"AWS": "*"} only if you need organisation-wide access, and add StringEquals on aws:PrincipalOrgID, or ForAnyValue:StringLike on aws:PrincipalOrgPaths for specific OUs. Otherwise name the account or role ARNs directly.
  3. If a vendor is a caller, move it to a named external principal with an external ID and review it under the cross-account process.
  4. If the role was meant for callers whose role names change, use aws:PrincipalArn in a condition rather than a role ARN in Principal: AWS converts a role ARN in Principal to the role's unique ID on save, and a deleted and recreated role then no longer matches.

F1 and F2: add the subject

  1. Take the token subjects seen in AssumeRoleWithWebIdentity events and confirm with the owning team which are legitimate.
  2. Add ISSUER:sub with StringEquals for the exact values, or StringLike with a prefix that begins with your organisation or project. Prefer immutable identifiers where the issuer offers them, as described in the OIDC audit guide.
  3. Keep ISSUER:aud. For Cognito, AWS states roles must contain at least one condition key and that cross-account roles need aud; check amr if the identity pool allows guest access.
  4. For built-in providers such as accounts.google.com, pin aud to your client ID and sub to known users, or move the workload to a custom provider you control.

S1: add identity attributes

  1. Keep SAML:aud for console roles, set to the Regional sign-in endpoint AWS documents for your provider.
  2. Add a condition on an attribute your IdP sends consistently: saml:iss for the issuer, saml:namequalifier to bind to one provider in one account, or a group attribute. Use saml:sub only where saml:sub_type is persistent, since AWS documents that a transient subject changes each session.
  3. Re-check the IdP side: the IdP's role assignment remains the primary control, so review which groups can receive the role in the assertion. See the Federation and Trust Relationships Guide.

Test and roll back

  • Pilot: change one non-production role per shape first and run the real pipeline, job or sign-in.
  • Save the old document: keep the previous AssumeRolePolicyDocument in your ticket; rollback is aws iam update-assume-role-policy with that saved document.
  • Watch for AccessDenied: after each change, query CloudTrail for failed AssumeRole* calls on the role for 24 hours. A failure from a legitimate subject means the condition value is wrong, not that the condition should be removed. See the AWS AccessDenied Troubleshooting Guide.

Decision guidance

SituationPreferred fixTrade-off
Many accounts in one organisation need the same roleAWS "*" plus aws:PrincipalOrgID or aws:PrincipalOrgPathsAny principal in the organisation with sts:AssumeRole on "*" can use it; pair with permission limits on the caller side
A small, stable set of callersNamed account or role ARNs in PrincipalRecreated roles break the trust until the ARN is re-saved
CI pipelines on a shared SaaS issuersub pinned to repository or project, plus environment or branch where availableMore roles to manage, one per trust boundary
Workforce console access through SAMLSAML:aud plus a group or issuer attribute; keep assignment in the IdPTwo places to review; attribute names must stay stable in the IdP

Small organisations: review a handful of roles by hand in the console plus one external access analyzer. Large organisations: run the export and rules centrally on a schedule and block new W1 and F1 shapes in CI.

Where identity fits

Each flagged role is a non-human identity entry point: record its owner, purpose and callers in your NHI inventory. See the Workload Identity Federation Guide and the Workload Identity Federation Trust Review Checklist.

Detection and metrics

  • Alert on trust changes: UpdateAssumeRolePolicy and CreateRole where the new document contains "*" in Principal, or a Federated principal with no Condition. See the AWS CloudTrail Guide.
  • Alert on first-seen callers: an AssumeRoleWithWebIdentity subject or an AssumeRole calling account not seen in the previous 30 days for that role.
MetricSourceTarget
Roles matching W1 without an organisation, account or ARN conditionRule tableZero
OIDC roles without a sub condition, or with a sub value starting with a wildcardRule tableZero
SAML roles with write or admin permissions and no identity attribute conditionRule table joined to permission policiesZero
Active external access findings on roles without a named ownerAccess AnalyzerZero
Trust policy changes that failed check-no-public-access in CI and were deployed anywayCI logs and CloudTrailZero
Median days from detection to fix for W1 and F1 findingsFindings registerFalling each quarter

Common failure patterns

  • Testing with "*" and never reverting: AWS's own guidance says you can change a role principal to "*" after creating it and warns not to leave the role accessible to everyone. Temporary wildcards made during debugging are a common source of W1 findings.
  • Trusting the issuer, not the subject: an aud-only trust on a shared CI issuer means every tenant who can request that audience is trusted. The audience is usually a public, well-known value such as sts.amazonaws.com.
  • Relying on IP conditions: aws:SourceIp is absent through VPC endpoints and says nothing about the calling account, so it is not a substitute for an organisation key.
  • Assuming IAM validation covers everything: the save-time checks AWS describes apply to the GitHub and HCP Terraform providers. Other OIDC issuers and SAML providers accept unconditioned policies.

Framework mapping

FrameworkReferenceHow this check supports it
NIST CSF 2.0PR.AA-01, PR.AA-05, DE.CM-09Managed identities and credentials, least privilege access enforced and reviewed, monitoring for adverse events
NIST SP 800-53 Rev 5AC-2, AC-3, AC-6, AC-20, CM-2, CA-7Account management, access enforcement, least privilege, use of external systems, baseline configuration, continuous monitoring
CIS Controls v8.1Controls 5 and 6Account management and access control management
ISO/IEC 27001:2022 Annex AA.5.15, A.5.18, A.8.2Access control, access rights, privileged access rights
MITRE ATT&CKT1078.004, T1484.002, T1098.003, T1199Cloud accounts, trust modification, additional cloud roles, trusted relationship

Practitioner checklist

  • Export every role trust policy and every OIDC and SAML provider in every account.
  • Apply rules W1, F1, F2 and S1 and record each match with its conditions and permissions.
  • Accept wildcard principals only with aws:PrincipalOrgID, aws:PrincipalOrgPaths, aws:PrincipalAccount or aws:PrincipalArn conditions.
  • Require both aud and sub, with no leading wildcard, on every OIDC trust.
  • Require an identity attribute condition on SAML roles with write or administrative permissions.
  • Run an external access analyzer with the organisation as zone of trust and reconcile findings with the rule table.
  • Check CloudTrail for AssumeRole, AssumeRoleWithWebIdentity and AssumeRoleWithSAML callers before editing any policy.
  • Run check-no-public-access on changed trust policies in CI.
  • Alert on UpdateAssumeRolePolicy, CreateOpenIDConnectProvider and CreateSAMLProvider.

Standards and references

Related NHI Mgmt Group resources: How to review AWS cross-account trust policies for confused deputy · How to audit AWS IAM Roles Anywhere and OIDC identity providers · AWS STS and AssumeRole Guide · AWS IAM Policies and Roles Guide

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 12 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