S3 跨账户存储桶权限

S3 跨账户存储桶权限

与本文[0]中描述的情况类似,我所在的公司使用堡垒 AWS 账户来存储 IAM 用户和其他 AWS 账户,以分隔不同的运行环境(生产环境、开发环境等)。这很重要,因为我们有多个 AWS 账户,在某些特殊情况下,这些 AWS 账户需要访问单个 S3 存储桶。

使其正常工作的一种方法是设置一个存储桶策略,允许从特定 AWS 账户的 VPC 的 S3 端点访问存储桶。

  1. 桶策略data-warehouse

    {
        "Sid": "access-from-dev-VPCE",
        "Effect": "Allow",
        "Principal": "*",
        "Action": "s3:*",
        "Resource": [
            "arn:aws:s3:::data-warehouse",
            "arn:aws:s3:::data-warehouse/*"
        ],
        "Condition": {
            "StringEquals": {
                "aws:sourceVpce": "vpce-d95b05b0"
            }
        }
    }
    
  2. 角色的角色策略EMRRole

     {
        "Sid": "AllowRoleToListBucket",
        "Effect": "Allow",
        "Action": "s3:ListBucket",
        "Resource": [
            "arn:aws:s3:::data-warehouse",
        ]
    },
    {
        "Sid": "AllowRoleToGetBucketObjects",
        "Effect": "Allow",
        "Action": [
            "s3:GetObject",
            "s3:GetObjectVersion"
        ],
        "Resource": "arn:aws:s3:::data-warehouse/*"
    }
    

不幸的是,这不起作用,直到我明确设置了 ACL每个对象允许我访问的 AWS 账户的所有者完全控制该对象。如果我不这样做,我会得到:

fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden

我运行此程序的实例(EMR)具有正确的角色:

[hadoop@ip-10-137-221-91 tmp]$  aws sts get-caller-identity
{
    "Account": "1234567890",
    "UserId": "AROAIGVIL6ZDI6SR87KXO:i-0eaf8a5ca52876835",
    "Arn": "arn:aws:sts::1234567890:assumed-role/EMRRole/i-0eaf8a5ca52876835"
}

存储桶中对象的 ACLdata-warehouse如下所示:

aws s3api get-object-acl --bucket=data-warehouse --key=content_category/build=2017-11-23/part0000.gz.parquet
{
    "Owner": {
        "DisplayName": "aws+dev",
        "ID": "YXJzdGFyc3RhcnRzadc6frYXJzdGFyc3RhcnN0"
    },
    "Grants": [
        {
            "Grantee": {
                "Type": "CanonicalUser",
                "DisplayName": "aws+dev",
                "ID": "YXJzdGFyc3RhcnRzadc6frYXJzdGFyc3RhcnN0"
            },
            "Permission": "FULL_CONTROL"
        }
    ]
}

在上面的 ACL 中,devAWS 账户将能够读取该对象,但另一个 AWS 账户(例如)prod不是能够读取该对象,直到被添加为“受让人”。

我的问题:有没有办法从多个 AWS 账户读取/写入对象到 S3 存储桶,而无需在每个单独的对象上设置 ACL?

注意:我们使用spark通过s3a写入s3。

[0]https://engineering.coinbase.com/you-need-more-than-one-aws-account-aws-bastions-and-assume-role-23946c6dfde3

答案1

虽然我还没有找到一种基于每个对象设置 ACL 的方法,但有一种方法可以强制使用存储桶策略在上传时正确设置 ACL。此示例策略显示如何允许 AWS 账户将对象上传到您的存储桶,并要求存储桶所有者被授予对所有上传对象的完全控制权:

{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "AllowSourceAccount0123456789ToPutObjects",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::0123456789:root"
        },
        "Action": "s3:PutObject",
        "Resource": "arn:aws:s3:::data-warehouse/*"
    },
    {
        "Sid": "RequireAllUploadedObjectsToAssignFullControlToBucketOwner",
        "Effect": "Deny",
        "Principal": {
            "AWS": "*"
        },
        "Action": "s3:PutObject",
        "Resource": "arn:aws:s3:::data-warehouse/*",
        "Condition": {
            "StringNotEquals": {
                "s3:x-amz-acl": "bucket-owner-full-control"
            }
        }
    }
]

}

关键是显式拒绝,它会检查x-amz-acl: bucket-owner-full-control标头(Michael-sqlbot 在评论中提到),如果未设置标头,则会导致上传失败。使用 AWS CLI 上传文件时,需要--acl 存储桶所有者完全控制要设置的标志。

例子:

aws s3 cp example-file.txt s3://data-warehouse/example-file.txt --profile aws-profile-name --acl bucket-owner-full-control

希望 AWS 能够在某些时候提供一种更优雅地解决 ACL 问题的方法。

相关内容