Join our Newsletter — 33% off our NHI Course
Home› Guides› How to review AWS cross-account trust policies for…
Guide Non-Human Identity (NHI)

How to review AWS cross-account trust policies for confused deputy: a role-by-role method

PDF for newsletter subscribers · free to read online

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 28 October 2026 10 min read
On this page

IAM role trust policies decide who outside your account can become a principal inside it, and a missing external ID or source condition lets a trusted vendor or AWS service be tricked into acting for someone else. This guide is a role-by-role review method for AWS cross-account trust: export every trust policy, classify each trusted principal, check for the conditions AWS recommends against the confused deputy problem, use IAM Access Analyzer to confirm what is reachable from outside, and fix policies without cutting off legitimate integrations. It is for cloud security engineers, platform teams and anyone approving third-party access to AWS. Design patterns for cross-account and cross-tenant access are covered in the Cross-Account and Cross-Tenant Access Guide; this page is the audit.

Key takeaways

  • Two different confused deputies: cross-account (a third party with a role in many customer accounts is tricked into using yours) is fixed with sts:ExternalId; cross-service (an AWS service principal acting for another customer) is fixed with aws:SourceArn, aws:SourceAccount, aws:SourceOrgID or aws:SourceOrgPaths.
  • The external ID belongs to the vendor: AWS states it must be generated by the third party, unique per customer, and is not a secret.
  • Trusting an account root trusts its admins: AWS notes that using the account ARN does not limit access to the root user; the other account's administrators decide which of their identities can assume your role.
  • Wildcard principals are the worst case: AWS strongly recommends against "*" in role trust policies without restrictive conditions, because they let other principals become principals in your account.
  • Access Analyzer shows reachability, not intent: it flags roles accessible from outside your zone of trust whether or not they were used, so every finding still needs an owner decision.

When you need this

  • Third-party onboarding or renewal: monitoring, cost, backup and security vendors almost always ask for a cross-account role. See the Third-Party Access Guide.
  • Periodic access review: roles created for vendors persist long after contracts end, and IAM Access Analyzer external access findings stay Active until you remove the access or archive them.
  • After a supplier incident: when a vendor holding roles in many customer accounts is compromised, you need to know exactly which of your roles it can assume and with what permissions.
  • Organisation changes: mergers, account moves between organisations and new organisational units change what counts as inside your zone of trust.
  • Before relying on service principal access: S3 bucket, SNS, SQS and KMS policies that grant AWS services access are where cross-service confused deputy conditions are most often missing.

Before you start

  • Access: read-only IAM in each account (for example a security audit role), plus administrator access to IAM Access Analyzer in the delegated administrator account if you use AWS Organizations.
  • Account map: a list of your own account IDs and organisation ID, so you can tell internal from external principals.
  • Vendor register: the AWS account IDs your approved vendors publish, with contract owners.
  • CloudTrail: organisation trail with management events, so you can see AssumeRole calls into each role.
  • Change process: trust policy edits take effect quickly and can cut off production integrations; agree a window and a vendor contact for each change.

Step-by-step

1. Export every trust policy

  1. In each account, export roles with their trust policies, for example with aws iam get-account-authorization-details --filter Role, which returns each role's AssumeRolePolicyDocument. Save the JSON per account.
  2. Exclude service-linked roles from vendor review (they are managed by AWS) but keep them in the inventory.
  3. Extract every Principal value and every Condition block into a table: account, role name, principal type (AWS, Service, Federated), principal value, conditions present, attached permission policies.

2. Classify each trusted principal

Principal in trust policyWhat it meansRequired control
Your own account or a role in your organisationInternal cross-account accessSpecific role ARNs; consider aws:PrincipalOrgID or path conditions
External account root (arn:aws:iam::<id>:root or bare account ID)Any identity the other account's admins permitsts:ExternalId for vendors; a specific role ARN where the vendor publishes one
Specific external role ARNOne role in the other accountsts:ExternalId if the vendor is multi-tenant
"*"Anyone in any accountRestrictive conditions at minimum; normally a critical finding
Service principal (service-name.amazonaws.com)An AWS service acting on behalf of some resourceaws:SourceArn or aws:SourceAccount where the service supports them
Federated (OIDC or SAML provider)Tokens from an external identity providerAudience and subject conditions; see How to set up workload identity federation for GitHub Actions to AWS
Raw principal ID (for example starting AROA) instead of an ARNThe trusted role was deleted; AWS cannot map the ID backRemove, or replace with the correct ARN if the access is still needed

The last row matters: AWS converts a role ARN in a trust policy to the role's unique principal ID when you save it, so deleting and recreating the trusted role breaks the trust and leaves an orphaned ID in your policy.

3. Check cross-account trusts for the external ID

  1. For every external account principal that belongs to a vendor serving many customers, confirm the trust policy has "StringEquals": {"sts:ExternalId": "..."}.
  2. Confirm the value came from the vendor and is unique to you. AWS recommends one external ID per AWS account in multi-tenant setups, generated by the third party as a random string, and states it must be generated by the vendor and not by customers.
  3. Check format: AWS requires 2 to 1,224 characters, alphanumeric without white space, plus the symbols + = , . @ : / -.
  4. Do not treat it as a secret or rotate it as one. AWS says it is not a secret and anyone who can view the role can see it.
  5. Ask the vendor whether they test your role both with and without the external ID. AWS advises vendors not to store a customer role ARN if it can be assumed without the correct external ID.

