跨不同AWS账户S3桶复制文件时遭遇HeadObject 403禁止错误
解决跨账户S3复制时HeadObject 403 Forbidden错误
问题核心原因
跨账户S3复制时,执行copy操作的身份(你切换到的目标账户角色)需要同时具备两个关键权限:
- 源桶BucketA中
names.csv对象的s3:GetObject/s3:HeadObject权限 - 目标桶BucketB的
s3:PutObject权限
且源桶必须显式允许该角色访问,否则就会触发403错误。
分步解决方案
1. 修正目标账户角色的IAM权限
不要直接给全量S3权限,按需配置最小权限策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::BucketB/*" }, { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:HeadObject" ], "Resource": "arn:aws:s3:::BucketA/names.csv" } ] }
2. 配置源桶BucketA的桶策略
在源账户的BucketA中添加桶策略,开放目标角色的访问权限:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::目标账户ID:role/你的角色名" }, "Action": [ "s3:GetObject", "s3:HeadObject" ], "Resource": "arn:aws:s3:::BucketA/names.csv" } ] }
替换其中的目标账户ID和你的角色名为实际值。
3. 修正代码的角色切换逻辑
你当前用目标账户AK/SK直接创建会话的方式不符合角色访问规范,正确做法是通过STS临时凭证切换角色:
import boto3 # 用当前身份(源账户凭证)获取目标角色的临时凭证 sts_client = boto3.client('sts') assume_role_response = sts_client.assume_role( RoleArn='arn:aws:iam::目标账户ID:role/你的角色名', RoleSessionName='cross-account-s3-copy-session' ) # 使用临时凭证初始化会话 temp_creds = assume_role_response['Credentials'] bucketB_session = boto3.Session( aws_access_key_id=temp_creds['AccessKeyId'], aws_secret_access_key=temp_creds['SecretAccessKey'], aws_session_token=temp_creds['SessionToken'] ) # 执行复制操作 bucketB_s3 = bucketB_session.resource('s3') copy_source = {'Bucket': 'BucketA', 'Key': 'names.csv'} bucketB_s3.Object("BucketB", 'names.csv').copy(copy_source)
额外检查项
- 确认目标角色的信任策略允许你当前使用的身份(源账户用户/角色)调用
sts:AssumeRole - 如果是在EC2/ECS等服务中运行代码,确保服务角色具备
sts:AssumeRole权限
内容的提问来源于stack exchange,提问作者DataGuy
相关产品推荐
相关产品推荐

