AWS跨账号STS角色会话AssumeRole权限拒绝问题解决
跨账号STS角色会话访问Secrets Manager权限拒绝问题
问题背景
我有账号A,服务使用的角色会话ARN为 arn:aws:sts::{account-A}:assumed-role/Worker...,需要访问账号B的Secrets Manager。账号B已创建具备Secrets Manager访问权限的角色,但账号A的Worker角色会话尝试扮演该角色时被拒绝。
相关代码
// 在arn:aws:sts::{account-A}:assumed-role/Worker{hashID}上下文下获取账号B的角色 async function assumeCrossAccountRole(accountId: string) { const sts = new STS(); const RoleArn = `arn:aws:iam::${accountId}:role/SecretsManagerRole`; // 账号B的角色ARN const testAWS = await sts .assumeRole({ RoleArn, RoleSessionName: 'CrossAccountSession' }) .promise(); const credentials: CredentialsOptions = { accessKeyId: testAWS.Credentials.AccessKeyId, secretAccessKey: testAWS.Credentials.SecretAccessKey, sessionToken: testAWS.Credentials.SessionToken, }; return credentials; // 原代码遗漏return,会导致后续credentials为undefined } // 使用扮演的角色访问Secrets Manager const credentials = await assumeCrossAccountRole(config.env.account); const secretsManager = new SecretsManager({ region, credentials });
当前配置的策略
账号B的SecretsManagerRole信任策略
{ "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": ["sts:AssumeRole"], "Condition": { "ForAnyValue:StringLike": { "aws:PrincipalArn": [ "arn:aws:sts::{account-A}:assumed-role/Worker*", "arn:aws:sts::{account-A}:assumed-role/Invoker*" ] } } }
账号A的Worker角色信任策略
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ecs-tasks.amazonaws.com" }, "Action": "sts:AssumeRole" }, { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
问题原因与修复方案
1. 修正账号B信任策略的条件匹配逻辑
当STS角色会话发起sts:AssumeRole请求时,aws:PrincipalArn对应的是账号A中Worker角色的ARN(而非STS会话ARN)。当前用STS会话ARN做匹配,导致策略不生效。
修改账号B的SecretsManagerRole信任策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::{account-A}:role/Worker" // 替换{account-A}为实际账号ID }, "Action": "sts:AssumeRole" } ] }
如果需要匹配多个角色,可直接添加多个ARN:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::{account-A}:role/Worker", "arn:aws:iam::{account-A}:role/Invoker" ] }, "Action": "sts:AssumeRole" } ] }
若Worker角色有带后缀的实例,可用通配符匹配:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "sts:AssumeRole", "Condition": { "StringLike": { "aws:PrincipalArn": [ "arn:aws:iam::{account-A}:role/Worker*", "arn:aws:iam::{account-A}:role/Invoker*" ] } } } ] }
2. 给账号A的Worker角色添加跨账号扮演权限
账号A的Worker角色当前仅允许ECS/Lambda服务扮演它,但本身没有权限调用sts:AssumeRole访问账号B的角色。需添加如下权限策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::{account-B}:role/SecretsManagerRole" // 替换{account-B}为实际账号ID } ] }
3. 修复代码遗漏
原assumeCrossAccountRole函数未返回credentials,会导致后续访问凭证为undefined,需添加return credentials;(如代码示例中已修正)。
验证步骤
- 确认账号A的Worker角色已配置
sts:AssumeRole权限,资源指向账号B的SecretsManagerRole ARN。 - 确认账号B的SecretsManagerRole信任策略正确引用了账号A的Worker角色ARN或通配符匹配。
- 运行代码测试,检查是否能成功获取凭证并访问Secrets Manager。
内容的提问来源于stack exchange,提问作者Noble Dinasaur
相关产品推荐
相关产品推荐

