IAM Policy Simulatorの新機能「PolicyExclusionList」を試してみた
はじめに
2026年7月30日、IAM Policy Simulatorのアップデートと、コンソールへの統合がありました。
追加された機能のうち PolicyExclusionList は、評価対象から指定したポリシーを外してシミュレーションできるパラメータです。あるDenyポリシーを削除して問題ないか、削除しても別のブロッカーで止まるのか。従来は実際に削除するまで分かりませんでした。このパラメータを使えば、削除前にその影響を見積もれます。本記事では除外対象を段階的に増やし、評価結果の変化を追いました。
検証内容
検証環境の構成
検証用のIAMユーザーには、s3:GetObject に対する許可元1つとブロッカー2つを用意しました。
| 要素 | 内容 | s3:GetObject に対する役割 |
|---|---|---|
管理ポリシー ReadOnlyAccess(AWS管理) |
s3:GetObject を Allow |
許可元 |
インラインポリシー DenyS3GetObject |
s3:GetObject を明示的Deny |
ブロッカー1 |
Permissions Boundary cm-simulator-exclusion-boundary(カスタマー管理) |
s3:ListBucket / s3:ListAllMyBuckets のみ Allow |
ブロッカー2(s3:GetObject を許可しない=暗黙的Deny) |
シミュレーションの実行には iam:SimulatePrincipalPolicy 権限が必要です。
基本シミュレーション(除外なし)
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:user/cm-simulator-exclusion-test-user \
--action-names s3:GetObject \
--resource-arns "arn:aws:s3:::cm-simulator-test-bucket/*"
EvalDecision:explicitDenyMatchedStatements:user_cm-simulator-exclusion-test-user_DenyS3GetObjectPermissionsBoundaryDecisionDetail:{"AllowedByPermissionsBoundary": false}
EvalDecision が可否、MatchedStatements がその判定に影響したポリシーを示します。ここではインラインポリシーの明示的Denyがマッチしており、これがブロッカー1です。
なお --resource-arns に指定するバケットは、実際に作成していなくてもかまいません。
ブロッカーを1つずつ除外する
PolicyExclusionList の各要素はユニオン構造です(PolicyIdentifier)。PolicyType / PolicyArn / InlinePolicyIdentifier のいずれか1つを指定します。インラインポリシーを指定する InlinePolicyIdentifier は、PolicyName・AttachmentType・AttachmentName の3フィールドすべてが必須です。
インラインポリシー DenyS3GetObject だけを除外してみます。明示的Denyが消えれば ReadOnlyAccess の Allow が通りそうに見えますが、結果は違いました。
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:user/cm-simulator-exclusion-test-user \
--action-names s3:GetObject \
--resource-arns "arn:aws:s3:::cm-simulator-test-bucket/*" \
--policy-exclusion-list '[{"InlinePolicyIdentifier":{"PolicyName":"DenyS3GetObject","AttachmentType":"user","AttachmentName":"cm-simulator-exclusion-test-user"}}]'
EvalDecision:implicitDenyMatchedStatements: 空PermissionsBoundaryDecisionDetail:{"AllowedByPermissionsBoundary": false}
EvalDecision は explicitDeny から implicitDeny に変わり、明示的Denyの除外は効いています。ただしブロッカーが複数あるため、1つ除外しただけでは allowed になりません。このとき MatchedStatements は空で、除外していない ReadOnlyAccess も現れないため、原因をここから読み取れません。原因は PermissionsBoundaryDecisionDetail が false のままである点です。ブロッカー2のPermissions Boundaryが s3:GetObject を許可していません。
続いてPermissions Boundaryも除外します。
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:user/cm-simulator-exclusion-test-user \
--action-names s3:GetObject \
--resource-arns "arn:aws:s3:::cm-simulator-test-bucket/*" \
--policy-exclusion-list '[{"InlinePolicyIdentifier":{"PolicyName":"DenyS3GetObject","AttachmentType":"user","AttachmentName":"cm-simulator-exclusion-test-user"}},{"PolicyType":"permission-boundary"}]'
EvalDecision:allowedMatchedStatements:ReadOnlyAccess(IAM Policy)
PolicyType に permission-boundary を指定すると、アタッチされているPermissions Boundary全体が除外されます。これでブロッカーが2つとも外れ、allowed になりました。
リソースベースポリシーが絡む場合
リソースベースポリシーを含むシミュレーションがサポートされるのはIAMユーザーのみです(SimulatePrincipalPolicy)。
アイデンティティ側の3つ(ReadOnlyAccess・DenyS3GetObject・Permissions Boundary)をすべて除外します。代わりに --resource-policy でリソースベースポリシー(バケットポリシー)の許可を与えます。
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:user/cm-simulator-exclusion-test-user \
--action-names s3:GetObject \
--resource-arns "arn:aws:s3:::cm-simulator-test-bucket/*" \
--policy-exclusion-list '[{"InlinePolicyIdentifier":{"PolicyName":"DenyS3GetObject","AttachmentType":"user","AttachmentName":"cm-simulator-exclusion-test-user"}},{"PolicyType":"permission-boundary"},{"PolicyArn":"arn:aws:iam::aws:policy/ReadOnlyAccess"}]' \
--resource-policy '{"Version":"2012-10-17","Statement":[{"Sid":"AllowUserGetObject","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:user/cm-simulator-exclusion-test-user"},"Action":"s3:GetObject","Resource":"arn:aws:s3:::cm-simulator-test-bucket/*"}]}'
EvalDecision:allowedMatchedStatements:ResourcePolicy(SourcePolicyType: Resource Policy)
この allowed はリソースベースポリシーのAllowのみによるものです。除外指定はそのままに --resource-policy だけを外すと implicitDeny となり、MatchedStatements も空になりました。アイデンティティ側の許可は残っていないため、通った理由はリソースベースポリシー以外にありません。
まとめ
PolicyExclusionList で除外できるポリシーは、インラインポリシー・AWS管理ポリシー・カスタマー管理ポリシー・Permissions Boundary・SCPの5種類です。今回試したのはインラインポリシー、AWS管理ポリシー、Permissions Boundaryの除外と、--resource-policy で与えたリソースベースポリシーの評価です。SCPを含む構成は試していません。
ブロッカーが複数ある構成では、明示的Denyを1つ除外しただけでは implicitDeny にとどまり、Permissions Boundaryまで外して初めて allowed になりました。PolicyExclusionList を使えば、この「どこまで消すと通るのか」をポリシーに手を加える前に段階的に切り分けられます。








