S3の特定のフォルダのみを許可するIAMポリシー


S3の特定のプレフィックスに限定して、S3オブジェクトの基本操作(読み込み、書き込み、削除、オブジェクト一覧確認)のみを許可するIAMポリシーは、

結論

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::BUCKET/PREFIX/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::BUCKET"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": "PREFIX/*"
                }
            }
        }
    ]
}

説明

S3オブジェクトの基本操作(読み込み、書き込み、削除、オブジェクト一覧確認)に必要な権限のActionは s3:GetObjects3:PutObjects3:DeleteObjects3:ListBucket です。

ちなみにオブジェクト一覧を見るための権限は ListObject のような名前ではなく s3:ListBucket です。これに対してバケットの一覧は s3:ListAllMyBuckets です。名前が紛らわしいです。

これを踏まえて、次のように書きたくなるのですが、

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

これはうまくいきません。読み込み、書き込み、削除はできますが、オブジェクト一覧を見ることができません。

Resourceで指定するリソースの種類はActionごとに決まっていて、s3:GetObjects3:PutObjects3:DeleteObject はオブジェクトですが、s3:ListBucket はバケットなのです。従って、s3:ListBucket だけResourceは arn:aws:s3:::BUCKET のようにバケット単位での指定が必要です。ここにプレフィックスを書くことはできません。

s3:ListBucket だけ分けて書くことになります。

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

しかし、これだと s3:ListBucket は特定プレフィックス配下ではなく、バケット全体で許可されてしまいます。Conditionに以下のように s3:prefix の条件を書くことで、特定プレフィックス配下に限定することが必要になります。これで冒頭のIAMポリシーになります。

            "Condition": {
                "StringLike": {
                    "s3:prefix": "PREFIX/*"
                }
            }

ポイント

  • s3:ListBucket だけ分けて書く
    • Resourceはバケット全体を指定
    • Conditionに s3:prefix を指定
  • s3:???Object はResourceにプレフィックスを含める

(毎回身近なところから似たIAMポリシーを探したり、ググったりしてるので、できる限りシンプルなパターンとして、記事にまとめておいたものです)

参考

Actionの一覧とそれぞれの指定できるリソースの種類は、次の公式ドキュメントに載っています。

Actions, resources, and condition keys for Amazon S3 - Service Authorization Reference