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

41. 認可の多層評価 — リソースポリシーとオーソライザーの合成

API Gatewayの入口判断は一つの門番ではなく、リソースポリシーとLambdaオーソライザーという独立した部品の出力を規則で合成して決まります。その評価の順序と合成表を図で追いましょう。

① 判定材料は二つ — 一枚岩の門番はいない

APIリクエスト「誰がこのAPIを呼べるか?」
二つの独立した材料
リソースポリシー送信元IP・VPCエンドポイントなど入口条件でAllow/Deny(IAM風)
Lambdaオーソライザーの返すポリシーprincipalId + execute-api:Invoke に Allow/Deny
合成
デフォルト拒否・明示Deny優先既習のアクセス制御モデルと同じ規則
最終判定: 許可 / 拒否

REST APIでLambdaオーソライザーとリソースポリシーを併用すると、二つの独立した部品の出力を「デフォルト拒否・明示Deny優先」の規則で合成した結果が最終判定になります。

② リソースポリシーは二段階で評価される

呼び出し到着
第1段階
リソースポリシーの明示Denyだけを先行評価
明示Denyに該当その場で拒否。オーソライザーは呼ばれない
通過通過した呼び出しだけが次へ進む
第2段階(通過分のみ)
Lambdaオーソライザーを呼び出し
返ってきたポリシーをリソースポリシーと突き合わせて最終判定
  • 公式ドキュメントに先行評価の目的(課金対象のLambda呼び出し削減など)は記載されていない
  • 押さえるのは順序の事実:「明示Denyだけが先に評価され、通過したものだけがオーソライザーに進む」

オーソライザーを呼ぶ前に、リソースポリシーの明示Denyだけが先行評価されます。ここで弾かれた呼び出しはオーソライザーに到達しません。

③ Table A — Lambdaオーソライザーの合成表(同一アカウント)

Table Aオーソライザーの返すポリシー × リソースポリシー(同一アカウント)
どちらかがAllow・どちらもDenyなし一方Allow+他方沈黙(neither Allow nor Deny)でも通る
Allow
片方でも明示Deny
Explicit Deny
両方とも沈黙
Implicit Deny(デフォルト拒否)
  • 読み方は既習の論理式の評価にそのまま対応する

公式のLambdaオーソライザーの節は「結果はTable Aに基づく」とだけ規定。ひとことで言えば「どちらかがAllow、かつDenyが無ければ通る」です。

④ Table B — IAM/Cognitoのクロスアカウント。Lambdaオーソライザーには適用されない

Table BIAM認証 / Cognitoオーソライザー × リソースポリシー(クロスアカウント)
リソースポリシー: 明示Allow
IAM / Cognito側: 明示Allow
両方が明示Allowのときだけ
許可
片方でも沈黙(neither Allow nor Deny)
クロスアカウントアクセスは拒否
  • Table BをLambdaオーソライザーの合成に結び付けるのは誤り(Lambdaオーソライザーの節が参照するのはTable Aだけ)
  • クロスアカウントで双方の明示的許可を要求するのはAWSの一貫した方針
  • 覚え分け: 同一アカウント=「どちらかAllowで通る」/ IAM・Cognitoクロスアカウント=「両方明示Allowでないと通らない」

Table Bの表題は「IAM policy(またはCognitoユーザープールオーソライザー)」のクロスアカウント用。双方の明示Allowが揃わないと通りません。

⑤ 結果はTTL付きでキャッシュ — 「何を鍵にするか」が使い回しの粒度を決める

リクエスト
キャッシュ確認(TTL: 既定300秒・最大3600秒)
キャッシュヒットLambdaを再呼び出しせず、キャッシュ済みポリシードキュメントをそのまま合成に使う
ミスオーソライザーを呼び出し、結果をキャッシュ
キャッシュキーの作り方
TOKENタイプトークンソースに指定したヘッダの値がキー
REQUESTタイプ複数のidentity source(ヘッダ・クエリ文字列・ステージ変数・コンテキスト変数)を順序を保って連結
  • キャッシュ有効なREQUESTオーソライザーで、identity sourceのいずれかが欠落・null・空 → Lambdaを呼ばずに401
  • キャッシュキーの構成要素を変えて再デプロイ → キャッシュ済みポリシーは破棄され新しく生成
  • 「何を鍵にするか」の設計が、そのまま「どの粒度で認可結果が使い回されるか」を決める

オーソライザーの結果はTTL付き(既定300秒・最大3600秒)でキャッシュされ、有効な間は関数を再呼び出しせずキャッシュ済みポリシーで合成します。

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