Lambda调用sts:AssumeRole时遇AccessDenied错误,请求排查
问题:Lambda执行sts:AssumeRole返回AccessDenied错误
使用AWS CDK创建栈,包含一个供Lambda运行时扮演的IAM角色,以及已添加sts:AssumeRole权限的Lambda函数,但执行Lambda时始终返回AccessDenied错误。
相关代码
Lambda基础设施代码
const roleAssumedInLambdaRunTime = new Role(this, "GrantS3AccessRole", { assumedBy: new ServicePrincipal("lambda.amazonaws.com"), inlinePolicies: { S3FullAccess: new PolicyDocument({ statements: [ new PolicyStatement({ effect: Effect.ALLOW, actions: ["s3:*"], resources: ["*"], }), ], }), }, }); const lambdaFn = new NodejsFunction(this, "TestSTSLambda11", { memorySize: 1024, timeout: cdk.Duration.seconds(30), runtime: Runtime.NODEJS_20_X, handler: "handler", entry: path.join(__dirname, `../../handlers/lambda-assume-sts-role.ts`), environment: { ASSUME_ROLE_ARN: roleAssumedInLambdaRunTime.roleArn, }, }); lambdaFn.addToRolePolicy( new PolicyStatement({ sid: "AllowSTSAssumeRole", effect: Effect.ALLOW, actions: ["sts:AssumeRole"], resources: ["*"], }), ); lambdaFn.node.addDependency(roleAssumedInLambdaRunTime);
Lambda函数代码
import { AssumeRoleCommand, STSClient } from "@aws-sdk/client-sts"; export async function handler() { const stsClient = new STSClient({ region: "eu-central-1" }); const assumeRoleArn = process.env.ASSUME_ROLE_ARN; console.log(`👉 assumeRoleArn = `, assumeRoleArn); const result = await stsClient.send( new AssumeRoleCommand({ RoleArn: assumeRoleArn, RoleSessionName: "mySession", DurationSeconds: 3600, // 1 hour }), ); console.log(`result = `, result); return { status: "OKAY", }; }
执行错误信息
"errorType": "AccessDenied",
"errorMessage": "User: arn:aws:sts::111111111111:assumed-role/TestLambdaWithSts-TestSTSLambda11ServiceRole3AAAA89-x420WaTiw1LF/TestLambdaWithSts-TestSTSLambda11D1433AEF-gRhoA42zLw1k is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::111111111111:role/TestLambdaWithSts-GrantS3AccessRole1D33947E-OFL9jGuPP02I"
原因分析
- 信任策略不匹配:目标角色
GrantS3AccessRole的信任策略仅允许lambda.amazonaws.com服务主体扮演它,但实际发起AssumeRole请求的是Lambda的执行角色(而非Lambda服务本身),该执行角色不在目标角色的信任列表中。 - 权限是双向要求:要成功执行
sts:AssumeRole,需同时满足两个条件:- 发起请求的角色(Lambda执行角色)拥有
sts:AssumeRole权限; - 目标角色的信任策略允许发起请求的角色来扮演它。
- 发起请求的角色(Lambda执行角色)拥有
解决方案
1. 修改目标角色的信任策略
将目标角色的信任主体改为Lambda的执行角色,或者添加Lambda执行角色到信任列表中。修改后的CDK代码如下:
const lambdaFn = new NodejsFunction(this, "TestSTSLambda11", { memorySize: 1024, timeout: cdk.Duration.seconds(30), runtime: Runtime.NODEJS_20_X, handler: "handler", entry: path.join(__dirname, `../../handlers/lambda-assume-sts-role.ts`), }); const roleAssumedInLambdaRunTime = new Role(this, "GrantS3AccessRole", { // 改为信任Lambda的执行角色 assumedBy: new ArnPrincipal(lambdaFn.role.roleArn), inlinePolicies: { S3FullAccess: new PolicyDocument({ statements: [ new PolicyStatement({ effect: Effect.ALLOW, actions: ["s3:*"], resources: ["*"], }), ], }), }, }); lambdaFn.addToRolePolicy( new PolicyStatement({ sid: "AllowSTSAssumeRole", effect: Effect.ALLOW, actions: ["sts:AssumeRole"], // 缩小资源范围到目标角色ARN,遵循最小权限原则 resources: [roleAssumedInLambdaRunTime.roleArn], }), ); lambdaFn.addEnvironment("ASSUME_ROLE_ARN", roleAssumedInLambdaRunTime.roleArn);
2. 可选:优化权限范围
将Lambda执行角色的sts:AssumeRole权限的资源从*改为目标角色的ARN,遵循AWS最小权限原则,减少过度授权风险。
内容的提问来源于stack exchange,提问作者Hairi
相关产品推荐
相关产品推荐

