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

ECS任务角色无法自我扮演导致S3访问失败问题排查

问题

将Next.js容器部署为ECS任务,希望通过该任务读写S3存储。为避免硬编码凭证,把任务角色ARN添加到容器环境变量(ROLE_NAME)中。该任务角色由CDK生成,已附加AmazonS3FullAccess权限,ARN为arn:aws:iam::426003470206:role/rolenameA。

代码中添加了以下逻辑:

let s3Client: S3Client;

let temp_credentials: any = {};
async function loginRole() {
  const stsClient = new STSClient({ region: process.env.S3_REGION });
  temp_credentials = await stsClient.send(
    new AssumeRoleCommand({
      RoleArn: process.env.ROLE_NAME,
      RoleSessionName: "FrontendSession",
      DurationSeconds: 3600,
    })
  );

  s3Client = new S3Client({
    region: process.env.S3_REGION,
    credentials: {
      accessKeyId: temp_credentials.Credentials.AccessKeyId,
      secretAccessKey: temp_credentials.Credentials.SecretAccessKey,
      sessionToken: temp_credentials.Credentials.SessionToken,
    },
  });
}

if (process.env.ROLE_NAME != undefined) {
  setInterval(() => {
    loginRole();
  }, 3_600_000);
  loginRole();
} else {
  s3Client = new S3Client({
    region: process.env.S3_REGION,
    credentials: {
      accessKeyId: process.env.MINIO_USER!,
      secretAccessKey: process.env.MINIO_PASS!,
    },
  });
}

运行时出现错误:

AccessDenied: User: arn:aws:sts::xxx:assumed-role/rolenameA/608fdb15fdfb418ea955e6c117245735 is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::426003470206:role/rolenameA

其中608fdb15fdfb418ea955e6c117245735是容器所在的任务ID。

任务角色的信任关系配置:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ecs-tasks.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

已附加的策略包括:AmazonS3FullAccess、AmazonSQSFullAccess、NextAppContainerTaskRoleDefaultPolicy31CD40AE。

使用普通技术用户的AccessKey(MINIO_USER)和SecretKey(MINIO_PASS)时一切正常,但使用任务角色的新代码出现上述错误,请问遗漏了什么配置?

解决方案
  • 核心问题:冗余的角色假设操作
    ECS任务角色会自动通过IAM角色凭证服务(IRSA)为容器提供临时凭证,不需要手动调用sts:AssumeRole获取凭证。你当前的代码是让已经通过任务角色获得权限的容器,再尝试"扮演"同一个任务角色,这完全没必要,且任务角色本身未被授权执行sts:AssumeRole操作自身,因此触发权限错误。

  • 修正步骤:

    1. 移除容器环境变量中的ROLE_NAME配置,无需将任务角色ARN传入容器。
    2. 简化S3客户端初始化代码,让AWS SDK自动从ECS任务元数据服务获取临时凭证:
      import { S3Client } from "@aws-sdk/client-s3";
      
      const s3Client = new S3Client({
        region: process.env.S3_REGION
      });
      
      AWS SDK会自动检测运行环境(ECS任务),并从任务元数据端点获取任务角色的临时凭证,无需手动指定凭证参数,也不需要定时刷新——SDK内部会自动处理凭证过期和刷新逻辑。
    3. 确认任务角色权限:当前已附加AmazonS3FullAccess策略,权限满足需求,无需修改信任关系。
  • 错误原因说明:
    任务角色的信任关系是允许ecs-tasks.amazonaws.com服务扮演该角色,为ECS任务提供凭证。而你的代码是让任务中的容器(已使用该角色身份)再调用sts:AssumeRole扮演自己,不符合IAM权限模型,且任务角色的权限策略中未包含sts:AssumeRole权限(也不应添加),因此被拒绝。

内容的提问来源于stack exchange,提问作者IFThenElse

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 18:43:29