4. Check service principal grants for source conditions

  1. Search trust policies and resource policies (S3, SNS, SQS, KMS, Lambda) for "Service": principals.
  2. For each, confirm one of the AWS-recommended keys is present: aws:SourceArn for a specific resource (such as one CloudTrail trail), aws:SourceAccount for a specific account, or aws:SourceOrgID or aws:SourceOrgPaths for your organisation.
  3. Check the service's own documentation: AWS notes that support for these keys and any service-specific mechanisms vary by service.
  4. Where many resources need the same protection, consider resource control policies (RCPs), which AWS describes as a way to apply cross-service confused deputy controls centrally with aws:SourceOrgID and aws:SourceOrgPaths.

5. Confirm external reachability with IAM Access Analyzer

  1. Create an external access analyzer with your organisation (or account) as the zone of trust. For IAM roles, Access Analyzer analyses trust policies and generates a finding for roles that an entity outside the zone of trust can access. Because roles are global, a finding appears in each enabled Region.
  2. Reconcile findings with your table from step 2. Every external principal should appear in the vendor register.
  3. Note that findings report access the policy allows regardless of whether it was used; Access Analyzer does not examine access logs.
  4. Run an unused access analyzer too: it flags roles inactive for a number of days you choose, which identifies vendor roles nobody is using (service-linked roles are not analysed).
  5. Archive only with a recorded reason, and prefer archive rules scoped to specific vendor account IDs over broad rules.

6. Check actual use and permissions

  • Who assumes it: search CloudTrail for AssumeRole events against each role ARN and record the calling account and source IP ranges.
  • What it can do: read attached permission policies. A vendor read-only role with iam:PassRole, write access to logging or broad * actions is a finding even if the trust policy is perfect.
  • Session duration: record the role's maximum session duration and reduce it where the vendor does not need long sessions.

Verify it worked

MetricSourceTarget
Vendor roles without sts:ExternalIdTrust policy tableZero for multi-tenant vendors
Service principal grants without source conditionsPolicy searchZero where the service supports the keys
Roles trusting "*"Trust policy table and Access AnalyzerZero
Active external access findings without an ownerAccess AnalyzerZero
Unused external rolesUnused access analyzerZero after each review
Orphaned principal IDs in trust policiesTrust policy tableZero

After each fix, Access Analyzer should move the finding to Resolved (AWS says findings may take up to 30 minutes to update after a policy change). Ask the vendor to run their connection test and check CloudTrail for successful AssumeRole calls from their account.

Rollback and common errors

  • Adding an external ID the vendor does not send: their AssumeRole calls start failing. Agree the value and the vendor's change date first; rollback is restoring the previous trust policy, so save it before editing.
  • Using your own value as the external ID: it defeats the control, because uniqueness across the vendor's customers is what prevents the confused deputy. Use the vendor-issued value.
  • Replacing account root with a specific role ARN that is later recreated: the trust breaks because the stored principal ID no longer matches. If the vendor recreates roles, AWS documents using aws:PrincipalArn in a condition, which is not converted to an ID.
  • Treating service principals as safe: without aws:SourceArn or aws:SourceAccount, a grant to a service principal can be used by another customer's resource of the same service.
  • Archiving findings in bulk: a broad archive rule hides new risky trusts to the same account. Scope rules narrowly and review them.
  • Fixing trust but ignoring permissions: a correctly trusted role with administrator permissions is still the biggest blast radius in the account.

Hardening afterwards

  • Codify trust policies: manage vendor roles in infrastructure as code with a review rule that rejects external principals without sts:ExternalId and service principals without source conditions. See the Terraform and IaC Pipeline Credential Security Guide.
  • Check policies in CI: use Access Analyzer policy validation and custom policy checks such as CheckNoPublicAccess before deployment.
  • Apply organisation guardrails: resource control policies for service principal access, and service control policies that restrict who can edit role trust policies.
  • Alert on trust changes: monitor UpdateAssumeRolePolicy and CreateRole events and new Access Analyzer findings. See the AWS CloudTrail Guide.
  • Offboard vendors fully: delete the role, not just the contract. See the NHI Offboarding and Decommissioning Guide.
FrameworkReferenceRelevance
NIST CSF 2.0PR.AA-05, GV.SC-07Least privilege and access review; supplier risk understood and monitored
NIST SP 800-53 Rev 5AC-2, AC-3, AC-6, SA-9Account review, access enforcement, least privilege, external system services
CIS Controls v8.1Controls 6 and 15Access control management and service provider management
ISO/IEC 27001:2022 Annex AA.5.15, A.5.19, A.8.2Access control, supplier relationships, privileged access
MITRE ATT&CKT1199, T1078.004, T1484.002Trusted relationship, cloud accounts, trust modification

Practitioner checklist

  • Export every role trust policy in every account and tabulate principals and conditions.
  • Map each external account ID to an approved vendor and owner.
  • Require vendor-issued, per-customer sts:ExternalId on every multi-tenant vendor role.
  • Add aws:SourceArn, aws:SourceAccount or organisation source keys to service principal grants.
  • Remove "*" principals and orphaned principal IDs.
  • Run external and unused access analyzers and resolve or justify every finding.
  • Review the permissions and session duration of each externally trusted role.
  • Alert on trust policy changes and new external access findings.

Standards and references

Related NHI Mgmt Group resources: Cross-Account and Cross-Tenant Access Guide · Confused Deputy in AI Agents Guide · Third-Party Access Guide · NHI Offboarding and Decommissioning 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 28 October 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.