背景
- 機密情報が含まれるファイルを格納する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
その他参考になる記事
- S3バケットへのアクセスを特定IAMユーザにだけ許可して他は弾く
- [AWS] S3バケットポリシーで、特定のIAMロールだけがバケットにアクセス出来るようにする。
- 特定の IAM ロールのみアクセスできる S3 バケットを実装する際に検討したあれこれ
-
複数のキーまたは値を含む条件の評価ロジック (Conditionブロック内に複数の条件がある場合ANDで評価される) ↩