table of contents
are you looking for a talent to recruit?

discover how we help you!

An AWS IAM trust policy decides who can assume a role. When that trust reaches another account, the blast radius can grow fast, especially if the policy is broad or missing conditions.

Cross-account trust is useful for vendors, shared services, and centralized security teams. It also creates a path for a less-trusted account to step into a more-sensitive one, which is why audits need to focus on the trust policy, not only the permission policy.

Start with the role’s trust document, then compare it with the real access pattern. The gaps usually show up quickly.

Contents

What AWS IAM trust policies control in cross-account access

A trust policy lives on an IAM role. It tells AWS which principals can call sts:AssumeRole and obtain temporary credentials. The permission policy on that role then decides what those temporary credentials can do.

That split matters. A role can have a very tight permission policy and still be risky if the trust policy accepts the wrong principal. A broad trust policy is like handing out a key before checking the lock.

AWS recommends using conditions to narrow access and using IAM Access Analyzer to verify public and cross-account exposure in its IAM best practices guide. That guidance lines up with what auditors see in real environments. The biggest mistakes usually come from vague principals, missing conditions, and roles that survive long after their original purpose.

Cross-account access appears in a few common forms. Sometimes a vendor assumes a role in your account. Sometimes one AWS account in your organization reaches into another. Sometimes a service, such as EventBridge or Lambda, needs to assume a role on your behalf. Each case needs a different trust pattern.

A trust policy that accepts a whole account gives every principal in that account a path to your role.

A minimalist digital illustration featuring interconnected nodes and abstract shields representing cloud accounts. Crisp lines and bold green accents highlight secure data pathways against a stark, clean white background environment.

How to read AWS IAM trust policies before you audit them

A trust policy review starts with three questions. Who is trusted? What action is allowed? Which conditions limit that trust?

A broad trust policy often looks like this:

