⚡ 結論ファースト:これだけは覚えて!
IAMのAllowは強力
IAMポリシーでAllowされていると、リソースポリシーで明示的にDenyしない限りアクセスが許可される
Denyは明示的に書く
タグ条件を確実に適用するには、バケットポリシーに「条件を満たさない場合はDeny」のルールが必須
Allow + Allowは危険
IAMでPutObject許可 + バケットポリシーにDenyなし = タグ条件が無視される
🏨 たとえ話:高級ホテルのVIPラウンジ
AWSのポリシー評価を「ホテルのセキュリティシステム」に例えて理解しましょう!
社員証(IAMポリシー)と各部屋のロック(リソースポリシー)の関係がポイントです。
🏨 AWS リゾートホテル
社員証(IAMポリシー)
IAM Policy
入社時に発行される「基本アクセス権」
例:「この人は従業員なので、
S3バケットにファイルをアップロードできます」
👤 ユーザー・ロールに紐付く
例:「この人は従業員なので、
S3バケットにファイルをアップロードできます」
👤 ユーザー・ロールに紐付く
各部屋のロック(リソースポリシー)
S3 Bucket Policy
各部屋に設置された「追加のセキュリティ」
例:「VIPラウンジには
VIPタグがある人だけ入れます」
📦 リソース(S3等)に紐付く
例:「VIPラウンジには
VIPタグがある人だけ入れます」
📦 リソース(S3等)に紐付く
❌ 問題のシナリオ:なぜタグ条件が効かない?
1
👤 田中さんが来館(IAMユーザー)
田中さんは「Project=Alpha」タグを持つユーザーです。
「Project=Beta」のファイルをアップロードしようとしています。
「Project=Beta」のファイルをアップロードしようとしています。
2
🪪 社員証チェック(IAMポリシー評価)
IAMポリシー:
「田中さんは従業員なので、S3へのアップロードOK!」
"Action": "s3:PutObject", "Effect": "Allow"「田中さんは従業員なので、S3へのアップロードOK!」
✅ Allow
3
🚪 VIPラウンジのドアチェック(バケットポリシー評価)
バケットポリシー:「VIPタグがある人は入れます」(Allowのみ)
「VIPタグがない人はダメ」というDenyルールがない!
「VIPタグがない人はダメ」というDenyルールがない!
⚠️ Denyなし
4
🚨 結果:タグが違うのに入れてしまった!
IAMでAllowされているため、バケットポリシーにDenyがなければ
タグ条件を満たさなくてもアクセスが許可されてしまう
タグ条件を満たさなくてもアクセスが許可されてしまう
✅ 許可(意図しない)
🧮 AWSポリシー評価の仕組み
IAM × リソースポリシーの評価フロー
重要な原則:「明示的Deny」が最優先
AWSでは「明示的なDenyは常に最優先」ですが、逆に言うとDenyがなければ、どちらかがAllowすればアクセス可能になります。これが落とし穴の原因です!
📊 同一アカウント内のポリシー評価フロー
🔍 アクセスリクエスト発生
⬇️
明示的
Deny?
Deny?
Yes(どちらかにDenyあり)
⬇️
🚫 アクセス拒否
No(Denyなし)
⬇️
IAMか
リソースで
Allow?
リソースで
Allow?
Yes(どちらかでAllow)
⬇️
✅ アクセス許可
No(両方とも沈黙)
⬇️
🚫 暗黙の拒否
| IAMポリシー | リソースポリシー | 最終結果 | 説明 |
|---|---|---|---|
| Allow | Allow | ✅ Allow | 両方許可 → アクセス可能 |
| Allow | 条件なし(沈黙) | ✅ Allow | ⚠️ IAMのAllowだけで通る! |
| Allow | Deny | 🚫 Deny | 明示的Denyが優先 |
| 条件なし | Allow | ✅ Allow | リソースポリシーのAllowで通る |
| Deny | Allow | 🚫 Deny | 明示的Denyが優先 |
✅ 解決策:明示的Denyを追加する
❌ NG:Allowのみのバケットポリシー
「VIPの人は入れます」
VIPじゃない人はどうする?→ 規定なし
社員証があれば誰でも入れてしまう!
✅ OK:明示的Denyありのバケットポリシー
「VIPの人は入れます」
「VIPじゃない人は絶対入れません」
明示的Denyにより確実にブロック!
NGパターン:Allowのみ
タグが一致する場合のみAllowを書いても、IAMポリシーでAllowされていると素通りしてしまいます。
❌ 効果が薄いバケットポリシー
JSON
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"StringEquals": {
// タグ一致時にAllowするだけ
"s3:RequestObjectTag/Project": "${aws:PrincipalTag/Project}"
}
}
}
OKパターン:明示的Deny追加
タグが一致しない場合は明示的にDenyすることで、IAMのAllowを上書きしてブロックできます。
✅ 安全なバケットポリシー
JSON
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"StringNotEquals": {
// タグ不一致時は明示的にDeny!
"s3:RequestObjectTag/Project": "${aws:PrincipalTag/Project}"
}
}
}
明示的Denyの効果
明示的DenyはすべてのAllowより優先されます。IAMポリシーでどれだけAllowしていても、リソースポリシーの明示的Denyは必ず勝ちます。これにより、タグベースのアクセス制御を確実に実施できます。
📋 完全なポリシー設定例
🔒 タグベースアクセス制御の完全なバケットポリシー
JSON
{
"Version": "2012-10-17",
"Statement": [
{
// ステートメント1:タグ不一致時の明示的Deny(最重要!)
"Sid": "DenyMismatchedProjectTag",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::project-data-bucket/*",
"Condition": {
"StringNotEquals": {
// ユーザーのProjectタグとオブジェクトのProjectタグが一致しない場合
"s3:RequestObjectTag/Project": "${aws:PrincipalTag/Project}"
}
}
},
{
// ステートメント2:タグなしアップロードの拒否(オプション推奨)
"Sid": "DenyNoProjectTag",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::project-data-bucket/*",
"Condition": {
"Null": {
// オブジェクトにProjectタグがない場合は拒否
"s3:RequestObjectTag/Project": "true"
}
}
}
]
}
🎯 ベストプラクティス
Denyファースト設計
タグベースのアクセス制御では、必ず「条件を満たさない場合のDeny」から書き始める。Allowだけでは不十分。
タグ必須ポリシー
オブジェクトにタグがない場合もDenyする。タグ付け漏れによるセキュリティホールを防止。
IAMポリシーの見直し
IAMポリシーで広範なAllowを与えている場合は特に注意。最小権限の原則を再確認。
テスト環境で検証
Policy Simulatorや実際のテストで、タグ不一致時にアクセスが拒否されることを必ず確認。
❓ よくある質問
なぜAllowだけではタグ条件が効かないのですか?
同一アカウント内では、IAMポリシーかリソースポリシーのどちらかがAllowすればアクセス可能になります。バケットポリシーに「タグ一致時のみAllow」と書いても、IAMポリシーで既にAllowされていれば、バケットポリシーの条件は評価されずに通過してしまいます。明示的Denyのみがこれを阻止できます。
クロスアカウントアクセスでも同じ問題が起きますか?
いいえ、クロスアカウントアクセスでは事情が異なります。クロスアカウントの場合は両方のポリシーでAllowが必要です。しかし、明示的Denyを書くのはベストプラクティスとして推奨されます。
SCPやPermissions Boundaryでも同様のことが起きますか?
SCP(Service Control Policy)やPermissions Boundaryは「許可の上限」として機能します。これらにAllowがなければ、IAMポリシーでAllowしてもアクセスできません。ただし、これらもDenyは明示的に書く必要があり、同様の注意が必要です。
どうやってポリシーをテストすればいいですか?
IAM Policy Simulatorを使用するか、テスト用のIAMユーザー/ロールで実際にアクセスを試みます。タグが一致するケース・一致しないケースの両方をテストし、期待通りに許可/拒否されることを確認してください。
📚 まとめ:3つの鉄則
IAMのAllowは強力
IAMポリシーでAllowされていると、リソースポリシーで明示的にDenyしない限りアクセス可能になる
必ず明示的Denyを書く
タグ条件を確実に適用するには「条件を満たさない場合はDeny」のルールが必須
テストで確認する
タグ不一致時にアクセスが拒否されることを必ずテストで検証する
🔐 AWS IAMポリシー vs リソースポリシー - 明示的Denyの重要性 完全図解ガイド
このガイドがAWSセキュリティの理解に役立てば幸いです!