
本文详解跨账户 iam 角色扮演失败的核心原因——信任策略(trust policy)中 principal 配置错误,并提供可落地的策略修正、代码验证及安全实践建议。
本文详解跨账户 iam 角色扮演失败的核心原因——信任策略(trust policy)中 principal 配置错误,并提供可落地的策略修正、代码验证及安全实践建议。
在 AWS 多账户架构中,通过 sts:AssumeRole 实现跨账户权限委派是常见且推荐的安全实践。但实践中,开发者常因对“信任关系”的双向性理解偏差,导致看似配置完备却持续返回 403 AccessDenied 错误——如错误信息所示:
User: arn:aws:sts::
:assumed-role/ /... is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam:: :role/my-query-role
该错误并非源于 Account 1 的权限策略(Permissions Policy)缺失(您已正确授予 sts:AssumeRole),而是 Account 2 中目标角色 my-query-role 的信任策略未准确识别发起方身份。
? 关键原理:信任必须精确匹配“实际调用者”ARN
当使用 WebIdentityTokenFileCredentialsProvider(典型于 EKS Pod IAM Roles for Service Accounts, IRSA 场景)获取临时凭证后,再调用 AssumeRole,其实际调用主体并非原始 IAM Role ARN,而是由 STS 动态生成的 assumed-role ARN,格式为:
arn:aws:sts::
而您当前的信任策略中指定的是:
"Principal": { "AWS": ["arn:aws:iam::<account_1_id>:root"] }</account_1_id>
这仅允许 Account 1 的根账户(即整个账户) 扮演该角色,但不包含任何由该账户内角色派生的会话身份。STS 的策略评估严格比对 Principal 字段,arn:aws:iam::123456789012:root ≠ arn:aws:sts::123456789012:assumed-role/account-1-role/xyz。
✅ 正确做法是:在 Account 2 的 my-query-role 信任策略中,明确列出 Account 1 中具体可扮演该角色的 IAM Role ARN:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::<account_1_id>:role/account-1-role"
]
},
"Action": "sts:AssumeRole"
}
]
}</account_1_id>
⚠️ 注意:此处必须使用 arn:aws:iam::...:role/... 格式(即原始角色 ARN),而非 arn:aws:sts::...:assumed-role/...。AWS 在评估 AssumeRole 请求时,会将传入的 assumed-role ARN 自动映射回其源 IAM Role,并与信任策略中的 Principal.AWS 列表进行匹配。
✅ 验证与最佳实践
1. 权限策略(Account 1)保持不变(已正确)
您的 Account 1 角色权限策略无需修改,它已正确授权调用 sts:AssumeRole:
{
"Version": "2012-10-17",
"Statement": [{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": "arn:aws:iam::<account_2_id>:role/my-query-role"
}]
}</account_2_id>
2. Java SDK 调用逻辑无误(关键点确认)
您的 Java 代码结构正确,但需确保 roleSessionName 具备唯一性和可追溯性:
AssumeRoleRequest assumeRoleRequest = AssumeRoleRequest.builder()
.roleArn("arn:aws:iam::<account_2_id>:role/my-query-role")
.roleSessionName("cross-account-query-session-" + System.currentTimeMillis()) // 建议加入时间戳或唯一ID
.build();</account_2_id>
3. 进阶加固:限制信任范围(强烈推荐)
为最小化权限,避免使用宽泛的 :root 或全账户角色,可进一步限定信任来源:
- ✅ 指定具体角色 ARN(如上所示)
- ✅ 添加条件约束(例如限定来源 IP、MFA 状态):
"Condition": { "StringEquals": { "aws:RequestedRegion": "eu-west-1" } }
4. 排查工具辅助
- 使用 AWS IAM Policy Simulator 模拟 sts:AssumeRole 请求,输入 assumed-role ARN 和目标角色 ARN,直观验证策略效果。
- 启用 CloudTrail 日志,搜索 AssumeRole 事件,检查 errorMessage 和 userIdentity.arn 字段,精准定位拒绝原因。
? 总结
跨账户 AssumeRole 失败的根源,90% 以上集中于目标角色的信任策略(Trust Policy)配置不当。请始终牢记:
? 信任策略定义“谁被允许来”,必须精确匹配调用方的 源身份(即原始 IAM Role ARN);
? 权限策略定义“谁能去调用”,控制发起方的 API 调用能力;
? assumed-role ARN 是临时会话标识,不是信任策略中应直接填写的 Principal。
修正信任策略后,无需重启服务或刷新凭证,变更立即生效。这是 AWS 权限模型中“最小权限”与“精确信任”的典型体现,也是构建安全、可审计多账户环境的基石。










