S3バケットへのアクセスを特定IAMユーザにだけ許可したい
課題
単純に考えると、バケットポリシーを次のようにすれば、s3-audit ユーザだけがアクセスできる xxxx-audit バケットが作れそうである。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxx:user/s3-audit"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::xxxx-audit",
"arn:aws:s3:::xxxx-audit/*"
]
}
]
}
しかしコレだけだと、実は PowerUser ロールなど S3 へのアクセスポリシーがついている IAM ユーザなら誰でもアクセスすることができてしまう。
バケットへのアクセス権限は、IAM ポリシーとバケットポリシーの複合になるので(正確にはもっと色々関わる)、IAMポリシーで許可が出ているとダメである。
BucketPolicy | IAM | 結果 |
---|---|---|
拒否 | 拒否 | 失敗 |
拒否 | 許可 | 失敗 |
許可 | 拒否 | 失敗 |
許可 | 許可 | 成功 |
未設定 | 拒否 | 失敗 |
未設定 | 許可 | 成功 |
ref. http://dev.classmethod.jp/cloud/aws/s3-acl-wakewakame/
※ IAMポリシーで許可が出ていると、BucketPolicyが未設定でも、通ってしまう(成功)点に注目
解答
正解は次のようになる。Principal: "*"
とした Deny の中で、"aws:username": "s3-audit"
のように s3-audit ユーザだけ除外しているのがポイント。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxx:user/s3-audit"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::xxxx-audit",
"arn:aws:s3:::xxxx-audit/*"
]
},
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::xxxx-audit/*"
],
"Condition": {
"StringNotEquals": {
"aws:username": "s3-audit"
}
}
}
]
}
補足
前述の解答だと、Deny の方の Resource に arn:aws:s3:::xxxx-audit
を指定していないので、ListBucket はできてしまう (PowerUser な人が Web Console から bucket にあるオブジェクトの一覧を見れてしまう。ダウンロードはできない)。
arn:aws:s3:::xxx-audit
を指定しなかったのは、これをやると terraform を apply しているユーザもアクセスできなくなって、ポリシーを変更できなくなってしまうため。
以下のように StringNotEquals に terraform 用の IAM アカウントも指定すれば問題ないといえばないのだけど、terraform 用の IAM アカウントからもバケットにアクセスできるようになってしまって、表題の要件を満たせなくなる。悩ましい。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxx:user/s3-audit"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::xxxx-audit",
"arn:aws:s3:::xxxx-audit/*"
]
},
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
+ "arn:aws:s3:::xxxx-audit",
"arn:aws:s3:::xxxx-audit/*"
],
"Condition": {
"StringNotEquals": {
- "aws:username": "s3-audit"
+ "aws:username": ["s3-audit", "terraform-user"]
}
}
}
]
}