允许用户只上传到一个 S3 桶

Allow User to Only Upload to one S3 Bucket

我看过其他类似的问题,但我不知道该怎么做。

我有一个 S3 存储桶,所有 public 访问都被阻止并且该存储桶启用了服务器端加密。

我想创建一个用户组,其权限允许特定用户查看列出的存储桶(但不允许其他用户)并上传,但不能下载、删除或该存储桶中的任何其他内容。

我有一个具有如下权限的用户组:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:CreateAccessPoint",
                "s3:PutAnalyticsConfiguration",
                "s3:PutAccelerateConfiguration",
                "s3:PutAccessPointConfigurationForObjectLambda",
                "s3:DeleteObjectVersion",
                "s3:RestoreObject",
                "s3:DeleteAccessPoint",
                "s3:CreateBucket",
                "s3:ListBucket",
                "s3:DeleteAccessPointForObjectLambda",
                "s3:ReplicateObject",
                "s3:PutEncryptionConfiguration",
                "s3:DeleteBucketWebsite",
                "s3:AbortMultipartUpload",
                "s3:PutLifecycleConfiguration",
                "s3:UpdateJobPriority",
                "s3:CreateMultiRegionAccessPoint",
                "s3:PutBucketVersioning",
                "s3:PutObjectAcl",
                "s3:PutIntelligentTieringConfiguration",
                "s3:PutMetricsConfiguration",
                "s3:PutBucketOwnershipControls",
                "s3:PutReplicationConfiguration",
                "s3:DeleteMultiRegionAccessPoint",
                "s3:PutObjectLegalHold",
                "s3:UpdateJobStatus",
                "s3:PutBucketCORS",
                "s3:PutInventoryConfiguration",
                "s3:PutObject",
                "s3:PutBucketNotification",
                "s3:DeleteStorageLensConfiguration",
                "s3:PutBucketWebsite",
                "s3:PutBucketRequestPayment",
                "s3:PutObjectRetention",
                "s3:PutBucketLogging",
                "s3:CreateAccessPointForObjectLambda",
                "s3:PutBucketObjectLockConfiguration",
                "s3:ReplicateDelete"
            ],
            "Resource": "arn:aws:s3:::my-bucket"
        }
    ]
}

我用可视化编辑器创建了它,这对我来说似乎有些过分,但是,即使我已将用户分配给该用户组,我仍然无法将文件上传到该存储桶,也无法在签名后看到列出的存储桶作为那个用户。

我做错了什么?

///编辑///

这是我标记为正确的答案专门针对的版本:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketPublicAccessBlock",
                "s3:GetBucketPolicyStatus",
                "s3:PutObject",
                "s3:GetObjectAcl",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:DeleteObject",
                "s3:GetBucketAcl",
                "s3:GetBucketLocation",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket",
                "arn:aws:s3:::my-bucket/*"
            ]
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": [
                "s3:GetAccountPublicAccessBlock",
                "s3:ListAccessPoints"
            ],
            "Resource": "arn:aws:s3:::*"
        }
    ]
}

这里有几个问题:

  1. 您正在混合存储桶级别和对象级别的操作
  2. 在某些情况下您使用了不正确的资源 ARN
  3. 您的政策过于宽松

操作的问题在于,一些操作与存储桶相关,一些操作与对象相关,而其他操作根本不与资源类型相关。任何时候您在 same 资源中同时包含存储桶 ARN(例如 "arn:aws:s3:::my-bucket""arn:aws:s3:::*")和对象 ARN(例如 "arn:aws:s3:::my-bucket/*")声明,你可能做错了。

您可以查看 bucket and object operations and you can see a list of actions defined by S3 的示例以及与这些操作相关的相应资源类型。您的策略应该将存储桶操作应用于存储桶资源 ARN,并将对象操作应用于对象资源 ARN,理想情况下它们不应混合使用(实际上,这在很大程度上与您在编辑示例中所做的一样,这很好)。是的,针对存储桶 ARN 和通配符对象 ARN 执行诸如允许 "s3:Get*" 之类的操作很诱人,但这是不正确的,而且维护起来很头疼。

例如,您会看到 ListAccessPoints 没有关联的资源类型。您指出的 "arn:aws:s3:::*" 是不正确的,并且不会授予任何内容(它需要改为 "*")。为什么需要 "*"?根据 documentation:

If an action does not support resource-level permissions, then that statement in the policy must use a wildcard (*) in the Resource element.

在我看来,这对 AWS 来说是一个有点不幸和值得怀疑的选择。

如果您想要一个允许列出所有存储桶、列出特定存储桶中的对象并上传到同一存储桶的 IAM 策略,但仅此而已,那么我将从以下内容开始:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": "arn:aws:s3:::my-bucket"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::my-bucket/*"
        }
    ]
}

现在,您可能会在实践中发现这还不够,必须添加额外的操作(我不知道您的客户做什么),但我希望这是一个很好的起点。