S3のバケットポリシーでPutBucketPolicyを制御する際はポリシーの記述ミスに要注意

記事タイトルとURLをコピーする

CI2部 技術2課の山﨑です。

今回の記事で伝えたいことは以下の通りです!

S3バケットポリシーでPutBucketPolicyを制御する際はポリシーの記述ミスに注意しましょう!

S3バケットポリシーについておさらい

S3のバケットポリシーはAWSで定義可能なポリシーの1つである「リソースベースのポリシー」に分類され、IAMポリシーよりも評価順序が優先されるという特性を持っています。つまりバケットポリシーでDenyした操作はIAMユーザーやIAMロールにAdministratorAccess権限を与えていても操作が制限されます。

その他、IAMポリシー設計やIAMの評価ロジックについては以下のブログも合わせて是非ご覧ください。

blog.serverworks.co.jp

blog.serverworks.co.jp

バケットポリシーにおけるPutBucketPolicyの制御について

実例の紹介

S3を利用する際に、バケットポリシーレベルで操作制御をしたいという要件があったとします。例えば特定のIAMユーザーを除いて操作を制御したい以下のようなケースです。

  • 特定のIAMユーザー以外で操作する場合、オブジェクトの削除を拒否したい
  • 特定のIAMユーザー以外で操作する場合のみ、バケットポリシーの編集を拒否したい

このようなケースの場合は、以下のように記述すれば制御が可能です。

参考:AWS JSON ポリシーの要素: NotPrincipal - AWS Identity and Access Management

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyDeleteActions",
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": [
                    "arn:aws:iam::111111111111:user/TestUser",
                    "arn:aws:iam::111111111111:root"
                ]
            },
            "Action": [
                "s3:DeleteObject",
                "s3:DeleteObjectVersion"
            ],
            "Resource": [
                "arn:aws:s3:::yamasaki-zakiyama-test",
                "arn:aws:s3:::yamasaki-zakiyama-test/*"
            ]
        },
        {
            "Sid": "ControlPutBucketPolicy",
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": [
                    "arn:aws:iam::111111111111:user/TestUser",
                    "arn:aws:iam::111111111111:root"
                ]
            },
            "Action": [
                "s3:PutBucketPolicy",
                "s3:DeleteBucketPolicy"
            ],
            "Resource": [
                "arn:aws:s3:::yamasaki-zakiyama-test",
                "arn:aws:s3:::yamasaki-zakiyama-test/*"
            ]
        }
    ]
}

次に、特定のIAMロールによる操作を除き、S3に対する操作を制御したい以下のようなケースを考えてみます。

  • 特定のIAMロール以外でスイッチロールをして操作した場合(Assumed Role)のみ、オブジェクトの削除を拒否したい
  • 特定のIAMロール以外でスイッチロールをして操作した場合(Assumed Role)のみ、バケットポリシーの編集を拒否したい

IAMユーザーのケースと同様に記述すると以下の通りになります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyDeleteActions",
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": [
                    "arn:aws:iam::111111111111:role/TestAdminRole",
                    "arn:aws:iam::111111111111:root"
                ]
            },
            "Action": [
                "s3:DeleteObject",
                "s3:DeleteObjectVersion"
            ],
            "Resource": [
                "arn:aws:s3:::yamasaki-zakiyama-test",
                "arn:aws:s3:::yamasaki-zakiyama-test/*"
            ]
        },
        {
            "Sid": "ControlPutBucketPolicy",
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": [
                    "arn:aws:iam::111111111111:role/TestAdminRole",
                    "arn:aws:iam::111111111111:root"
                ]
            },
            "Action": [
                "s3:PutBucketPolicy",
                "s3:DeleteBucketPolicy"
            ],
            "Resource": [
                "arn:aws:s3:::yamasaki-zakiyama-test",
                "arn:aws:s3:::yamasaki-zakiyama-test/*"
            ]
        }
    ]
}

これでOK!と思いきや、実はこのポリシーの記述だと意図した通りの制御が適用されません。

IAMロールの権限でAWSリソースを操作する場合、AWS Security Token Service(AWS STS)を利用して一時的な認証情報を取得することでIAMロールをアタッチしたAWSリソースに対して権限を与え操作を可能にしています。

よって、今回のように特定のIAMロールによる操作を除き、S3に対する操作を制御したい場合は以下のようにNotPrincipal要素で指定するAWSリソースにAWS STSのARNも含める必要があります。

この内容についてはAWSドキュメントにも記載されています。

docs.aws.amazon.com

なお、AWS STSのARNの末尾にある「administrator」の箇所(セッション名)はスイッチロールの場合、デフォルトではスイッチロールを実行したIAMユーザー名となります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyDeleteActions",
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": [
                    "arn:aws:sts::111111111111:assumed-role/TestAdminRole/administrator",
                    "arn:aws:iam::111111111111:role/TestAdminRole",
                    "arn:aws:iam::111111111111:root"
                ]
            },
            "Action": [
                "s3:DeleteObject",
                "s3:DeleteObjectVersion"
            ],
            "Resource": [
                "arn:aws:s3:::yamasaki-zakiyama-test",
                "arn:aws:s3:::yamasaki-zakiyama-test/*"
            ]
        },
        {
            "Sid": "ControlPutBucketPolicy",
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": [
                    "arn:aws:sts::111111111111:assumed-role/TestAdminRole/administrator",
                    "arn:aws:iam::111111111111:role/TestAdminRole",
                    "arn:aws:iam::111111111111:root"
                ]
            },
            "Action": [
                "s3:PutBucketPolicy",
                "s3:DeleteBucketPolicy"
            ],
            "Resource": [
                "arn:aws:s3:::yamasaki-zakiyama-test",
                "arn:aws:s3:::yamasaki-zakiyama-test/*"
            ]
        }
    ]
}

注意事項

上記で示した実例のように、PutBucketPolicyの操作権限を制御するポリシーの記述を誤るとAdministratorAccess権限を持ったIAMユーザーやIAMロールでもバケットポリシーを編集することができなくなってしまいます。これはバケットポリシーはIAMポリシーよりも評価順序が優先されるという前述の特性を持っているためです。

この場合はrootアカウントでログインしてバケットポリシーを削除するしか対処方法がありません。

aws.amazon.com

まとめ

S3のバケットポリシーでPutBucketPolicyを制御する際、ポリシー記述を誤ってしまうとAdministratorAccess権限を持ったIAMユーザーやIAMロールでもバケットポリシーを編集することができず、rootアカウントでログインしてバケットポリシーを削除する他ありません。そのため以下のいずれかの方法を採用して、rootアカウントを利用する事態を回避しましょう。

  • Organizations を利用している場合はバケットポリシーではなくSCPで制御する。
  • 検証環境でバケットポリシーの動作を十分に検証した上で、本番環境でバケットポリシーを定義する。
  • バケットポリシーではなく、IAMで制御する。
    • ただし、制御対象のPrincipalにIAMの編集権限があると制御の意味がなくなってしまうので対象Principalに対してIAM操作を禁止する等の別措置を考慮する必要あり

山﨑 翔平 (Shohei Yamasaki) 記事一覧はコチラ

カスタマーサクセス部所属。2019年12月にインフラ未経験で入社し、AWSエンジニアとしてのキャリアを始める。2023 Japan AWS Ambassadors/2023-2024 Japan AWS Top Engineers