目次
IAMポリシーとS3バケットポリシーの関係のまとめ
| 適用場所 | 管理主体 | 優先度 | |
|---|---|---|---|
| IAMポリシー | IAMユーザー/グループ/ロールに設定 | ユーザー側(誰が何をできるか) | デフォルト拒否。IAMポリシーにAllowがないと不可 | 
| S3バケットポリシー | S3バケット(リソース側)に設定 | リソース側(このバケットに誰がアクセスできるか) | リソースポリシーでDenyがあればIAMのAllowより優先して拒否される | 
IAMポリシーとは
ユーザー / グループ / ロール に「どんな操作が許されるか」を定義するルール集です。
形式は JSON ドキュメントで記述されます。
IAMポリシーの例
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::example-bucket/*"
    }
  ]
}
効果 (Effect) → 許可
操作 (Action) → s3:GetObject(S3のオブジェクト取得)
対象 (Resource) → example-bucket 配下のすべてのオブジェクト
IAMポリシーの構成
| Version | ポリシー言語のバージョン。通常 "2012-10-17" を使用します。 | 
| Statement | 実際のルールの定義。1つ以上の文(ステートメント)を持つことができます。 | 
Statement(ステートメント)の中身
| Effect | Allow または Deny(許可か拒否か) | 
| Action | 許可/拒否する操作(例: "s3:PutObject", "ec2:StartInstances") | 
| Resource | 操作対象のリソース(ARNで指定) | 
| Condition | 特定の条件下でのみ適用する場合の制約(例: IPアドレス、時刻、MFA認証など) | 
仕様
デフォルト拒否: 何も許可されていない状態からスタート
明示的な許可が必要: Allowがないと操作不可
明示的な拒否が最優先: どんなAllowがあっても、Denyがあれば拒否される
S3バケットポリシーとは
S3バケットに直接追加するするポリシーです。
JSON形式で記述し、誰(Principal)がバケットやオブジェクトに対して、どの操作(Action)を、どの条件でできるかを制御します。
クロスアカウントアクセスや匿名アクセス(インターネット公開)を許可したいときによく使います。
S3バケットポリシーの例
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ExampleStatement01",
      "Effect": "Allow",
      "Principal": {"AWS": "arn:aws:iam::123456789012:root"},
      "Action": ["s3:GetObject"],
      "Resource": ["arn:aws:s3:::example-bucket/*"],
      "Condition": {
        "IpAddress": {"aws:SourceIp": "203.0.113.25/32"}
      }
    }
  ]
}
Version: ポリシー言語のバージョン(通常 "2012-10-17")
Statement: ルールのかたまり
Effect: Allow または Deny
Principal: 許可対象(ユーザー、ロール、アカウント、*=全員)
Action: 実行可能な操作(例: "s3:GetObject", "s3:PutObject")
Resource: バケットやオブジェクトをARNで指定
Condition: 条件(例: IP制限、TLS必須、特定VPCエンドポイントなど)
評価方法
上から順に評価するわけではありません。
すべてのステートメントを評価します。Denyがあれば拒否されます。
DenyとNotの組み合わせ
{
  "Effect": "Deny",
  "Principal": "*",
  "Action": "s3:*",
  "Resource": [
    "arn:aws:s3:::bucket-name",
    "arn:aws:s3:::bucket-name/*"
  ],
  "Condition": {
    "NotIpAddress": {
      "aws:SourceIp": [
        "203.0.113.22/32",
        "203.0.113.23/32"
      ]
    }
  }
上記のバケットポリシーは、2行目のEffectのDenyと10行目のNotIpAddressの指定で、12,13行目のIPアドレスのときのみアクセスできる例です。
2行目のEffect:Denyは、明示的に拒否することを意味します。
明示的な拒否は、どのような許可(Allow)よりも常に優先されます。
3行目は、すべてのプリンシパル(ユーザー、ロール、サービスなど)に適用されます。
4行目は、S3に対するすべてのアクション(操作)を対象とします。
9行目のConditionは、この拒否のルールが適用される条件を定義します。
→拒否を発動させるトリガー条件。
10行目は、先頭にNotがあるため、12,13行目以外のIPアドレスの場合は拒否されます。
まとめると、12,13行目「以外」のIPアドレスの場合は、全てのプリンシパルのS3の操作は拒否されます。
ただし、そのIPからのリクエストは「拒否しないだけ」で、別途どこかで Allow(IAMユーザー/ロール、または同バケットポリシーの許可文)が必要です。
注意
9行目のCondition以下がない場合は、全てのユーザのS3操作を拒否になってしまい、どんなIAMユーザーやロールでも一切アクセスできなくなってしまいます。
ベストプラクティス
Allowを基本にして必要最小限で許可します(最小権限の原則)。
Deny+Notは「例外を拒否する」「特定条件外を締め出す」など明確なセキュリティ制約が必要な場合のみ使用します。
明示的な拒否
Deny+NotでIPアドレスを指定した場合は、明示的な拒否となり、ACL(バケット、オブジェクト)にパブリクアクセスの設定があっても、明示的な拒否が優先されます。
関連の記事
AWS S3へのアクセスの設定(IAMポリシーとバケットポリシー)
AWS S3のアカウント間コピー時のバケットポリシーの設定
