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

S3跨账号上传触发Lambda失败:GetObject权限问题排查

跨账号S3触发Lambda时GetObject权限拒绝问题

场景概述

账号A内有一个Lambda函数,会在指定S3桶上传文件时触发,功能为将PDF转换为DataFrame并写入另一个S3桶。目前允许账号B的Administrator IAM用户跨账号上传文件触发该Lambda,但Lambda执行GetObject操作时出现权限拒绝错误。账号A内部上传文件时流程正常,仅跨账号上传时出现问题。

相关代码与报错

Lambda代码

LOGGER = logging.getLogger(__name__)
logging.basicConfig(level=logging.ERROR)
logging.getLogger(__name__).setLevel(logging.DEBUG)
session = boto3.Session(
    aws_access_key_id="XXXX",
    aws_secret_access_key="XXXX",
)
s3 = session.resource('s3')
dest_bucket = 'bucket-output'
csv_buffer = StringIO()

def lambda_handler(event,context):
    source_bucket = event['Records'][0]['s3']['bucket']['name']
    pdf_name = event['Records'][0]['s3']['object']['key']
    LOGGER.info('Reading {} from {}'.format(pdf_name, source_bucket))
    pdf_obj = s3.Object(source_bucket,pdf_name)
    fs = pdf_obj.get()['Body'].read() #### code is failing here
    df = convert_bytes_to_df(BytesIO(fs)) 
    df.to_csv(csv_buffer,index=False)
    s3.Object(dest_bucket,str(pdf_name.split('.')[0])+".csv").put(Body=csv_buffer.getvalue())
    LOGGER.info('Successfully converted {} from {} to {}'.format(pdf_name,source_bucket,dest_bucket))

报错信息

ClientError: An error occurred (AccessDenied) when calling the GetObject operation: Access Denied

已配置的权限策略

账号A的S3桶策略(Terraform)

resource "aws_s3_bucket_policy" "cross_account_input_access" {
  bucket = aws_s3_bucket.statements_input.id
  policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::XXXXXXXXX:user/Administrator"
            },
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::capsphere-input"
            ]
        },      
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::XXXXXXXXX:user/Administrator"
            },
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::bucket-name",
                "arn:aws:s3:::bucket-name/*"
            ]
        }
    ]
}
EOF
}

账号B的Administrator用户IAM策略

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::bucket-name"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::bucket-name",
                "arn:aws:s3:::bucket-name/*"
            ]
        }
    ]
}

跨账号上传命令

aws s3 cp filename.pdf s3://bucket-name

解决方案

  • 修复桶策略资源ARN不一致问题:账号A的桶策略中第一个Statement的Resource是arn:aws:s3:::capsphere-input,第二个Statement用的是bucket-name,需统一为实际输入桶名称(如capsphere-input),避免资源匹配错误。
  • 配置S3桶对象所有权:将账号A的目标S3桶对象所有权设置为Bucket owner preferred,这样账号B用户上传的对象会自动归账号A所有,避免因对象归属导致的权限拒绝。
  • 为Lambda使用的身份添加GetObject权限:Lambda中硬编码密钥对应的账号A用户需要明确拥有目标桶的s3:GetObject权限,可在该用户的IAM策略中添加对应规则,同时在账号A的桶策略中补充允许该用户访问桶内对象的Statement:
    {
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::账号AID:user/硬编码密钥对应的用户名"
        },
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::capsphere-input/*"
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:42:50