SAA S3 アクセス制御設計パターン5選|バケットポリシー・Access Points・Presigned URL・VPC Endpoint・クロスアカウント完全攻略

AWS SAA-C03 で頻出の S3 アクセス制御を完全整理。「誰が・どこから・何に対して」の3軸フレームワークで、バケットポリシー × Block Public Access・S3 Access Points・Presigned URL・VPC エンドポイントポリシー・クロスアカウント IAM ロールの5パターンを体系化。Object Ownership による ACL 廃止の現代的推奨まで、試験頻出シナリオを解法パターン早見表で一気に整理する。

「S3 のアクセス制御は IAM だけではない。バケットポリシー・ACL・Access Points・Presigned URL・VPC エンドポイントポリシーを組み合わせた多層防御が SAA の最頻出テーマだ」 — 本記事では「誰が(Principal)・どこから(ネットワーク)・何に対して(バケット/オブジェクト粒度)」の3軸フレームワークで5つの設計パターンを体系化し、試験で迷わず正解を選べる反射を身につける。

※ 本記事はアフィリエイト広告(Amazon アソシエイト等)を含みます


📑 目次

  1. 結論:S3 アクセス制御の3軸フレームワーク
  2. パターン1:バケットポリシー × Block Public Access(公開遮断の標準構成)
  3. パターン2:S3 Access Points(大規模データレイクの多チームアクセス管理)
  4. パターン3:Presigned URL(期限付き一時アクセスの安全な委任)
  5. パターン4:VPC エンドポイントポリシー(プライベートアクセス強制)
  6. パターン5:クロスアカウントアクセス制御(二重許可モデル)
  7. Object Ownership と ACL の廃止(現代的 S3 セキュリティの前提)
  8. 試験頻出シナリオ → 解法パターン早見表
  9. 次のアクション チェックリスト
  10. 関連記事
  11. 関連サイト

1. 結論:S3 アクセス制御の3軸フレームワーク

S3 のアクセス制御設問は「誰が(Principal)・どこから(ネットワーク)・何に対して(バケット/オブジェクト粒度)」の3軸で解く。

問いかけ主なメカニズム
誰が(Principal)同一アカウント?クロスアカウント?パブリック?IAM ポリシー、バケットポリシー、ACL(廃止推奨)
どこから(ネットワーク)インターネット?VPC 内のみ?特定 VPC エンドポイント?Block Public Access、VPC エンドポイントポリシー
何に対して(粒度)バケット全体?特定プレフィックス?一時的なオブジェクト?S3 Access Points、Presigned URL

S3 のアクセス判断ロジック(ポリシー評価の順序):

1. 明示的 DENY(どのポリシーでも)→ 即アクセス拒否
2. 明示的 ALLOW が存在する       → 許可
3. それ以外                       → 暗黙的 DENY(デフォルト拒否)

クロスアカウントアクセスでは IAM ポリシー(リクエスト元アカウント)バケットポリシー(バケット所有アカウント) の両方が ALLOW していなければならない。どちらか一方では不十分。


2. パターン1:バケットポリシー × Block Public Access(公開遮断の標準構成)

適用シナリオ

  • バケットを完全にプライベートに保ち、特定の IAM エンティティのみアクセスを許可したい
  • 誤操作による公開設定を組織レベルで防止したい
  • S3 をバックエンドとした EC2/Lambda からのアクセスのみ許可したい

アーキテクチャ

[IAM ロール (EC2/Lambda)] → [バケットポリシー(許可)] → [S3 バケット]

                    Block Public Access(4設定すべて ON)で
                    インターネットからの到達を遮断

Block Public Access の4設定

設定効果
BlockPublicAcls新規オブジェクトへのパブリック ACL 付与をブロック
IgnorePublicAcls既存のパブリック ACL を無視
BlockPublicPolicyパブリックアクセスを許可するバケットポリシーをブロック
RestrictPublicBucketsパブリックバケットポリシーがあっても、公開アクセスを制限

バケットポリシーの基本構造

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/MyEC2Role"
      },
      "Action": ["s3:GetObject", "s3:PutObject"],
      "Resource": "arn:aws:s3:::my-bucket/*"
    }
  ]
}

3. パターン2:S3 Access Points(大規模データレイクの多チームアクセス管理)

適用シナリオ

  • 1 つのバケットに複数チームがアクセスし、それぞれ異なるプレフィックスへのアクセス権限が必要
  • バケットポリシーが巨大化・複雑化して管理が困難になっている
  • チームごとに VPC 経由のみのアクセス制限を設けたい

S3 Access Points の仕組み

