security
A
信頼度ランク
| S | 公式ソース確認済み |
| A | 成功実績多数・失敗例少数 |
| B | 賛否両論 |
| C | 動作未確認・セキュリティリスク高 |
| Z | 個人所感 |
S3バケットポリシー vs IAMポリシー — 優先順位・使い分け・組み合わせパターン
S3アクセス制御のバケットポリシーとIAMポリシーの評価ロジック、同一アカウントとクロスアカウントの違い、ACLとの関係、バケットポリシーが必要なケースを具体例で解説。
一言結論
S3のクロスアカウントアクセスはバケットポリシーとIAMポリシーの両方のAllowが必須であり、Block Public AccessはポリシーのAllowより優先されるため、VPCエンドポイント経由のみを強制したい場合はバケットポリシーでaws:SourceVpce条件のDenyを使うのが正しいアプローチだ。
S3アクセス制御の全体像
S3アクセス制御には複数のレイヤーがある。
1. バケットポリシー(リソースベース)
2. IAMポリシー(アイデンティティベース)
3. S3 ACL(Access Control List)← レガシー、現在は非推奨
4. アクセスポイントポリシー
5. S3 Block Public Access設定
評価ロジックの基本
同一アカウント内:
バケットポリシー OR IAMポリシーの一方がAllowでOK
(明示的Denyがなければ)
クロスアカウント:
バケットポリシー AND IAMポリシーの両方がAllow必須
バケットポリシーを使うべきケース
IAMポリシーだけではできない制御をバケットポリシーで実現する。
ケース1: パブリックアクセスの制御
// 静的ウェブサイト公開(特定バケットをパブリックに)
{
"Statement": [{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-website-bucket/*"
}]
}
ケース2: VPCエンドポイント経由のみ許可
{
"Statement": [{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::secure-bucket",
"arn:aws:s3:::secure-bucket/*"
],
"Condition": {
"StringNotEquals": {
"aws:SourceVpce": "vpce-0123456789abcdef0"
}
}
}]
}
ケース3: HTTPSのみ許可(HTTP経由を拒否)
{
"Statement": [{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
}]
}
ケース4: クロスアカウントアクセス
// 別アカウントのロールにアクセス許可
{
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::987654321098:role/DataProcessingRole"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}]
}
ケース5: 特定のKMSキーによる暗号化を強制
{
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"StringNotEqualsIfExists": {
"s3:x-amz-server-side-encryption-aws-kms-key-id":
"arn:aws:kms:ap-northeast-1:123456789012:key/xxx"
}
}
}
]
}
S3 Block Public Access の優先度
Block Public Access設定はバケットポリシーより優先される
バケットレベルとアカウントレベルの2段階で設定可能:
アカウントレベル: 全バケットに適用(推奨: 全てBlockに設定)
バケットレベル: 個別のバケットに設定
BlockPublicAcls: ACLによるパブリックアクセスをブロック
IgnorePublicAcls: 既存のパブリックACLを無視
BlockPublicPolicy: パブリックポリシーの設定をブロック
RestrictPublicBuckets: パブリックバケットへの匿名アクセスをブロック
# アカウントレベルでBlock Public Accessを有効化
aws s3control put-public-access-block \
--account-id 123456789012 \
--public-access-block-configuration '{
"BlockPublicAcls": true,
"IgnorePublicAcls": true,
"BlockPublicPolicy": true,
"RestrictPublicBuckets": true
}'
ACLはいつ使うか
S3 ACLは現在非推奨で、デフォルトで無効化されている(Object Ownership: Bucket owner enforced)。
非推奨の理由:
- バケットポリシーで同じことが細かく実現できる
- 管理が複雑(各オブジェクトにACLが付く)
- クロスアカウントのオブジェクル所有権問題が発生しやすい
有効に残っているケース:
- CloudFrontのアクセスログ(OAIを使う古い設定)
- 一部のレガシーシステム
バケットポリシーのサイズ制限
バケットポリシーは20KBの制限がある。複雑なポリシーがこの制限に達した場合は、IAMポリシーへの分散やポリシーの整理が必要だ。
試験頻出パターン
| シナリオ | 解決策 |
|---|---|
| Organizationsメンバーのみアクセス可 | バケットポリシーに aws:PrincipalOrgID 条件 |
| VPCエンドポイント経由のみ許可 | aws:SourceVpce 条件でDeny |
| HTTPS強制 | aws:SecureTransport: false でDeny |
| 特定プレフィックスへの書き込みのみ許可 | s3:prefix 条件とPutObjectのAllow |
まとめ
S3のアクセス制御はバケットポリシーとIAMポリシーを適切に組み合わせることで実現される。クロスアカウントは両方のAllow必須という原則と、Block Public AccessがポリシーのAllow設定より優先されることを確実に理解しておく。