AWS政策解读

AWS policy interpretation

我正在尝试了解条件 "home/${aws:userid}/*" 的必要性。这个条件其实感觉在 "arn:aws:s3:::bucket-name/home/${aws:userid}/*" .

中就满足了

当我们在该用户的第三条语句中允许所有 s3 操作时。那么为什么我们需要专门为该用户允许 s3:listbuckets?

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets",
                "s3:GetBucketLocation"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::bucket-name",
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "",
                        "home/",
                        "home/${aws:userid}/*"
                    ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::bucket-name/home/${aws:userid}",
                "arn:aws:s3:::bucket-name/home/${aws:userid}/*"
            ]
        }
    ]
}

ref https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_s3_federated-home-directory-console.html

资源不同。第三条语句,用户只能访问bucket-name/home/${aws:userid}。这意味着当用户进入 S3 控制台并单击存储桶 bucket-name 时,访问将被拒绝。因此用户将无法 列出存储桶内容 ,也不会看到那里有 home 文件夹。他们也不会在 bucket-name/home 中看到一个包含他们用户名的文件夹。

因此,为了克服这个问题,有第二个语句,它允许列出``bucket-nameand thenbucket-name/home`的所有内容。这样用户就可以在 S3 控制台中轻松导航以到达他们实际的主文件夹。

如果没有第二条语句,用户必须在浏览器中输入 url 的主文件夹才能直接转到它,这对用户来说不是很友好。

s3:ListBucket 是 bucket-level 权限,而 arn:aws:s3:::bucket-name/home/${aws:userid}/* 是通配符 object ARN,而不是 bucketARN.

授予 s3:ListBucket 的尝试将不会匹配任何不是存储桶 ARN 的 Resource,因此 s3:* 授予 - 仅包括对象 ARN - 不会实际上允许对象列表。

所以这个示例策略不包含任何冗余。

如果此实现看起来仍然有点 counter-intuitive 或可能令人费解,但如果您考虑 S3 API 在线路上的工作方式,它确实会变得更加清晰。 ListObjects API action(以及较新的 ListObjectsV2)是针对存储桶提交的——请求中没有路径……或者,更准确地说,HTTP 请求中的路径始终是¹ /... 并且查询字符串包含 prefix= 和要锚定所请求列表的对象键前缀。

虽然底层 API 的工作方式与 IAM 策略的工作方式之间没有强制关联,但 s3:prefix 条件键用于控制 prefix ListObjects 的参数,而不是 object-level ARN,并且存储桶(不是对象键或通配符模式)是正在访问的资源。


¹ 始终 / 除非它是 /${bucket} 旧的已弃用 path-style URL 所要求的 finally being phased out 在一两次错误的开始之后,至少对于新的水桶。请求 URI 的路径部分中表示的资源始终是存储桶本身,而不是存储桶加上键前缀。