はじめに
S3のアクセス制御には、IAMポリシーとS3バケットポリシーがありますよね。
どちらでもS3へのアクセス権限を設定できるため、
「結局、どちらに権限を書けばいいの?」
と迷うことがあります。
実際の環境でも、IAMポリシーとバケットポリシーの両方に同じようなAllowが設定され、
どこで権限を管理しているのか分かりにくくなっているケースがあります。
この記事では、両者の違いと、実際にどう使い分けるべきかを整理します。
先に結論
ざっくりですが、次のように分けると整理しやすいです。
| やりたいこと | 検討するポリシー |
|---|---|
| このRoleに何をさせるか | IAMポリシー |
| このバケットを誰に公開するか | バケットポリシー |
| この条件ではアクセスさせない | バケットポリシー |
| 別アカウントにリソースを公開する | AMポリシー + バケットポリシー |
特に、単一アカウント内でアプリケーションRoleにS3へのアクセス権を与えるだけなら、
IAMポリシーを中心に設計すると、権限の管理場所を集約しやすくなります。
「S3ではIAMポリシーを使うべき」と決めているというわけではありません。
重要なのは、どちらを使うかではなく、どこを権限管理の責任範囲にするかです。
IAMポリシーとバケットポリシーの違い
両者の大きな違いは、どちらを起点に権限を定義するかです。
IAMポリシー
IAMポリシーはIdentity-based policyなので、以下のように「このRoleに何を許可するか」を定義します。
AppRole
↓
s3:GetObject
↓
Bucket
バケットポリシー
バケットポリシーはResource-based policyなので、「このS3バケットに誰がアクセスできるか」を定義します。
Bucket
↓
AppRoleからのアクセスを許可
IAMポリシーとバケットポリシーの両方にAllowが設定された場合は?
例えば、同一アカウント内で次のような設定があったとします。
IAM Policy
└─ s3:GetObject Allow
Bucket Policy
└─ s3:GetObject Allow
Allowを両方に書いたからと言って、権限が2倍になるわけではありません。
そのため、単純な同一アカウント内のアクセスであれば、同じAllow設定はあまり意味のないものになります。
むしろ問題になるのは、
同じ権限を複数個所で管理することで、権限の管理が難しくなることです。
バケットポリシーはいつ使う?
1. クロスアカウントアクセス
例えば、以下のような構成です。
Account A
AppRole
↓
Account B
S3 Bucket
この場合、Account AのIAMポリシーだけでは完結しません。
Account A側でRoleにS3へのアクセスを許可し、Account B側のバケットポリシーでも、そのRoleからのアクセスを許可する必要があります。
つまり、クロスアカウントでは、
「アクセス元のIAMポリシー」+「アクセス先のバケットポリシー」 という設計になります。
2. S3側でガードレールを設定する
例えば、
「このバケットにはHTTPS通信でしかアクセスさせない」
という要件です。
この場合は、バケットポリシーで明示的なDenyを設定できます。
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::example-bucket",
"arn:aws:s3:::example-bucket/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
}
IAMポリシーでAllowされていても、明示的なDenyがあればアクセスは拒否されます。
よくあるアンチパターン
IAMポリシーとバケットポリシーに同じAllowを二重に書く
例えば以下のような状態です。
IAM Policy
Allow s3:GetObject
+
Bucket Policy
Allow s3:GetObject
単一アカウント内の単純なアクセスであれば、
まず「なぜ両方必要なのか」を疑った方がいいでしょう。
バケットポリシーにPrincipalを大量に書く
例えば以下のような状態です。
Bucket Policy
├─ RoleA
├─ RoleB
├─ RoleC
├─ RoleD
├─ RoleE
└─ RoleF
このような状態になると、バケットポリシーがPrincipal管理台帳になってしまいます。
単に各Roleのアクセス権をすべてバケットポリシーに寄せているのであれば、
設計を見直す余地があります。
まとめ
IAMポリシーとS3バケットポリシーは、単純に「どちらが正しい」というものではありません。
次のように使い分けると分かりやすくなります。
| 要件 | 主に使うもの |
|---|---|
| アプリケーションRoleにS3権限を与える | IAMポリシー |
| クロスアカウントアクセス | IAMポリシー + バケットポリシー |
| HTTPS以外を禁止する | バケットポリシー |
| 特定のVPC Endpoint以外を禁止する | バケットポリシー |
「S3だからバケットポリシーを使う」のではなく、
どこで権限を管理するのが自然なのかという観点で設計すると、
ポリシーの重複や複雑化を防ぎやすくなります。
参考
AWS Security Blog: IAM Policies and Bucket Policies and ACLs! Oh, My!