{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::111122223333:root"},"Action":"sts:AssumeRole"}]}

That policy trusts every identity in the external account. It may be acceptable in rare cases, but it should always trigger a deeper review.

A tighter version names one role and adds conditions:

{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::111122223333:role/vendor-ci"},"Action":"sts:AssumeRole","Condition":{"StringEquals":{"sts:ExternalId":"ops-72f4","aws:PrincipalOrgID":"o-a1b2c3d4"}}}]}

This is easier to reason about. It ties trust to one role, one external relationship, and one organization boundary.

The details matter. Principal tells you who can try. Action should usually be sts:AssumeRole for role assumption. Condition is where the real limits live. For service-linked access, aws:SourceArn and aws:SourceAccount often matter more than a raw account ID. For federated or vendor access, sts:ExternalId, aws:PrincipalArn, aws:PrincipalOrgID, and aws:PrincipalTag are common control points.

The AWS Security Blog has a useful overview of four ways to grant cross-account access in AWS. That context helps when the same use case could be solved with a role, a resource policy, or a different trust pattern.

Trust policy elementWhat to inspectRed flag
PrincipalOne specific role, service, or account?*, account root, or many unrelated principals
ActionIs the role assumed through the expected STS action?Extra actions or mixed access paths
ConditionAre ExternalId, SourceArn, SourceAccount, or PrincipalOrgID present where needed?Missing or weak condition keys
ScopeDoes the role serve one job?Shared use across teams, apps, or vendors

That table gives you a fast triage path. If the trust names a wide audience and adds few conditions, treat it as high risk.

Practical steps for auditing trust policies in AWS

Start with inventory. Export every IAM role trust policy across all accounts, including roles managed through IaC. If the role only exists in a template, it still matters. Drift and copy-paste often create the worst surprises.

Next, sort roles by who they trust. Put whole-account trusts, third-party trusts, and any Principal: "*", first. Then separate internal cross-account roles from service roles. That simple grouping makes patterns easier to see. If one vendor account appears in 20 roles, you may be looking at role sprawl rather than a true need.

The next pass is about conditions. Check whether each external trust has a reason to exist and a control to match that reason. For vendors, that usually means a unique ExternalId. For service principals, it often means SourceArn and SourceAccount. For trust inside your AWS Organization, aws:PrincipalOrgID can help, but it should not become a substitute for proper role scoping.

Then compare the policy to actual use. CloudTrail AssumeRole events show which accounts and roles are using the trust path. If a role has no activity for 90 days, ask why it still exists. Stale trust is still trust. Unused roles are easy to forget and easy to abuse later.

IAM Access Analyzer is also worth a pass because it finds external access paths you may have missed. AWS calls out analyzer-based review in its IAM best practices documentation, and that fits well with a recurring audit cycle. Use analyzer findings as a starting point, then confirm each one against the business owner and the actual runtime behavior.

A stylized figure holds a large magnifying glass over a document, highlighting specific sections with a vibrant green glow. Clean geometric shapes and professional lines maintain a minimalist aesthetic throughout.

A final check belongs on the caller side. Cross-account access needs two halves. The trust policy on the target role must allow assumption, and the caller must have permission to call sts:AssumeRole. Auditing only one side gives you a false sense of safety.

Red flags in AWS IAM trust policies

Some trust policies need immediate attention. These are the ones that show up again and again in incident reviews and internal audits.

  • Wildcard principals: Principal: "*" is almost always too broad. It opens the door wider than most teams expect.
  • Account root trust: Trusting arn:aws:iam::123456789012:root gives every identity in that account a path to your role.
  • Missing condition keys: If the role is for a vendor, a service, or a specific org boundary, the policy should usually include a narrowing condition.
  • Overly broad ExternalId values: A shared, guessable, or reused ExternalId weakens the protection it is supposed to provide.
  • Confused deputy risk: Third-party access without a unique ExternalId lets the vendor’s own credentials get mixed up across customers.
  • Unused roles: A role that nobody assumes anymore can still be assumed tomorrow if the trust policy stays open.
  • Third-party access with no owner: If nobody knows who approved the vendor, the trust path is already out of control.
  • Organization boundary issues: Trust that relies on aws:PrincipalOrgID without checking the role scope can still be wider than it should be.

A helpful way to think about it is simple. If the policy trusts an account, a vendor, or an org without saying why and how, the risk is probably too high.

Broad trust is often invisible until someone maps every principal that can use it.

For a good overview of the ways teams misread cross-account access, see common cross-account trust mistakes. The core lesson is consistent. The trust policy is the control surface, and broad language there deserves scrutiny.

Remediating AWS IAM trust policies that are too broad

Fixing a weak trust policy usually means narrowing the principal, adding conditions, or splitting the role into smaller pieces. The right fix depends on the reason the trust exists in the first place.

Risk foundBetter patternWhat it changes
Whole-account trustTrust a specific role ARNLimits assumption to one known workload
Vendor access without ExternalIdRequire a unique ExternalId per tenant or customerReduces confused deputy risk
Service principal without source controlsAdd aws:SourceArn and aws:SourceAccountTies trust to one service resource
Org-wide trust with no reviewAdd aws:PrincipalOrgID and confirm the business needKeeps trust inside the org boundary
Shared role for many usesSplit roles by application, team, or pipelineShrinks the blast radius
Stale role with no usageRemove the role or disable the trust pathCuts dead access paths

When possible, trust one role instead of one whole account. Use the narrowest condition keys that fit the use case. Keep the role names clear, so future reviewers can see why the trust exists.

AWS Organizations can help here, but it should not hide the risk. An account inside your org is still a separate security boundary. Pair role review with SCP review so a broad trust in one account does not become the easiest path around your controls.

If your estate has inherited vendor access, shared pipelines, and old cross-account roles, a focused review can save a lot of time. Book a Discovery Call with Bud Consulting if you want a second set of eyes on the highest-risk trust paths.

Concise audit checklist

Use this checklist during a review or as part of a recurring control.

  1. Export every role trust policy from every account.
  2. Flag any role that trusts another account, a vendor, or a wildcard principal.
  3. Check whether the Principal is one role, one account, or many.
  4. Verify the right condition keys are present, such as ExternalId, PrincipalOrgID, SourceArn, or SourceAccount.
  5. Review CloudTrail AssumeRole activity for the last 30, 60, or 90 days.
  6. Confirm the role is still needed and has a named owner.
  7. Compare the trust policy with Access Analyzer findings.
  8. Remove or narrow anything undocumented, unused, or broader than the use case.

If a role fails two or more of those checks, it belongs on the remediation list.

Conclusion

Cross-account trust gets risky when the policy says more than the business need. The most dangerous roles are often the ones that look ordinary, especially when they trust a whole account or skip a key condition.

A good audit checks the trust policy, the caller side, CloudTrail activity, and analyzer findings together. That gives you a clear view of who can assume the role and why.

If you tighten the principal, add the right conditions, and retire stale roles, you cut the risk without slowing down legitimate work. That is the real goal of reviewing AWS IAM trust policies.

FAQ

What is the difference between a trust policy and a permission policy?

A trust policy decides who can assume a role. A permission policy decides what the role can do after assumption. Both matter, because a tight permission policy does not fix a broad trust policy. For cross-account access, the trust side is often where the larger risk lives.

When should sts:ExternalId be required?

Use sts:ExternalId when a third party assumes a role in your account. It helps reduce confused deputy risk by tying the request to a value that the vendor should know, and outsiders should not guess. Each customer or tenant should usually have a unique value.

Is aws:PrincipalOrgID enough for cross-account trust?

No. It helps define an organization boundary, but it can still be too broad if many accounts in the org can assume the role. Combine it with a specific role ARN, a clear business owner, and the smallest permission set you can manage.

How often should trust policies be audited?

Audit them when they are created, when they change, and on a regular schedule after that. Many teams use monthly or quarterly reviews for high-risk roles, plus event-driven reviews after vendor changes, account merges, or org restructures. CloudTrail and Access Analyzer can keep the review cycle honest.

Can IAM Access Analyzer replace manual review?

No. It is a strong first pass, but it won’t tell you whether the access is still business-approved or whether the role should exist at all. Manual review is still needed to confirm intent, document ownership, and retire old trust paths that analyzer can still see.

post tags :

Leave A Comment