IAM Policy Simulator をざっくり理解する

はじめに

この度、特定のIAMロールが特定のS3バケットに対して、想定したアクションを実施できるか、事前検証することになりました。
例:IAMロール「TestRole」がバケット「TestBacket」のオブジェクトを削除可能だが、バケットポリシーの変更は不可・・・など

そこで、表題のIAM Policy Simulatorという機能を初めて使ってみました。
本ブログにて、本機能について紹介していきます。

IAM Policy Simulator とは

IAM ポリシーを 実際のリクエストを送らずに 評価し、「このユーザがこの操作をしたら許可されるか、拒否されるか」を返してくれる機能です。
特徴は以下です。

  • 実 API は呼ばれないので、本番リソースに対して試しても何も起きない
  • アクションごとに allowed / explicitDeny / implicitDeny の 3 値で返る
  • allow または explicitDeny のときは、どのポリシーのどの Statement が効いたかも教えてくれる

評価に含められるポリシーは次の 4 種類です。

種類
アイデンティティベースポリシー ユーザ・ロールに付いている IAM ポリシー
アクセス許可の境界 Permissions boundary
SCP Organizations のサービスコントロールポリシー
リソースベースポリシー S3 バケットポリシー、SQS キューポリシーなど

公式: IAM policy testing with the IAM policy simulator

今回はS3のバケットポリシーとIAMユーザーの評価に使いました。

評価バケットポリシー

バケットポリシーの要件は以下です。

  1. 特定のIAMロールのみ、オブジェクトの追加や削除が可能
  2. バケットの管理ユーザーのみ、バケットポリシーの編集が可能

そのため以下のような Deny のみで構成したバケットポリシーを作成しました。

  • オブジェクトの書き込み・削除は user/backup-writer 以外を拒否
  • バケットの管理操作(削除・ポリシー変更など)は管理者ロール 2 つ(BackupAdmin/InfraOps)と root 以外を拒否
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyObjectWriteExceptBackupWriter",
      "Effect": "Deny",
      "Principal": "*",
      "Action": ["s3:PutObject", "s3:DeleteObject"],
      "Resource": "arn:aws:s3:::example-backup-bucket/*",
      "Condition": {
        "ArnNotEquals": {
          "aws:PrincipalArn": "arn:aws:iam::123456789012:user/backup-writer"
        }
      }
    },
    {
      "Sid": "DenyBucketManagementExceptAdmins",
      "Effect": "Deny",
      "Principal": "*",
      "Action": ["s3:DeleteBucket", "s3:PutBucketPolicy", "s3:DeleteBucketPolicy"],
      "Resource": "arn:aws:s3:::example-backup-bucket",
      "Condition": {
        "ArnNotEquals": {
          "aws:PrincipalArn": [
            "arn:aws:iam::123456789012:role/BackupAdmin",
            "arn:aws:iam::123456789012:role/InfraOps",
            "arn:aws:iam::123456789012:root"
          ]
        }
      }
    }
  ]
}

では以下の二点について、IAM Policy Simulatorを使用して検証していきます。

  1. backup-writer の DeleteObject が allowed になること
  2. backup-writer の DeleteBucket が explicitDeny になること

CLIでの実行例

以下コマンドにてbackup-writer の DeleteObject が allowed になることを確認します。

aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789012:user/backup-writer \
  --action-names s3:DeleteObject \
  --resource-arns arn:aws:s3:::example-backup-bucket/test/x \
  --resource-policy file://bucketpolicy.json \
  --context-entries "ContextKeyName=aws:PrincipalArn,ContextKeyValues=arn:aws:iam::123456789012:user/backup-writer,ContextKeyType=string" \
  --query 'EvaluationResults[].[EvalActionName,EvalDecision]'

各オプションの意味は次のとおりです。

オプション 意味
--policy-source-arn 誰の権限で試すか
--action-names 試す操作。複数指定可
--resource-arns 対象バケット
--resource-policy 渡すバケットポリシー
--context-entries 条件キーの値
--query 出力を「操作名と判定」だけに絞る

出力:

 ["s3:DeleteObject", "allowed"]

公式: simulate-principal-policy (AWS CLI reference)

注意点: --context-entries を付けないと全部拒否になる

上のコマンドから --context-entries を外して実行すると、以下のような結果になりバケットポリシーでDenyしていないアクションまでDenyされています。

[["s3:PutObject", "explicitDeny"], ["s3:DeleteObject", "explicitDeny"], ["s3:GetObject", "allowed"]]

原因

理由は 2 つの仕様の組み合わせです。

(1) Simulator には –policy-source-arnで渡すarnと条件キーで使うaws:PrincipalArnは別物

Simulator実行時、以下のように複数の情報をくっつけたものが、実行するようなイメージです。

情報 名前 CLI での渡し方
誰が Principal(プリンシパル) backup-writer --policy-source-arn
何を Action(アクション) s3:PutObject --action-names
どこに Resource(リソース) example-backup-bucket/test/x --resource-arns
どこから aws:SourceIp(グローバル条件キー) 203.0.113.5 --context-entries、型 ip
いつ aws:CurrentTime(グローバル条件キー) 2026-09-05T01:00:00Z --context-entries、型 date
ARN は aws:PrincipalArn(グローバル条件キー) arn:aws:iam::123456789012:user/backup-writer --context-entries、型 string

しかし、aws:PrincipalArn については自動で渡されず、明示的に情報を付与してあげる必要があります。
※上記のIPや時間も、aws:PrincipalArnと同様に明示的に付与する必要がある

(2)バケットポリシーでaws:PrincipalArnを指定している

以下でaws:PrincipalArnを指定しています。--context-entries で明示的にarnを指定しないと、バケットポリシーは問答無用で拒否します。
backup-writer で試しているのに aws:PrincipalArn が空 → 「backup-writer ではない」と判定 → Deny

      "Condition": {
        "ArnNotEquals": {
          "aws:PrincipalArn": "arn:aws:iam::123456789012:user/backup-writer"
        }

まとめ

IAM Policy Simulatorについて深掘りしてみました。
--context-entriesでarnの指定が必要だった件は、「それくらい融通利かせてくれ」と思いましたが、
あくまで実際にAPIをたたかないという仕組み上、仕方ないことなのかもしれません。

今回はS3のバケットポリシーが主な検証対象でしたが、MFAや送信元制限の検証など、色々と便利そうなので、今後機会があれば試してみたいと思います。

Last modified: 2026-09-05

Author