S3で特定のオブジェクトだけGetObjectを許可したかった
はじめに
こんにちは、馬場です!
S3オブジェクトに顧客情報が含まれるようなケースでは、権限管理の中でS3のGetObjectを基本的に拒否したい。ということが考えられると思います。
一方でログやビルド生成物等についても同様にS3で管理している場合、それらについては取得したい。ということも考えられます。
今回私もちょうどこの「基本的にはオブジェクトを取得できないようにしたいが、例外として一部は許可したい」という場面に遭遇して少し手間取ったので、備忘と情報共有を兼ねて記事にします。
結論
先に結論
取得したい一部例外を NotResource で指定して Deny し、Allowでは全てのリソースを許可します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAllS3GetObject",
"Effect": "Allow",
"Action": "s3:Get*",
"Resource": "*"
},
{
"Sid": "DenyGetSpecificObjects",
"Effect": "Deny",
"Action": "s3:GetObject",
"NotResource": [
"arn:aws:s3:::my-app-*/*",
"arn:aws:s3:::logs-*/*"
]
}
]
}
これにより、ログやビルド生成物だけ取得できるような権限を実現できます。
詰まったポイント
詰まっていた際に設定していたポリシーは以下のようなものでした。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAllS3GetObject",
"Effect": "Allow",
"Action": "s3:Get*",
"Resource": "*"
},
{
"Sid": "DenyGetSpecificObjects",
"Effect": "Deny",
"Action": "s3:GetObject",
"Resource": "*",
"Condition": {
"StringNotLike": {
"s3:prefix": [
"my-app-",
"logs-"
]
}
}
}
]
}
パッと見s3のprefixで条件を絞っているため、意図した内容に見えます。
しかし、このIAMポリシーでは意図したとおりに動作しませんでした。
これについて解説していきます。
AmazonS3のアクション、リソース、条件キーのページを見てみると以下のようになっています。
ぶっちゃけこのページを本当の意味でちゃんと見たのは初めてだったのですが、見てわかる通り "s3:prefix" という 条件キー はありません。
なのでそれっぽい条件で設定されているように見えるが、条件の評価をする際に無効な条件式として評価されるため素通りされ、意図した動作をすることができない。という結果になりました。
この時点では Condition を使ってDenyの例外を指定する。というバイアスにはまって「これログ諦めてもらうか?」まで血迷っていましたが、偉大な先輩の「NotResource使えばいけそう!」という発想により、何とか当初の目的の「基本的にはオブジェクトを取得できないようにしたいが、例外として一部は許可したい」を達成することができました!
まとめ
以下ポイントを押さえていくことで、自分の意図するIAMポリシーを複雑な条件でも実現できます!
- IAMポリシーを設定する際に、条件キーまで意識しよう
- Condition以外の条件も活用しよう
最後に
今回のケースでは、なんとなくで見ていたIAMポリシーのAWSドキュメントの読み方が身に染みて分かっりました。また、条件文については発想を転換させることも大事だなとも思います。後10回は同じこと良いそうですが、この記事が同じような状況の誰かの役に立てれば幸いです。
Discussion