Dev Study
AWSサービスの内部原理 コース

56. IAMはデフォルト拒否の判定機である — 明示的Deny > Allow > 暗黙のDeny

すべてのリクエストは最初から拒否されている、という前提から出発するIAMの判定コードが、どんな順番で「例外的に許可してよいか」を確かめていくのかを図で追っていきます。

① 何もしなければ拒否される

リクエスト到着誰かが何かをしようとする
例外はただ1つ
暗黙のDenyimplicit deny
「明示的な許可がない限り拒否」がデフォルト
rootユーザーフルアクセス
唯一の例外
他の全主体許可を勝ち取る必要がある
  • 公式の言い回しは "By default, all requests are implicitly denied with the exception of the AWS account root user, which has full access."
  • 許可されるには "Requests must be explicitly allowed by a policy or set of policies" が必要。
  • Organizationsのメンバーアカウントでは、SCP/RCPはrootユーザーにも適用される(例外は管理アカウントのプリンシパルとservice-linked role)。「rootは無敵」なのは単一アカウントの話である。

IAMは「許可リストに載っていなければ通さない」門番であり、初期値は常に拒否。これはOSのファイルパーミッションやACLが採るデフォルト拒否(fail-safe defaults)という設計原則そのもので、「うっかり許可される」事故を構造的に防ぐ。

② 認証→コンテキスト→評価

[1] 認証「誰か」を確定する
S3の匿名アクセス等、一部サービスでは不要
材料が揃ったら
[2] コンテキスト処理効くポリシーを集める
プリンシパル/アクション/リソース/条件 = PARCモデルに整形
[3] 判定コード評価全ポリシーを突き合わせAllow/Denyを出す
  • 3ステップは公式の "Authentication" → "Processing the request context" → "How AWS enforcement code logic evaluates requests" に対応。
  • リクエストコンテキストの中身は公式ではプリンシパル・アクション・リソース・リソースデータ・環境データ(IPアドレスや時刻等)で、これをPrincipal / Action / Resource / Condition(PARC)モデルとして整理する。
  • 認証は「誰か(principal)」の確定であって、「何をしてよいか(認可)」はステップ3で初めて決まる。

「認証(誰か)」と「認可(何をしてよいか)」は別の関門である。IAMの主戦場はステップ3で、ここに入る前にリクエストは「プリンシパル・アクション・リソース・条件」というコンテキストへ整形されている。API Gateway編でリクエストがTLS終端やマッピングの関門を順に通ったのと同じく、認可も一段ずつ通していく構図になる。

③ 先に「Denyがないか」を探す

全ポリシー走査SCP / RCP / リソースベース / アイデンティティベース / boundary / セッション
はい / いいえ で分岐
Deny文はあるか?当てはまる明示的Denyを1つでも探す
即 最終Deny他の全Allowを打ち消す
はい: 1つでもあれば確定
Allow関門へ第2段に進む
いいえ: まだ許可ではない
  • "the enforcement code looks for a Deny statement that applies to the request ... If the enforcement code finds even one explicit deny that applies, the enforcement code returns a final decision of Deny."
  • "An explicit deny overrides an explicit allow."

第1段は「拒否の一票探し」。ポリシーの種類を問わず、当てはまる明示的Denyが1つでもあれば即拒否で、どれだけAllowが積まれていても覆せない。ブール論理で言えば、Denyは全体に対する強制的なゲート(AND側の否定条件)として働く。

④ 「Allowがあるか」の関門を順に通す

RCP組織のリソース制御ポリシー
Allow無ければ→Deny
通過
SCP組織のサービス制御ポリシー
Allow無ければ→Deny
無ければ次へ(Denyにはならない)
リソースベースバケット/キュー等に付与
唯一のショートカット: プリンシパルに直接Allowがあれば最終Allowになり得る
通過
アイデンティティユーザ/ロール/グループ
Allow無ければ→Deny
通過
boundary上限を定める枠
Allow無ければ→Deny
通過
セッション一時認証時に渡す絞り込み
Allow無ければ→Deny
最終決定=Allow
  • Denyが1つも無かったリクエストだけがこの第2段へ進む。
  • リソースベース以外の関門の共通形は「該当するAllow文が無ければ implicitly denied → final decision of Deny、あれば評価続行」。
  • RCPには`RCPFullAWSAccess`がRCP有効化時に自動作成・全エンティティにアタッチされ(デタッチ不可)、常にAllow文が存在する。
  • SCP・boundary・セッションポリシーは「無ければ素通り、あれば必ずAllowを含む必要がある関門」。
  • リソースベースポリシーだけは形が違い、Allowが無くてもDenyにならず次へ進む一方、リクエスト中のプリンシパル(IAMユーザ・ロールセッション等)に直接Allowしていれば、以降のアイデンティティベース・boundary・セッションポリシーの暗黙Denyを飛び越えて最終Allowになり得る(詳細条件はプリンシパル種別ごとに異なるため本レッスンでは深追いしない)。

第2段は関門の直列で、効いている必須関門(RCP・SCP・アイデンティティベース・boundary・セッションポリシー)のすべてでAllowを見つけて初めてAllow。ブール論理では必須関門の連なりはAND。リソースベースポリシーだけは「落とす関門」ではなく「早く通すショートカット」として振る舞う。DynamoDB編でリクエストがパーティションキー→物理ノードと一段ずつ絞られたのと同じく、認可も「効くポリシー種別」を上から順に絞り込んでいく。

⑤ 関門の中は論理OR

ポリシーAStmt1: Deny / Stmt2: 無関係
明示Denyは第1段(③)で全体Deny済み。ここへは到達しない
ポリシーBStmt3: Allow
グループCStmt4: 無関係
あり / なし で分岐
Allowは1つある?例: アイデンティティベースという1つの関門の内部
関門を通過1つでもAllowすれば開く(OR)
暗黙Denyで停止この関門で終わり
  • "If any statement in any applicable identity-based policies allows the requested action, the code evaluation continues."
  • 同一アカウント内では、アイデンティティベースとリソースベースの許可は和集合(union)を取る: "If an action is allowed by an identity-based policy, a resource-based policy, or both, then AWS allows the action."

関門「内」は緩く、複数ステートメント・複数ポリシーは論理ORでまとまり、1つでもAllowすればその関門は開く。関門「間」は厳しくAND。この「内はOR・間はAND」という二層のブール構造こそが、IAM評価の骨格である。

⑥ なぜ「Deny優先」が安全側なのか

Allowの票何票あっても「開けてよい」候補にすぎない
Denyの票1票で全部を却下できる
拒否権 / veto
一列に並べると
判定ロジック明示Denyが1つでも? → Deny / 全関門でAllow? → Allow / 否 → Deny
明示的Deny最優先
明示的Allow次点
暗黙のDenyデフォルト
  • 決定順は "An explicit deny overrides an explicit allow" と "By default, all requests are implicitly denied"。
  • 優先順位を一列に並べると 明示的Deny > 明示的Allow > 暗黙のDeny。
  • SCP/RCP/boundaryは公式で "maximum available permissions"(利用可能な権限の上限)と説明される。

権限設計では「許可の付け忘れ」より「拒否の付け忘れ」の方が危険なので、拒否に絶対の優先権を与える。だからガードレール(SCP/boundary/セッションポリシー)は、末端の管理者がどれだけAllowを足しても越えられない上限として機能する。これはメッセージング編の「配信保証は緩い方向(重複)には倒せても厳しい方向は守る」発想と同じく、安全側に倒す(fail-safe)という一貫した原理の現れである。

公式ドキュメントで詳しく ↗