Introducing Trust Policy Support In Cloudsplaining

September 24, 2025
-
Brian Henderson

Cloudsplaining is an AWS Identity and Access Management (IAM) Security Assessment tool that identifies least privilege violations in your AWS environments. Until now, Cloudsplaining has focused solely on what a user, group, or role is allowed to do via managed and inline policies. Our fork introduces trust policy support to gain visibility into who can assume a role and identify roles that are overly permissive.

What Are Trust Policies And Why Visibility Matters

In AWS IAM, a role’s identity policy defines what that role is allowed to do, while the trust policy (the AssumeRole policy) defines which principals are allowed to become that role. Most security programs obsess over the first and under-invest in the second. That imbalance can lead to privilege escalation, lateral movement, and cross-account compromise.

Trust policies are defined in JSON documents attached to IAM roles and are visible in the AWS console under the “Trust Relationships” tab of a role. The Principal element of these policies can name AWS accounts, IAM users or roles, federated IdPs, AWS services, or a wildcard (*).  Here are a few things to keep in mind:

  • Wildcard principals: "Principal": "*" or account-root ARNs like arn:aws:iam::*:root lets anyone with access to any AWS principal attempt to assume the role. If you absolutely must do this, it should be paired with tight condition guards like aws:PrincipalOrgId.
  • External account principals: Trusting another AWS account (e.g., arn:aws:iam::111122223333:role/TheirRole or arn:aws:iam::111122223333:root) enables cross-account access. Without safeguards like external ID or organization scoping, these become pivot points for vulnerable or compromised third parties.
  • Service principals: EC2/ECS/EKS/Lambda trusts (e.g., ec2.amazonaws.com) are normal for instance profiles and execution roles. But if an attacker can launch or compromise compute resources in your account, they can reach any role those services can assume.

Why this Matters

In order to surface escalation paths before an attacker does you need a map of which principals can assume which roles. Visibility into your trust relationships can help you:

  1. Detect escalation chains by building a role-trust graph to spot “A ⇒ B ⇒ Admin” hops.
  2. Catch unintended access by flagging roles assumable by principals outside your org.
  3. Guard against drift by implementing continuous scanning. Trusts change over time; continuous scanning keeps surprises out.
  4. Validate conditions by confirming sts:ExternalId, aws:PrincipalOrgID, aws:SourceArn, etc., are present and correct.
  5. Speed incident response times by having a deeper understanding of your environment. When a key leaks, quickly answer “Which roles could this principal pivot into?”

Example: A seemingly harmless DataExportRole with read-only access to an S3 bucket becomes a data leak if its trust policy allows "Principal": "*". Anyone with an AWS account can export data from that bucket.

What Changed In Cloudsplaining?

Cloudsplaining now analyzes trust policies alongside identity policies with the introduction of a new CLI flag that includes trust checks in JSON reports:

cloudsplaining scan --input-file default.json \  
--exclusions-file exclusions.yml \  
--flag-trust-policies \  
--output results/

With this flag enabled, each role includes new AssumableBy* indicators:

  • AssumableByAnyPrincipal: The trust is effectively open to everyone (* or any account root). This is a big red flag.
  • AssumableByAnyPrincipalWithConditions: Wildcard with conditions. This is common, but deserves scrutiny to ensure the conditions limit access as expected.
  • AssumableByComputeServices: The role is assumable by AWS compute (EC2/ECS/EKS/Lambda). Useful context but becomes risky if an attacker can run code on those compute resources.
  • AssumableByCrossAccountPrincipal: The role trusts principals in other AWS accounts. Great for spotting unintended third-party access.

Sample JSON output:

{
 "roles: {
   "AROA2NRZ4P2YROLEID": {
     "name": "ExampleRoleName",
     ...
     "AssumableByAnyPrincipal": ["*", arn:aws:iam::*:root],
     "AssumableByCrossAccountPrincipal": [
       "arn:aws:iam::111122223333:role/TheirRole"
     ]
   }
 }
}

Note: You can tune noise with the exclusions file by populating a known-accounts list that will suppress expected cross-account findings (e.g. your accounts or vetted vendors). This will allow Cloudsplaining to focus on unknowns.

What To Do Next

Bring trust policy visibility into your scanning and automation platform to help close blind spots into who can become what. The new `AssumableBy*` findings transform opaque JSON documents into actionable indicators that should be triaged in this order:

  1. Eliminate AssumableByAnyPrincipal immediately.
  2. Tighten AssumableByAnyPrincipalWithConditions or replace the wildcard entirely.
  3. Harden cross-account trusts with ExternalId and/or PrincipalOrgID; keep the allowlist short.
  4. Scope compute-service trusts with SourceArn/SourceAccount and prune anything unused.

Update the roles’ trust policies, re-run Cloudsplaining, and add these checks into your provisioning flow so bad trusts will never make it to production. Once you operationalize these items you significantly reduce the potential for lateral movement and strengthen your overall identity resilience.

How to Remediate These Findings

  • AssumableByAnyPrincipal: Any principal can assume the role; no guarding conditions.
    • Risk: Critical
    • Recommended Remediation: Replace * with explicit principals. If a wildcard is unavoidable, add strict conditions (IP allowlists, aws:PrincipalOrgID, MFA constraints).
  • AssumableByAnyPrincipalWithConditions: Wildcard trust exists but is gated by Condition..
    • Risk: Medium
    • Recommended Remediation: Review and harden conditions. Whenever possible, replace the wildcard with specific principals and keep conditions as defense-in-depth.
  • AssumableByComputeServices: Role can be assumed by EC2/ECS/EKS/Lambda.
    • Risk: Low
    • Recommended Remediation: Limit to only required services/resources. Add scoping conditions like aws:SourceArn / aws:SourceAccount. Remove unneeded service principals.
  • AssumableByCrossAccountPrincipal: Principals in other AWS accounts can assume the role.
    • Risk: Medium
    • Recommended Remediation: Remove if unnecessary. If needed, require sts:ExternalId and/or constrain via aws:PrincipalOrgID to your org. Keep the trust specific.

About the Author

Brian Henderson is a Principal Engineer at Cloud Security Partners and has dedicated his 20-year career to cybersecurity, gaining expertise across offensive and defensive security. He began with a focus on application and penetration testing before transitioning to securing cloud infrastructures for both startups and enterprises. In addition to his security expertise, Brian has recently worked as a software engineer, developing enterprise cloud security solutions, leading engineering teams, managing people, shaping product direction, and maintaining strong customer relationships. His broad experience allows him to bridge the gap between security, engineering, and business needs.

Stay in the loop.
Subscribe for the latest in AI, Security, Cloud, and more—straight to your inbox.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Back to blogs