1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

S3バケットポリシーで管理者IAMユーザ以外のアクセスを弾く

Last updated at Posted at 2021-09-05

S3BucketPolicy.drawio.png

背景

  • 機密情報が含まれるファイルを格納するS3がある(Protected Bucket)
  • Protected Bucketには管理者グループに属するIAMユーザだけがアクセスできるようにしたい(管理者グループ以外のIAMユーザはアクセス不可)

※各IAMグループに属するIAMユーザは下表のような命名規則を想定しています

ユーザ グループ
001admin Admin
002admin Admin
001deploy Deploy
002deploy Deploy
001readonly ReadOnly
002readonly ReadOnly
003readonly ReadOnly
004readonly ReadOnly

IAMポリシーでアクセス制限する

最もシンプルで確実なやり方としては、管理者グループ以外のグループたち(上の例だとDeployグループ、ReadOnlyグループ)に対して、「Protected Bucketに対する明示的なDeny」のポリシーをそれぞれアタッチする方法だと思います。
ただこの方法のデメリットとしては、以下が挙げられます。

  • 管理者グループ以外のすべてのIAMグループのポリシーを変更する必要がある(1グループだけ適用するの忘れていた、となりかねない)
  • 機密情報を格納したいS3バケットが新たに増えたときに、その都度IAMポリシーの中身を書き換える必要がある

Protected BucketのようなS3バケットの新規作成をCloudFormation等を使ってコード管理したいとき、IAMポリシーの設定だけ手動にするというのは手間に感じます。そこでIAMグループ側ではなく、S3バケット側でアクセス制限をかけられるようにしたい!というのが以降説明する内容の動機になります。

Protected Bucketのバケットポリシーを設定する

NotPrincipal要素にワイルドカード(*)は使えない

管理者ユーザ以外のアクセスを拒否したいわけですから、パッと思いつくのは下のような書き方です。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": [
                    "arn:aws:iam::123456789012:root",
                    "arn:aws:iam::123456789012:user/*admin"
                ]
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::protected-bucket/*",
                "arn:aws:s3:::protected-bucket"
            ]
        }
    ]
}

プリンシパル要素と明示的な拒否でワイルドカードを使用するには にあるように、NotPrincipal要素ではワイルドカードはサポートされていないため、このような記法は認められていません。(Principal要素でもワイルドカード使用不可)

ではどう書けばいいのか?

Principalとワイルドカードの相性が悪いので、
"Principal": "*"Condition.StringNotLikeとを組み合わせて表現します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::protected-bucket/*",
                "arn:aws:s3:::protected-bucket"
            ],
            "Condition": {
                "StringNotLike": {
                    "aws:username": "*admin"
                },
                "StringNotEquals": {
                    "aws:userid": "123456789012"
                }
            }
        }
    ]
}

①StringNotLike

"aws:username": "*admin"とすることで、条件*adminにヒットしないIAMユーザに対して明示的にアクセス拒否できます。1

②StringNotEquals

"aws:userid": "123456789012"
なぜこの部分が必要になるかというと、①だけだとルートアカウントもDenyされてしまうからです。
①と②を並べてあげることで、「"条件*adminにヒットしない" かつ "ルートアカウント以外"」すなわち"管理者ユーザ以外の全IAMユーザ"を表現することができます。2

その他参考になる記事

  1. 文字列条件演算子

  2. 複数のキーまたは値を含む条件の評価ロジック (Conditionブロック内に複数の条件がある場合ANDで評価される)

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?