[チームA IAM ロール] → [Access Point A(プレフィックス: /team-a/*)] ─→ [S3 バケット]
[チームB IAM ロール] → [Access Point B(プレフィックス: /team-b/*)] ─→ [同一バケット]
[チームC IAM ロール] → [Access Point C(VPC 限定)]                  ─→ [同一バケット]

Access Points の二重許可モデル

Access Points が機能するには バケットポリシーと Access Point ポリシーの両方 が ALLOW していなければならない。

// バケットポリシー側:Access Point からのアクセスを委任
{
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"AWS": "*"},
    "Action": "s3:*",
    "Resource": ["arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*"],
    "Condition": {
      "StringLike": {
        "s3:DataAccessPointArn":
          "arn:aws:s3:ap-northeast-1:123456789012:accesspoint/*"
      }
    }
  }]
}
// Access Point ポリシー側:チームA に /team-a/* の権限を付与
{
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"AWS": "arn:aws:iam::123456789012:role/TeamARole"},
    "Action": ["s3:GetObject", "s3:PutObject"],
    "Resource":
      "arn:aws:s3:ap-northeast-1:123456789012:accesspoint/team-a-ap/object/team-a/*"
  }]
}

Access Points の VPC 限定設定

Access Point に VPC を指定すると、その Access Point は指定 VPC からのリクエストのみを受け付ける。

// Access Point 作成時の VPC Configuration(AWS CLI/SDK での設定例)
{
  "VpcConfiguration": {
    "VpcId": "vpc-xxxxxxxx"
  }
}

4. パターン3:Presigned URL(期限付き一時アクセスの安全な委任)

適用シナリオ

  • 認証されたユーザーに、一定時間だけ特定オブジェクトへのダウンロード・アップロード権限を付与したい
  • S3 バケットをプライベートに保ちつつ、外部ユーザーにコンテンツを共有したい
  • フロントエンドから直接 S3 にアップロードさせたい(アプリサーバー経由を避けたい)

Presigned URL の仕組み

① Lambda/EC2 が Presigned URL を生成(署名者の IAM 認証情報で署名)
② URL をクライアントに返す
③ クライアントが Presigned URL を使って S3 へ直接アクセス
   (有効期限: IAM ユーザー最大 7日、IAM ロールは最大 12時間)

CloudFront Signed URL vs S3 Presigned URL

比較軸S3 Presigned URLCloudFront Signed URL
経路S3 直接CloudFront → S3(OAC 経由)
有効期限の最大7日(IAM ユーザー) / 12時間(ロール)任意に設定可能
IP 制限不可可(IP アドレス範囲を指定)
コンテンツ保護強度高(CloudFront OAC でバケット直接アクセスを封鎖)
CDN キャッシュなしあり(エッジからの高速配信)

5. パターン4:VPC エンドポイントポリシー(プライベートアクセス強制)

適用シナリオ

  • VPC 内のリソース(EC2・ECS・Lambda in VPC)が S3 へアクセスする際、インターネットを経由させたくない
  • 特定のバケットのみ VPC 内からアクセスを許可し、インターネットからの直接アクセスを拒否したい
  • 規制要件でデータをプライベートネットワーク内のみに閉じる必要がある

Gateway 型 vs Interface 型 VPC エンドポイント

比較軸Gateway エンドポイントInterface エンドポイント(PrivateLink)
対象サービスS3・DynamoDB のみ200 以上の AWS サービス + カスタム
料金無料時間課金 + データ転送料
ルーティングルートテーブルに自動追加ENI(プライベート IP)で接続
DNS 解決パブリック DNS のまま(ルートでバイパス)プライベート DNS で解決
オンプレ経由不可DX/VPN 経由でアクセス可能

VPC エンドポイントポリシーによるアクセス制限

パターン4-A:特定 VPC エンドポイント経由のみ許可(バケットポリシー側)

{
  "Statement": [{
    "Effect": "Deny",
    "Principal": "*",
    "Action": "s3:*",
    "Resource": [
      "arn:aws:s3:::my-secure-bucket",
      "arn:aws:s3:::my-secure-bucket/*"
    ],
    "Condition": {
      "StringNotEquals": {
        "aws:SourceVpce": "vpce-xxxxxxxx"
      }
    }
  }]
}

パターン4-B:特定 VPC 全体からのみ許可(aws:SourceVpc 条件)

{
  "Condition": {
    "StringNotEquals": {
      "aws:SourceVpc": "vpc-xxxxxxxx"
    }
  }
}

VPC エンドポイントポリシー側:特定バケットのみアクセスを許可

{
  "Statement": [{
    "Effect": "Allow",
    "Principal": "*",
    "Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"],
    "Resource": [
      "arn:aws:s3:::my-secure-bucket",
      "arn:aws:s3:::my-secure-bucket/*"
    ]
  }]
}

6. パターン5:クロスアカウントアクセス制御(二重許可モデル)

適用シナリオ

  • アカウント A のバケットに、アカウント B の EC2/Lambda からアクセスさせたい
  • データ集約バケットに複数の子アカウントからデータを書き込ませたい(マルチアカウントアーキテクチャ)
  • サードパーティ SaaS に一部のデータへのアクセスを許可したい

二重許可モデルの仕組み

[アカウントB: EC2]
  ↓ ① AssumeRole → アカウントB の IAM ロール(s3:GetObject 許可)
  ↓ ② アカウントA バケットへリクエスト
[アカウントA: S3 バケットポリシー]
  → アカウントB のロール ARN を ALLOW
  → アクセス成功

クロスアカウントでは 必ず両方が ALLOW でなければならない:

チェックポイント設定先
① リクエスト元 IAM ポリシーで S3 操作を許可アカウント B の IAM ロールポリシー
② バケットポリシーでアカウント B のプリンシパルを許可アカウント A のバケットポリシー

バケットポリシー(アカウント A)の例

{
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "AWS": "arn:aws:iam::ACCOUNT_B_ID:role/CrossAccountRole"
    },
    "Action": ["s3:GetObject", "s3:PutObject"],
    "Resource": "arn:aws:s3:::account-a-bucket/*"
  }]
}

クロスアカウント + S3 Access Points の組み合わせ

クロスアカウントシナリオで複数の接続元を管理する場合、S3 Access Points を使うとバケットポリシーを Access Point ポリシーに委任でき、アカウントごとに Access Point を分けて管理できる。


7. Object Ownership と ACL の廃止(現代的 S3 セキュリティの前提)

ACL は廃止推奨

AWS は現在、ほとんどのユースケースで ACL の使用を推奨していない。新規バケットはデフォルトで「Bucket owner enforced(ACL 無効)」設定で作成される。

Object Ownership 設定ACL動作
Bucket owner enforced(推奨)無効すべてのオブジェクトはバケット所有者が所有。バケットポリシーで制御
Object writer有効オブジェクトをアップロードした IAM エンティティが所有
Bucket owner preferred有効アップロード時に bucket-owner-full-control ACL があればバケット所有者が所有

8. 試験頻出シナリオ → 解法パターン早見表

シナリオ(要件文キーワード)正解パターン落とし穴
「プライベートバケットのオブジェクトをアプリユーザーに一時的に配布したい」Presigned URLバケットポリシーでパブリック公開は NG
「VPC 内からのみ S3 アクセスを許可し、インターネット経由を遮断したい」Gateway VPC エンドポイント + aws:SourceVpce 条件のバケットポリシーInterface エンドポイントは有料(コスト最適化設問では誤答になりやすい)
「複数チームが1つのバケットにアクセスするが、プレフィックスごとに権限を分けたい」S3 Access Pointsバケットポリシーで委任しないと動かない(二重許可モデル)
「別アカウントの Lambda からバケットにデータを書き込みたい」IAM ロール(AssumeRole) + バケットポリシー(両方 Allow)どちらか一方だけでは不可
「クロスアカウントで PutObject してもバケット所有者がアクセスできるようにしたい」Object Ownership: Bucket owner enforcedACL で bucket-owner-full-control を要求する古いパターンも動くが、現代的推奨は Object Ownership
「特定 IP アドレスからのアクセスのみ許可したい」バケットポリシーに aws:SourceIp 条件VPC エンドポイント経由は aws:SourceIp が機能しないことがある(aws:SourceVpce を使う)
「バケットポリシーを書かずに S3 をプライベートに保ちたい」Block Public Access(全4設定 ON)デフォルトでも ON だが、明示的に確認する必要がある設問あり
「S3 へのアクセスをコスト効率よくプライベートネットワーク経由にしたい」Gateway VPC エンドポイント(無料)Interface エンドポイントを選ぶと誤答

9. 次のアクション チェックリスト

  • S3 バケットで Block Public Access の全4項目が ON になっているか確認
  • ACL が無効化され、Object Ownership が「Bucket owner enforced」になっているか確認
  • クロスアカウントアクセスで「IAM ポリシー AND バケットポリシー」の二重許可を設定したか
  • VPC 内から S3 へのアクセスに Gateway VPC エンドポイントを使っているか(インターネット経由を排除)
  • Presigned URL の有効期限を最小限に設定しているか(長期共有なら CloudFront Signed URL を検討)
  • 複数チームへのアクセス管理に S3 Access Points を活用しているか(バケットポリシーの複雑化を防ぐ)

10. 関連記事


11. 関連サイト

出典・参考情報