IAM ポリシーの評価ロジック完全解説 - 暗黙の Deny が明示的な Allow に勝つ仕組み

IAM がリクエストを許可・拒否する際の評価フローを、暗黙の Deny、明示的な Allow、明示的な Deny の優先順位、SCP・パーミッションバウンダリー・セッションポリシーの交差判定まで段階的に解説します。

IAM の評価結果は 3 種類しかない

IAM のポリシー評価は複雑に見えますが、最終的な結果は「明示的な Deny」「明示的な Allow」「暗黙の Deny」の 3 種類しかありません。そして、優先順位は常に「明示的な Deny > 明示的な Allow > 暗黙の Deny」です。暗黙の Deny とは、どのポリシーにも Allow が記述されていない状態です。IAM はデフォルトですべてのアクションを拒否するため、明示的に Allow されていないアクションは自動的に拒否されます。これが「最小権限の原則」の技術的な基盤です。明示的な Allow は、ポリシーの Effect が Allow で、リクエストの条件がポリシーの条件に一致した場合です。明示的な Deny は、ポリシーの Effect が Deny で条件が一致した場合で、他のどのポリシーに Allow があっても、明示的な Deny が常に優先されます。この「Deny が常に勝つ」ルールが IAM のセキュリティモデルの根幹です。管理者が誤って広範な Allow を付与しても、Deny ポリシーで特定のアクションを確実にブロックできます。

同一アカウント内の評価フロー

同一アカウント内でのポリシー評価は、複数のポリシータイプを順番に評価する多段階プロセスです。まず、Organizations の SCP (Service Control Policy) が評価されます。SCP は組織のアカウントに対する「天井」として機能し、SCP で許可されていないアクションは、アカウント内のどのポリシーで Allow されていても拒否されます。次に、リソースベースポリシー (S3 バケットポリシー、Lambda のリソースポリシーなど) が評価されます。リソースベースポリシーで明示的に Allow されている場合、アイデンティティベースポリシーに Allow がなくてもアクセスが許可されます。これは同一アカウント内でのみ成立するルールで、クロスアカウントアクセスでは両方のポリシーで Allow が必要です。続いて、パーミッションバウンダリーが評価されます。パーミッションバウンダリーは IAM ユーザーやロールに設定する「上限」で、アイデンティティベースポリシーとパーミッションバウンダリーの交差部分 (両方で Allow されているアクション) のみが許可されます。最後に、アイデンティティベースポリシー (IAM ポリシー) が評価されます。

SCP とパーミッションバウンダリーの交差判定

SCP とパーミッションバウンダリーは、どちらも「許可の上限」を設定する仕組みですが、適用レベルが異なります。SCP は Organizations のアカウントレベル、パーミッションバウンダリーは IAM エンティティ (ユーザー・ロール) レベルです。両方が設定されている場合、最終的に許可されるアクションは「SCP で許可 AND パーミッションバウンダリーで許可 AND アイデンティティベースポリシーで許可」の交差部分です。具体例で説明します。SCP が s3:* と ec2:* を許可し、パーミッションバウンダリーが s3:* と lambda:* を許可し、アイデンティティベースポリシーが s3:GetObject と lambda:InvokeFunction を許可している場合、実際に許可されるのは s3:GetObject だけです。lambda:InvokeFunction は SCP で許可されていないため拒否されます。この交差判定は、セキュリティチームが SCP で組織全体のガードレールを設定し、開発チームのリーダーがパーミッションバウンダリーでチームメンバーの権限上限を設定し、個々の開発者がアイデンティティベースポリシーで必要な権限を付与する、という多層的な権限管理を可能にします。

条件キーの評価 - 見落としがちな落とし穴

IAM ポリシーの Condition ブロックは、リクエストの属性 (送信元 IP、リクエスト時刻、タグ値など) に基づいてアクセスを制御する強力な機能ですが、評価ロジックに落とし穴があります。最も多い誤解は、条件キーが存在しない場合の挙動です。たとえば、aws:SourceIp 条件でアクセスを制限するポリシーを設定した場合、AWS サービスからの内部呼び出し (Lambda が S3 にアクセスする場合など) では aws:SourceIp が存在しないことがあります。条件キーが存在しない場合、その条件は「一致しない」と評価されます。Allow ポリシーの条件が一致しなければ Allow が適用されず、暗黙の Deny になります。Deny ポリシーの条件が一致しなければ Deny が適用されず、他のポリシーの Allow が有効になります。この非対称性を理解していないと、「IP 制限を設定したら Lambda からのアクセスまでブロックされた」という問題が発生します。対策として、aws:ViaAWSService 条件キーを使用し、AWS サービス経由のリクエストを条件から除外する方法があります。また、StringEquals と StringLike の違い (ワイルドカードの扱い)、IpAddress と NotIpAddress の論理的な関係も、ポリシー設計時に正確に理解しておく必要があります。

クロスアカウントアクセスの評価ルール

クロスアカウントアクセスの評価ルールは、同一アカウント内とは異なります。アカウント A のプリンシパルがアカウント B のリソースにアクセスする場合、アカウント A 側のアイデンティティベースポリシーとアカウント B 側のリソースベースポリシーの両方で Allow が必要です。同一アカウント内では、リソースベースポリシーの Allow だけでアクセスが許可されますが、クロスアカウントではこの「片方だけで OK」ルールは適用されません。ただし、例外があります。IAM ロールの信頼ポリシー (AssumeRole) は、クロスアカウントでもリソースベースポリシーとして機能し、信頼ポリシーの Allow だけで AssumeRole が許可されます。AssumeRole 後のアクションは、ロールのアイデンティティベースポリシーに従います。S3 バケットポリシーでクロスアカウントアクセスを許可する場合、バケットポリシーに Principal としてアカウント A の ARN を指定し、かつアカウント A 側のアイデンティティベースポリシーでも s3:GetObject を許可する必要があります。この二重の許可要件は、一方のアカウントの管理者が意図しないアクセスを防ぐためのセキュリティメカニズムです。IAM の設計パターンを体系的に学ぶには、専門書籍 (Amazon)が参考になります。