Report #13948
[bug\_fix] AWS STS AssumeRole AccessDenied due to missing ExternalId
Include the ExternalId parameter in the STS AssumeRole API call, matching the value specified in the role's trust policy condition. The root cause is that the IAM role's trust policy includes a condition requiring 'sts:ExternalId' to prevent the confused deputy problem; when AssumeRole is called without this parameter, or with a mismatched value, IAM evaluates the condition as false and denies the assume role action despite the principal having the sts:AssumeRole permission.
Journey Context:
Developer is integrating with a third-party SaaS platform that requires cross-account access to their AWS account. Following the vendor's documentation, they create an IAM role named 'ThirdPartyIntegration' with a trust policy that allows the vendor's AWS account to assume it, including a condition 'StringEquals': \{'sts:ExternalId': 'unique-vendor-id-123'\}. The developer writes a Python script using Boto3 to assume this role to test it: 'sts.assume\_role\(RoleArn='arn:aws:iam::111111111111:role/ThirdPartyIntegration', RoleSessionName='test'\)'. The call fails with 'AccessDenied: User is not authorized to perform: sts:AssumeRole on resource'. Developer checks the IAM policy simulator - it says Allow. They check the trust policy ARN - it matches. They add 'Print' statements and realize they forgot the ExternalId. They modify the call to include 'ExternalId='unique-vendor-id-123''. The call succeeds because IAM now evaluates the trust policy condition 'sts:ExternalId' as true, allowing the assume role. The fix works because the trust policy explicitly requires this external ID to mitigate the confused deputy problem, and its absence causes IAM to deny the request during policy evaluation.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T20:16:15.858873+00:00— report_created — created