特定 IAM ユーザーのみアクセスできる S3 バケットを作ってみた

2023.09.19

特定 IAM ユーザーのみアクセスできる S3 バケットを作成する機会がありましたので、ご紹介します。

前提として、下記のリソースをそれぞれ作成しておきます。動作確認のため、 IAM ユーザーには S3 へのフルアクセス権限を付与しています。

  • S3 バケット (test.txt をアップロード済み)
  • IAM ユーザー:userA -> AmazonS3FullAccess ポリシーをアタッチ
  • IAM ユーザー:userB -> AmazonS3FullAccess ポリシーをアタッチ

結論

下記のように、aws:username キーを用いて、特定 IAM ユーザー(今回の場合だと userA)以外からのアクションを全て拒否することで、要件を満たすことができます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "sid1",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::<バケット名>",
                "arn:aws:s3:::<バケット名>/*"
            ],
            "Condition": {
                "StringNotEquals": {
                    "aws:username": "userA"
                }
            }
        }
    ]
}

動作確認

userAでアクセスしてみた結果。想定通りアクセスできています。

userBでアクセスしてみた結果。権限がないので、オブジェクトの一覧を見ることができません。もちろん、プロパティなどの各種設定へもアクセスすることはできません。

これで、無事特定ユーザー(userA)のみがアクセスできるバケットが出来上がりました!

バケットポリシーのNG例

結論としては上記ポリシーの設定で以上ですが、最後に自分が過去にやらかしたバケットポリシーのNG例も併せてご紹介します。

当時の自分は、「特定ユーザーのみアクセスできるということは、”特定ユーザー(userA)のアクションを許可” して “それ以外を拒否” すればいいんじゃない?というアプローチで以下のように書きました。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "sid1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<アカウントID>:user/userA"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::<バケット名>",
                "arn:aws:s3:::<バケット名>/*"
            ]
        },
        {
            "Sid": "sid2",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::<バケット名>",
                "arn:aws:s3:::<バケット名>/*"
            ]
        }
    ]
}

しかし結果は以下のように、アクションを許可したはずの userA からもアクセスすることができず、誰からもアクセスできない(もちろん誤ったポリシーを削除することもできない)ゾンビバケットとなってしまいました。

動作確認

userAからアクセスしたにも関わらず、中身が見れません。

アクセスできなくなった原因

上記の挙動が生じる原因は、ポリシー内で定義される明示的な Deny が、明示的な Allow より優先されて評価されるためです。

NG例のポリシーでは、Allow と Deny の2つの “Effect” ブロックを定義していますが、この場合、2つ目の Deny ブロックが優先されて評価されます。 そのため、1つ目の Allow ブロックで許可権限を与えていても2つ目の Deny ブロックがそれを上書きしてしまうため、userA からもアクセスできなくなるという結果になります。

バケットポリシーの評価論理については下記ブログが詳しいため、ぜひご参照ください。複雑なバケットポリシーについて、分かりやすい図を用いて説明しています。

まとめ

今回は、特定 IAM ユーザーのみアクセスできる S3 バケットの作成方法をご紹介しました。 バケットポリシーの設定を間違えると、NG例のような誰からもアクセスできないゾンビバケットを誕生させてしまい、ルートユーザーを使わないと消せない…なんてことになりかねません。 なので、設定する際には十分に注意しましょう(自戒)。

本ブログが誰かのお役に立てば幸いです。

アノテーション株式会社について

アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社WEBサイトをご覧ください。