AWS IAM Support
Fixing cross-account AssumeRole errors.
Cross-account access needs two things to agree: the target role's trust policy must allow the caller, and the caller must be allowed to call sts:AssumeRole on that role. When either is missing you get "not authorized to perform sts:AssumeRole". We check both sides.
When You Need This
The situations where this work pays for itself.
Signs it is time
- You see "User is not authorized to perform: sts:AssumeRole on resource"
- A pipeline or Lambda cannot deploy to another account
- Role chaining fails or sessions expire early
- A third-party tool cannot assume your role
- Assume role works from the CLI but not from code
What you get
- Corrected trust and permission policies in infrastructure as code
- A cross-account access diagram
- CloudTrail queries to audit AssumeRole use
- Hardening recommendations such as external IDs and conditions
How we do it
A clear, safe process you can follow along with.
1. Identify caller and target exactly
We run aws sts get-caller-identity from the failing environment to see the real calling principal, which is often not who people assume, then note the target role ARN and account.
2. Check the target trust policy
The role's trust policy must name the caller account or specific principal in Principal, with the action sts:AssumeRole. A recreated role invalidates trust that referred to the deleted role's unique ID.
3. Check the caller's permissions
In the caller's account, the identity needs an allow for sts:AssumeRole on the target ARN, and nothing may deny it through a permissions boundary or SCP.
4. Review conditions
Trust policy conditions can require an ExternalId, MFA, an organization ID, source identity or a particular session name. We compare each with what the caller actually sends.
5. Check role chaining and duration
When one assumed role assumes another, the session is limited to one hour, and requesting a longer duration fails. Maximum session duration must also be raised on the target role if needed.
6. Test, verify in CloudTrail, harden
We retest the assume call and confirm AssumeRole events in both accounts' CloudTrail. We then tighten trust to specific roles instead of whole accounts.
Mistakes we help you avoid
Common ways this goes wrong, and what we do instead.
Trusting the account root
It allows any principal in that account with permission, which is broader than intended.
Fixing only one side
Both the trust policy and the caller's policy must allow it.
Hard-coding the external ID in public code
Treat it as an identifier for confused deputy protection, and generate a unique one per customer.
Expecting long chained sessions
Chained role sessions are capped at one hour.
Frequently Asked Questions
Why do I get "not authorized to perform sts:AssumeRole"?
Either the caller's own policy lacks sts:AssumeRole on the role, or the target role's trust policy does not trust the caller. A condition mismatch can cause it too.
What is an external ID in AssumeRole?
It is a value the assuming party must supply, used to prevent the confused deputy problem when a third party accesses your account on behalf of many customers.
Why does my role session expire after an hour?
Role chaining limits the session to one hour. For longer, assume the role directly from the original identity and set the role's maximum session duration.
Want Help With Fixing cross-account AssumeRole errors?
Schedule an appointment. Tell us about your environment and we will outline the safest, highest-value approach.
Schedule Appointment › No commitment required