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

