You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,需同时满足两个条件:
    1. 发起请求的角色(Lambda执行角色)拥有sts:AssumeRole权限;
    2. 目标角色的信任策略允许发起请求的角色来扮演它。
解决方案

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 10:52:42