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

跨账号S3对象复制调用CopyObject遇权限拒绝(IAM STS扮演)

跨账号S3复制CopyObject报AccessDenied错误排查与解决方案

问题背景

通过Account-B的Lambda函数关联Role-B,扮演Account-A的Role-A执行跨账号S3对象复制时,调用CopyObject操作触发AccessDenied错误,但已成功AssumeRole并能访问Bucket-A及其对象。

环境配置

Account-A侧

  • Bucket-A:无桶级别策略
  • IAM角色Role-A:
    内联权限策略:
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "VisualEditor0",
                "Effect": "Allow",
                "Action": [
                    "kms:Decrypt",
                    "kms:GenerateDataKey"
                ],
                "Resource": "*"
            },
            {
                "Sid": "VisualEditor1",
                "Effect": "Allow",
                "Action": [
                    "s3:GetObject",
                    "s3:GetObjectVersion",
                    "s3:GetObjectAcl",
                    "s3:CopyObject",
                    "s3:HeadObject",
                    "s3:GetObjectTagging",
                    "s3:PutObjectTagging"
                ],
                "Resource": "arn:aws:s3:::Bucket-A/*"
            },
            {
                "Sid": "VisualEditor2",
                "Effect": "Allow",
                "Action": [
                    "s3:ListBucket",
                    "s3:ListAllMyBuckets",
                    "s3:GetBucketAcl",
                    "s3:GetBucketLocation"
                ],
                "Resource": "arn:aws:s3:::Bucket-A"
            }
        ]
    }
    
    信任关系(允许Account-B的Role-B调用AssumeRole):
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "AWS": [
                        "arn:aws:iam::xxxxxxxxxx:role/service-role/Role-B"
                    ]
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }
    

Account-B侧

  • Bucket-B:无桶级别策略
  • Lambda函数Lambda-B:执行跨账号S3复制的Python函数
  • IAM角色Role-B:
    扮演Role-A的权限策略:
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Action": [
                    "iam:PassRole",
                    "iam:GetRole"
                ],
                "Resource": "*",
                "Effect": "Allow"
            },
            {
                "Action": "sts:AssumeRole",
                "Resource": "arn:aws:iam:: xxxxxxxxxx:role/Role-A",
                "Effect": "Allow"
            }
        ]
    }
    
    附加权限:
    Encrypt and Decrypt KMS - of KMS-A and KMS-B (tried adding both accounts KMS IDs too)
    AmazonSSMFullAccess
    AWSLambdaVPCAccessExecutionRole
    AmazonRedshiftFullAccess
    AmazonS3FullAccess
    

错误日志

[ERROR] ClientError: An error occurred (AccessDenied) when calling the CopyObject operation: Access Denied
Traceback (most recent call last):
   File "/var/task/lambda_function.py", line 136, in lambda_handler
    s3_resource.meta.client.copy(copy_source, TARGET_BUCKET, SOURCE_PATH)
   File "/var/runtime/boto3/s3/inject.py", line 380, in copy
    return future.result()
   File "/var/runtime/s3transfer/futures.py", line 103, in result
    return self._coordinator.result()
   File "/var/runtime/s3transfer/futures.py", line 266, in result
    raise self._exception
   File "/var/runtime/s3transfer/tasks.py", line 139, in __call__
    return self._execute_main(kwargs)
   File "/var/runtime/s3transfer/tasks.py", line 162, in _execute_main
    return_value = self._main(**kwargs)
   File "/var/runtime/s3transfer/copies.py", line 313, in _main
    client.copy_object(
   File "/var/runtime/botocore/client.py", line 391, in _api_call
    return self._make_api_call(operation_name, kwargs)
   File "/var/runtime/botocore/client.py", line 719, in _make_api_call
    raise error_class(parsed_response, operation_name)END RequestId: 80c88cc3-46ee-4707-85d1-6b62b0f3f50d

解决方案

1. 缺失的权限分析

核心问题是执行CopyObject时使用的是Role-A的身份,而Role-A没有写入Account-B的Bucket-B的权限:

  • CopyObject操作需要同时拥有源对象的读取权限和目标桶的写入权限。当前Role-A仅配置了Bucket-A的权限,缺少对Bucket-B的s3:PutObject(或s3:CopyObject)权限。
  • 注意:Role-B的AmazonS3FullAccess权限不会生效,因为复制操作是通过AssumeRole后的Role-A凭证执行的,权限以Role-A为准。
  • 另外,Role-B的AssumeRole策略中,Role-A的ARN存在空格(arn:aws:iam:: xxxxxxxxxx:role/Role-A),虽当前AssumeRole成功,但属于拼写错误,建议修正。

需给Role-A添加以下权限策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:CopyObject"
            ],
            "Resource": "arn:aws:s3:::Bucket-B/*"
        },
        {
            "Effect": "Allow",
            "Action": "s3:GetBucketLocation",
            "Resource": "arn:aws:s3:::Bucket-B"
        }
    ]
}

若Account-B的Bucket-B有桶策略限制,需确保允许Role-A的ARN访问。

2. 该复制方式是否可行

这种方式完全可行,只要修正Role-A的权限配置,确保其同时拥有源桶读取和目标桶写入权限,即可通过AssumeRole后的身份执行跨账号复制。

3. 大文件跨账号复制推荐方案

针对大文件(尤其是超过5GB的对象),推荐以下方案:

  • S3批量复制(S3 Batch Operations):无需编写代码,直接通过控制台或API配置批量任务,支持跨账号,可指定IAM角色执行,适合大量文件的一次性复制。
  • 分段复制(Multipart Copy):对于大于5GB的文件,必须使用分段复制,boto3的copy方法会自动处理分段逻辑,但需确保Role-A拥有s3:UploadPartCopy、s3:CompleteMultipartUpload等相关权限。
  • S3 Transfer Acceleration:如果跨区域复制,开启目标桶的Transfer Acceleration功能,可提升跨区域传输速度。
  • S3跨区域复制(CRR):若需长期同步源桶和目标桶的对象,配置CRR自动同步,无需手动触发,适合持续同步场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:40:43