IAM 権限のトラブルシューティング

IAM の Policy Troubleshooter を使用すると、ユーザーが特定のリソースにアクセスできる理由や、API を呼び出す権限がない理由を確認できます メールアドレス、リソース、権限を指定すると、Policy Troubleshooter がリソースに適用されているすべての許可ポリシーと拒否ポリシーを調査します。これらのポリシーを使用して、プリンシパルに権限があるかどうかを示します。また、ポリシーのロール バインディングと拒否ルールを一覧表示し、プリンシパルのアクセス権への影響を示します。

ポリシーに関するトラブルシューティングには、Google Cloud コンソール、Google Cloud CLI、または REST API を使用してアクセスできます。単純なクエリについては、通常は、Google Cloud コンソールを使用するのが最も迅速に処理できる方法です。より複雑なシナリオでは、gcloud CLI または REST API の使用を検討してください。

始める前に

  • Policy Troubleshooter API を有効にします。

    API を有効にする

必要な権限

プリンシパルのアクセス権を完全にトラブルシューティングするには、次の権限が必要です。

個別のプリンシパルのアクセス権に関するトラブルシューティングを行う権限

ポリシーのトラブルシューティングでは、許可権限を持つポリシー、拒否ポリシー、ロールに基づいて、リソースに対するプリンシパルのアクセス権を分析します。リソースに適用されるポリシーに対する閲覧権限、カスタムロールに対する閲覧権限がない場合は、プリンシパルにアクセス権があるかどうかを判断できないことがあります。

プリンシパルのアクセス権のトラブルシューティングに必要な権限を取得するには、組織に対して次の IAM ロールを付与するよう管理者に依頼してください。

ロールの付与の詳細については、アクセスの管理をご覧ください。

必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

グループ メンバーのアクセス権に関するトラブルシューティングを行う権限

許可ポリシーと拒否ポリシーにグループが含まれている場合、個別のグループ メンバーに対するアクセス権のトラブルシューティングを行うには、Google Workspace Admin API の権限 groups.read が必要です。特権管理者とグループ管理者にはこの権限が自動的に付与されます。特権管理者またはグループ管理者ではないユーザーにこの権限を付与するには、groups.read 特権(Admin API 特権にあります)を含むカスタムの Google Workspace 管理者ロールを作成し、ユーザーに付与します。

これらの権限を付与されていない場合、グループまたはドメインを含むロール バインディングまたは拒否ルールの結果は、不明になります。ただし、ロール バインディングまたは拒否ルールにプリンシパルが明示的に含まれている場合を除きます。

ドメイン メンバーのアクセス権に関するトラブルシューティングを行う権限

許可ポリシーと拒否ポリシーに Google Workspace アカウントまたは Cloud Identity ドメインが含まれている場合、個々のドメイン メンバーに対するアクセス権のトラブルシューティングを行うには、ドメイン管理者である必要があります。

これらの権限を付与されていない場合、グループまたはドメインを含むロール バインディングまたは拒否ルールの結果は、不明になります。ただし、ロール バインディングまたは拒否ルールにプリンシパルが明示的に含まれている場合を除きます。

アクセス権のトラブルシューティング

アクセス権のトラブルシューティングには、次の情報が必要です。

  • プリンシパル: 確認するメールアドレス。メールアドレスは、ユーザーまたはサービス アカウントを参照している必要があります。他の種類のプリンシパル(グループ、ドメイン、Workforce Identity、ワークロード ID など)はサポートされていません。
  • リソース: リソースの完全な名前。たとえば、プロジェクト my-project を確認するには、「//cloudresourcemanager.googleapis.com/projects/my-project」と入力します。他のリソースタイプについては、完全なリソース名の例をご覧ください。
  • 権限: 確認する権限。Google Cloud コンソールを使用している場合は、入力時に候補のリストが表示されます。権限の完全なリストについては、権限のリファレンスをご覧ください。

コンソール

アクセス権のトラブルシューティングを行うには、次のようにします。

  1. Google Cloud コンソールで、[ポリシーに関するトラブルシューティング] ページに移動します。

    [ポリシーに関するトラブルシューティング] に移動

  2. アクセス権を確認するプリンシパルのメールアドレスを入力します。

  3. 確認するリソースの完全なリソース名を入力します。

    完全なリソース名がわからない場合は、次のいずれかを行います。

    • プロジェクト、フォルダ、組織のアクセス権のトラブルシューティングを行う場合は、入力を開始するとオートコンプリート オプションが表示されます。
    • 別のリソースタイプへのアクセスのトラブルシューティングを行う場合は、[参照] をクリックしてリソース検索ダイアログを開き、リソースを検索します。

      1. [スコープを選択] ボックスで、検索するプロジェクト、フォルダ、または組織を選択します。
      2. [リソースタイプ] ボックスで、検索するリソースタイプを選択します。
      3. [リソースの検索] ボックスに、リソース名の一部を入力します。
      4. 結果セクションで、確認するリソースを選択します。
      5. [選択] をクリックしてリソースを選択し、ダイアログを閉じます。
  4. 確認する権限を入力します。

    完全な権限名がわからない場合は、入力を開始するとオートコンプリート オプションが表示されます。

  5. 省略可: 複数のリソースと権限を確認するには、[別のペアを追加] を選択して前の手順を繰り返します。

  6. [アクセスを確認] をクリックします。

gcloud

プリンシパルに IAM 権限が付与されている(または付与されていない)理由を確認するには、gcloud policy-troubleshoot iam コマンドを使用します。

後述のコマンドデータを使用する前に、次のように置き換えます。

  • EMAIL: 権限をトラブルシューティングする対象のプリンシパルのメールアドレス。
  • RESOURCE: 権限が付与されているリソース。
  • PERMISSION: トラブルシューティングする対象となる権限。

gcloud policy-troublewriting iam コマンドを実行します。

Linux、macOS、Cloud Shell

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL \
    --permission=PERMISSION

Windows(PowerShell)

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL `
    --permission=PERMISSION

Windows(cmd.exe)

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL ^
    --permission=PERMISSION

次のようなレスポンスが返されます。

{
  "accessTuple": {
    "conditionContext": {
      "destination": {},
      "effectiveTags": [
        {
          "tagValue": "tagValues/281481941428044",
          "namespacedTagValue": "803434038361/env/dev",
          "tagKey": "tagKeys/281475994198094",
          "namespacedTagKey": "803434038361/env",
          "tagKeyParentName": "organizations/803434038361"
        }
      ],
      "request": {},
      "resource": {}
    },
    "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
    "permission": "compute.instances.get",
    "permissionFqdn": "compute.googleapis.com/instances.get",
    "principal": "user1@example.com"
  },
  "allowPolicyExplanation": {
    "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
    "explainedPolicies": [
      {
        "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
        "bindingExplanations": [
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
            "combinedMembership": {
              "membership": "MEMBERSHIP_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_HIGH"
            },
            "memberships": {
              "user:user1@example.com": {
                "membership": "MEMBERSHIP_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_HIGH"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_HIGH",
            "role": "roles/compute.viewer",
            "rolePermission": "ROLE_PERMISSION_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH"
          },
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED",
            "combinedMembership": {
              "membership": "MEMBERSHIP_NOT_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_NORMAL"
            },
            "memberships": {
              "user:user2@example.com": {
                "membership": "MEMBERSHIP_NOT_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_NORMAL"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_NORMAL",
            "role": "roles/owner",
            "rolePermission": "ROLE_PERMISSION_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH"
          },
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED",
            "combinedMembership": {
              "membership": "MEMBERSHIP_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_NORMAL"
            },
            "memberships": {
              "user:user1@example.com": {
                "membership": "MEMBERSHIP_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_NORMAL"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_NORMAL",
            "role": "roles/resourcemanager.organizationAdmin",
            "rolePermission": "ROLE_PERMISSION_NOT_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_NORMAL"
          }
        ],
        "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
        "policy": {
          "bindings": [
            {
              "members": [
                "user:user1@example.com"
              ],
              "role": "roles/compute.viewer"
            },
            {
              "members": [
                "user:user2@example.com"
              ],
              "role": "roles/owner"
            },
            {
              "members": [
                "user:user1@example.com"
              ],
              "role": "roles/resourcemanager.organizationAdmin"
            },
          ],
          "etag": "BwX5/L9Vbg4=",
          "version": 3
        },
        "relevance": "HEURISTIC_RELEVANCE_HIGH"
      }
    ],
    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
  },
  "denyPolicyExplanation": {
    "denyAccessState": "DENY_ACCESS_STATE_DENIED",
    "explainedResources": [
      {
        "denyAccessState": "DENY_ACCESS_STATE_DENIED",
        "explainedPolicies": [
          {
            "denyAccessState": "DENY_ACCESS_STATE_DENIED",
            "policy": {
              "createTime": "2023-04-18T07:15:47.702191Z",
              "displayName": "Deny compute instance get",
              "etag": "MTc3MDA1ODIyNjExNTMzMDg2NzI=",
              "kind": "DenyPolicy",
              "name": "policies/cloudresourcemanager.googleapis.com%2Fprojects%2F123456789012/denypolicies/deny-compute-get",
              "rules": [
                {
                  "denyRule": {
                    "deniedPrincipals": [
                      "principal://iam.googleapis.com/projects/-/serviceAccounts/user1@example.com"
                    ],
                    "deniedPermissions": [
                      "compute.googleapis.com/instances.get"
                    ]
                  }
                }
              ],
              "uid": "77e93c80-b383-0027-268e-a52a608aa13d",
              "updateTime": "2023-04-18T07:15:47.702191Z",
            },
            "relevance": "HEURISTIC_RELEVANCE_HIGH",
            "ruleExplanations": [
              {
                "combinedDeniedPermission": {
                  "permissionMatchingState": "PERMISSION_PATTERN_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "combinedDeniedPrincipal": {
                  "membership": "MEMBERSHIP_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "combinedExceptionPermission": {
                  "permissionMatchingState": "PERMISSION_PATTERN_NOT_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "combinedExceptionPrincipal": {
                  "membership": "MEMBERSHIP_NOT_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "deniedPermissions": {
                  "compute.googleapis.com/instances.get": {
                    "permissionMatchingState": "PERMISSION_PATTERN_MATCHED",
                    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                  }
                },
                "deniedPrincipals": {
                  "principal://iam.googleapis.com/projects/-/serviceAccounts/user1@example.com": {
                    "membership": "MEMBERSHIP_MATCHED",
                    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                  }
                },
                "denyAccessState": "DENY_ACCESS_STATE_DENIED",
                "relevance": "HEURISTIC_RELEVANCE_HIGH"
              }
            ]
          }
        ],
        "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/123456789012",
        "relevance": "HEURISTIC_RELEVANCE_HIGH"
      }
    ],
    "permissionDeniable": true,
    "relevance": "HEURISTIC_RELEVANCE_HIGH"
  },
  "overallAccessState": "CANNOT_ACCESS"
}

REST

プリンシパルに IAM 権限が付与されている(または付与されていない)理由を確認するには、Policy Troubleshooter API の iam.troubleshoot メソッドを使用します。

リクエストのデータを使用する前に、次のように置き換えます。

  • EMAIL: 権限をトラブルシューティングする対象のプリンシパルのメールアドレス。
  • RESOURCE: 権限が付与されているリソース。
  • PERMISSION: トラブルシューティングする対象となる権限。
  • PROJECT_ID: リクエストを行うために使用するプロジェクトの ID。 プロジェクト ID は英数字からなる文字列です(例: my-project)。

HTTP メソッドと URL:

POST https://policytroubleshooter.googleapis.com/v3/iam:troubleshoot

JSON 本文のリクエスト:

{
  "accessTuple": {
    "principal": "EMAIL",
    "fullResourceName": "RESOURCE",
    "permission": "PERMISSION"
  }
}

リクエストを送信するには、次のいずれかのオプションを展開します。

次のような JSON レスポンスが返されます。

{
  "overallAccessState": "CANNOT_ACCESS",
  "accessTuple": {
    "principal": "user1@example.com",
    "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
    "permission": "compute.instances.get",
    "permissionFqdn": "compute.googleapis.com/instances.get",
    "conditionContext": {
      "effectiveTags": [
        {
          "tagValue": "tagValues/281481941428044",
          "namespacedTagValue": "803434038361/env/dev",
          "tagKey": "tagKeys/281475994198094",
          "namespacedTagKey": "803434038361/env",
          "tagKeyParentName": "organizations/803434038361"
        }
      ]
    }
  },
  "allowPolicyExplanation": {
    "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
    "explainedPolicies": [
      {
        "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
        "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
        "bindingExplanations": [
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
            "role": "roles/compute.viewer",
            "rolePermission": "ROLE_PERMISSION_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH",
            "combinedMembership": {
              "membership": "MEMBERSHIP_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_HIGH"
            },
            "memberships": {
              "user:user1@example.com": {
                "membership": "MEMBERSHIP_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_HIGH"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_HIGH"
          },
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED",
            "role": "roles/owner",
            "rolePermission": "ROLE_PERMISSION_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH",
            "combinedMembership": {
              "membership": "MEMBERSHIP_NOT_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_NORMAL"
            },
            "memberships": {
              "user:user2@example.com": {
                "membership": "MEMBERSHIP_NOT_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_NORMAL"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_NORMAL"
          },
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED",
            "role": "roles/resourcemanager.organizationAdmin",
            "rolePermission": "ROLE_PERMISSION_NOT_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_NORMAL",
            "combinedMembership": {
              "membership": "MEMBERSHIP_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_NORMAL"
            },
            "memberships": {
              "user:user1@example.com": {
                "membership": "MEMBERSHIP_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_NORMAL"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_NORMAL"
          }
        ],
        "relevance": "HEURISTIC_RELEVANCE_HIGH",
        "policy": {
          "version": 3,
          "etag": "BwX5/L9Vbg4=",
          "bindings": [
            {
              "role": "roles/compute.viewer",
              "members": [
                "user:user1@example.com"
              ]
            },
            {
              "role": "roles/owner",
              "members": [
                "user:user2@example.com"
              ]
            },
            {
              "role": "roles/resourcemanager.organizationAdmin",
              "members": [
                "user:user1@example.com"
              ]
            },
          ]
        }
      }
    ],
    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
  },
  "denyPolicyExplanation": {
    "denyAccessState": "DENY_ACCESS_STATE_DENIED",
    "explainedResources": [
      {
        "denyAccessState": "DENY_ACCESS_STATE_DENIED",
        "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/123456789012",
        "explainedPolicies": [
          {
            "denyAccessState": "DENY_ACCESS_STATE_DENIED",
            "policy": {
              "name": "policies/cloudresourcemanager.googleapis.com%2Fprojects%2F123456789012/denypolicies/deny-compute-get",
              "uid": "77e93c80-b383-0027-268e-a52a608aa13d",
              "kind": "DenyPolicy",
              "displayName": "Deny compute instance get",
              "etag": "MTc3MDA1ODIyNjExNTMzMDg2NzI=",
              "createTime": "2023-04-18T07:15:47.702191Z",
              "updateTime": "2023-04-18T07:15:47.702191Z",
              "rules": [
                {
                  "denyRule": {
                    "deniedPrincipals": [
                      "principal://iam.googleapis.com/projects/-/serviceAccounts/user1@example.com"
                    ],
                    "deniedPermissions": [
                      "compute.googleapis.com/instances.get"
                    ]
                  }
                }
              ]
            },
            "ruleExplanations": [
              {
                "denyAccessState": "DENY_ACCESS_STATE_DENIED",
                "combinedDeniedPermission": {
                  "permissionMatchingState": "PERMISSION_PATTERN_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "deniedPermissions": {
                  "compute.googleapis.com/instances.get": {
                    "permissionMatchingState": "PERMISSION_PATTERN_MATCHED",
                    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                  }
                },
                "combinedExceptionPermission": {
                  "permissionMatchingState": "PERMISSION_PATTERN_NOT_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "combinedDeniedPrincipal": {
                  "membership": "MEMBERSHIP_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "deniedPrincipals": {
                  "principal://iam.googleapis.com/projects/-/serviceAccounts/user1@example.com": {
                    "membership": "MEMBERSHIP_MATCHED",
                    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                  }
                },
                "combinedExceptionPrincipal": {
                  "membership": "MEMBERSHIP_NOT_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "relevance": "HEURISTIC_RELEVANCE_HIGH"
              }
            ],
            "relevance": "HEURISTIC_RELEVANCE_HIGH"
          }
        ],
        "relevance": "HEURISTIC_RELEVANCE_HIGH"
      }
    ],
    "relevance": "HEURISTIC_RELEVANCE_HIGH",
    "permissionDeniable": true
  }
}

トラブルシューティングの結果を把握する

コンソール

結果ページに含まれる情報は、次のとおりです。

評価の詳細

[評価の詳細] セクションには、トラブルシューティングしているアクセス権の概要(指定したプリンシパル、リソース、権限など)が含まれています。複数のリソース権限のペアのトラブルシューティングを行う場合は、[アクセス権の評価] リストを使用して対象のペアを切り替えることができます。

ポリシーの詳細

[ポリシーの詳細] セクションには、関連する許可ポリシーと拒否ポリシーがプリンシパルのアクセス権にどのように影響するかに関する詳細情報が表示されます。

関連する許可ポリシーと拒否ポリシーには次のものがあります。

  • リソースの許可ポリシー
  • リソースの拒否ポリシー(ある場合)
  • リソースの親プロジェクト、フォルダ、組織の許可ポリシー(ある場合)
  • リソースの親プロジェクト、フォルダ、組織の拒否ポリシー(ある場合)

ポリシー継承により、親プロジェクト、フォルダ、組織の許可ポリシーと拒否ポリシーが関連しています。 プロジェクト、フォルダ、組織に許可ポリシーまたは拒否ポリシーを適用すると、そのプロジェクト、フォルダ、組織内のすべてのリソースにポリシーが適用されます。

たとえば、組織の拒否ポリシーで、プリンシパルが特定の権限を使用できない場合、プリンシパルは組織内のどのリソースに対しても、その権限を使用できません。このルールは、その組織内のフォルダとプロジェクトのほうが制限の緩い拒否ポリシーを使用している場合や、プリンシパルに権限を付与する許可ポリシーを使用している場合でも適用されます。

同様に、プロジェクトの許可ポリシーでプリンシパルに特定の権限が付与されている場合、この権限が拒否されない限り、プリンシパルはプロジェクト内の任意のリソースに対する権限を持ちます。

[ポリシーの詳細] セクションには、次のセクションがあります。

アクセス状態

[アクセス状態] セクションには、関連する IAM の許可ポリシーと拒否ポリシーに基づくプリンシパルのアクセス権の概要が表示されます。この概要には、拒否ポリシーの影響、許可ポリシーの影響、関連する拒否ポリシーと許可ポリシーに基づく最終的なアクセス結果が含まれます。

拒否ポリシー

[拒否ポリシー] セクションでは、プリンシパルへのアクセスを拒否するすべての拒否ポリシーを表示し、プリンシパルへのアクセスを拒否する拒否ルールを特定できます。また、拒否ルールがプリンシプルの権限を拒否する、または拒否しない理由を理解できます。

[拒否ポリシーを含むリソース] ペインには、関連するすべての拒否ポリシーが、接続されているリソース別に整理されて一覧表示されます。各拒否ポリシーの横にはアクセス評価があります。この評価は、拒否ポリシーにのみ適用され、継承されたポリシーからのアクセスは反映されません。リソースの拒否ポリシーを表示する権限を付与されていない場合は、リソースリストにそのリソースまたは拒否ポリシーは含まれません。

これらの拒否ポリシーに関連する拒否ルールを表示するには、拒否ポリシーをクリックします。リソースの拒否ポリシー内のすべての拒否ルールを表示するには、リソースをクリックします。拒否ルールが [拒否ルール] ペインに表示されます。このペインには、選択したリソースまたは拒否ポリシーに対してクエリされたプリンシパルまたは権限が付与されているすべての拒否ルールのテーブルが表示されます。

[アクセス] 列は、拒否ルールによってプリンシパルが権限を拒否するかどうかを示します。拒否ルールの詳細を表示するには、ルールの行の [拒否ルールを表示] をクリックします。

許可ポリシー

[許可ポリシー] セクションで、関連するすべての許可ポリシーに移動し、プリンシパルへのアクセスを許可するロール バインディングを特定し、ロール バインディングが付与または付与されない理由を理解できますプリンシパルに権限を提供します。

[リソース] ペインには、指定したリソースとその祖先が表示されます。各リソースの横にはアクセス評価があります。この評価は、リソースの許可ポリシーにのみ適用され、継承されたポリシーからのアクセスは反映されません。リソースの許可ポリシーを表示する権限を付与されていない場合は、リソースリストにそのリソースが含まれていません。

リソースの許可ポリシー内の関連するロール バインディングを表示し、プリンシパルに権限が付与されているか付与されないかを確認するには、リソースをクリックします。許可ポリシーのバインディングが [ロール バインディング] ペインに表示されます。

[ロール バインディング] ペインには、選択したリソースの許可ポリシーのロール バインディングのテーブルが表示されます。デフォルトでは、指定した権限を持つロールを含むロール バインディングのみがテーブルに含まれます。プリンシパルがアクセス権を付与されていない場合は、編集可能なカスタムロールを付与されているロール バインディングも表に表示されます。すべてのロール バインディングを表示するには、[関連するバインディングのみを表示] チェックボックスをオフにします。

[アクセス] 列は、ロール バインディングがプリンシパルに権限を付与しているかどうかを示します。ロール バインディングの詳細を表示するには、バインディングの行の [バインディングの詳細を表示] をクリックします。

gcloud

レスポンスには、4 つのメイン セクション(リクエスト内のアクセスタプルの説明、許可ポリシーの評価結果、拒否ポリシーの評価結果、全体的なアクセス状態)が含まれます。

  • accessTuple: 指定したアクセス コンテキストを含む、リクエスト内のアクセスタプルの説明。このセクションには、リソースに適用されるタグの概要も含まれています。
  • allowPolicyExplanation: 関連する許可ポリシーによってプリンシパルに権限を付与できるかどうかの概要。その後に、許可ポリシーとそれらのロール バインディングのリストを表示します。

    レスポンスでは、許可ポリシーごとにポリシー内のすべてのロール バインディングが一覧表示され、次の基準に基づいて評価されます。

    • バインディングに権限が含まれているかどうか。
    • バインディングにプリンシパルが含まれているかどうか。
    • バインディングの条件が満たされているかどうか(存在する場合)。

    レスポンスでは、許可ポリシーの完全な JSON テキストが出力されます。

  • denyPolicyExplanation: 関連する拒否ポリシーでプリンシパルに権限を拒否するかどうかの概要と、拒否ポリシーを含むリソースのリストが表示されます。レスポンスでは、そのリソースに関連付けられたすべての拒否ポリシーがリソースごとに一覧表示されます。

    レスポンスでは、拒否ポリシーごとにポリシーのメタデータが出力され、ポリシー内の拒否ルールが一覧表示されて、次の基準でルールが評価されます。

    • 拒否ルールに権限が含まれているかどうか。
    • 拒否ルールで権限が例外として一覧表示されているかどうか。
    • 拒否ルールにプリンシパルが含まれているかどうか。
    • 拒否ルールでプリンシパルが例外としてリストされているかどうか。
    • 拒否ルールの条件が満たされているか。
  • overallAccessState: 関連する許可ポリシーと拒否ポリシーに基づいて、指定された権限にプリンシパルがアクセスできるかどうか。

    関連する許可ポリシーと拒否ポリシーには次のものがあります。

    • リソースの許可ポリシー
    • リソースの拒否ポリシー(ある場合)
    • リソースの親プロジェクト、フォルダ、組織の許可ポリシー(ある場合)
    • リソースの親プロジェクト、フォルダ、組織の拒否ポリシー(ある場合)

    ポリシー継承により、親プロジェクト、フォルダ、組織の許可ポリシーと拒否ポリシーが関連しています。 プロジェクト、フォルダ、組織に許可ポリシーまたは拒否ポリシーを適用すると、そのプロジェクト、フォルダ、組織内のすべてのリソースにポリシーが適用されます。

    たとえば、組織の拒否ポリシーで、プリンシパルが特定の権限を使用できない場合、プリンシパルは組織内のどのリソースに対しても、その権限を使用できません。このルールは、その組織内のフォルダとプロジェクトのほうが制限の緩い拒否ポリシーを使用している場合や、プリンシパルに権限を付与する許可ポリシーを使用している場合でも適用されます。

    同様に、プロジェクトの許可ポリシーでプリンシパルに特定の権限が付与されている場合、この権限が拒否されない限り、プリンシパルはプロジェクト内の任意のリソースに対する権限を持ちます。

  • レスポンス内の多くのオブジェクトにも relevance フィールドがあります。このフィールドの値は、そのオブジェクトがアクセス全体の状態にどの程度寄与しているかを示します。relevance フィールドには次の値を指定できます。

    • HEURISTIC_RELEVANCE_HIGH: オブジェクトが結果に強い影響を与えていることを示します。つまり、オブジェクトを削除すると、全体的なアクセス状態が変わる可能性があります。たとえば、指定した権限を付与するプリンシパルにバインディングを付与するロール バインディングは、この関連性の値になります。

    • HEURISTIC_RELEVANCE_NORMAL: オブジェクトによる結果への影響が限定的であることを示します。つまり、オブジェクトを削除しても、アクセス状態全体が変更されることはほとんどありません。たとえば、権限を含まない拒否ルールまたはプリンシパルには、この関連性値があります。

REST

レスポンスには、主要なアクセス状態、リクエスト内のアクセスタプルの説明、許可ポリシーの評価結果、拒否ポリシー評価の結果の 4 つのメイン セクションがあります。

  • overallAccessState: 関連する許可ポリシーと拒否ポリシーに基づいて、指定された権限にプリンシパルがアクセスできるかどうか。

    関連する許可ポリシーと拒否ポリシーには次のものがあります。

    • リソースの許可ポリシー
    • リソースの拒否ポリシー(ある場合)
    • リソースの親プロジェクト、フォルダ、組織の許可ポリシー(ある場合)
    • リソースの親プロジェクト、フォルダ、組織の拒否ポリシー(ある場合)

    ポリシー継承により、親プロジェクト、フォルダ、組織の許可ポリシーと拒否ポリシーが関連しています。 プロジェクト、フォルダ、組織に許可ポリシーまたは拒否ポリシーを適用すると、そのプロジェクト、フォルダ、組織内のすべてのリソースにポリシーが適用されます。

    たとえば、組織の拒否ポリシーで、プリンシパルが特定の権限を使用できない場合、プリンシパルは組織内のどのリソースに対しても、その権限を使用できません。このルールは、その組織内のフォルダとプロジェクトのほうが制限の緩い拒否ポリシーを使用している場合や、プリンシパルに権限を付与する許可ポリシーを使用している場合でも適用されます。

    同様に、プロジェクトの許可ポリシーでプリンシパルに特定の権限が付与されている場合、この権限が拒否されない限り、プリンシパルはプロジェクト内の任意のリソースに対する権限を持ちます。

  • accessTuple: 指定したアクセス コンテキストを含む、リクエスト内のアクセスタプルの説明。このセクションには、リソースに適用されるタグの概要も含まれています。
  • allowPolicyExplanation: 関連する許可ポリシーによってプリンシパルに権限を付与できるかどうかの概要。その後に、許可ポリシーとそれらのロール バインディングのリストを表示します。

    レスポンスでは、許可ポリシーごとにポリシー内のすべてのロール バインディングが一覧表示され、次の基準に基づいて評価されます。

    • バインディングに権限が含まれているかどうか。
    • バインディングにプリンシパルが含まれているかどうか。
    • バインディングの条件が満たされているかどうか(存在する場合)。

    レスポンスでは、許可ポリシーの完全な JSON テキストが出力されます。

  • denyPolicyExplanation: 関連する拒否ポリシーでプリンシパルに権限を拒否するかどうかの概要と、拒否ポリシーを含むリソースのリストが表示されます。レスポンスでは、そのリソースに関連付けられたすべての拒否ポリシーがリソースごとに一覧表示されます。

    レスポンスでは、拒否ポリシーごとにポリシーのメタデータが出力され、ポリシー内の拒否ルールが一覧表示されて、次の基準でルールが評価されます。

    • 拒否ルールに権限が含まれているかどうか。
    • 拒否ルールで権限が例外として一覧表示されているかどうか。
    • 拒否ルールにプリンシパルが含まれているかどうか。
    • 拒否ルールでプリンシパルが例外としてリストされているかどうか。
    • 拒否ルールの条件が満たされているか。
  • レスポンス内の多くのオブジェクトにも relevance フィールドがあります。このフィールドの値は、そのオブジェクトがアクセス全体の状態にどの程度寄与しているかを示します。relevance フィールドには次の値を指定できます。

    • HEURISTIC_RELEVANCE_HIGH: オブジェクトが結果に強い影響を与えていることを示します。つまり、オブジェクトを削除すると、全体的なアクセス状態が変わる可能性があります。たとえば、指定した権限を付与するプリンシパルにバインディングを付与するロール バインディングは、この関連性の値になります。

    • HEURISTIC_RELEVANCE_NORMAL: オブジェクトによる結果への影響が限定的であることを示します。つまり、オブジェクトを削除しても、アクセス状態全体が変更されることはほとんどありません。たとえば、権限を含まない拒否ルールまたはプリンシパルには、この関連性値があります。

条件付きロール バインディングのトラブルシューティング

ポリシーのトラブルシューティングでは、タグに基づいて、条件付きロール バインディングと拒否ルールが自動的にトラブルシューティングされます。ただし、他の種類の条件付きロール バインディングまたは条件付き拒否ルールのトラブルシューティングを行うには、ポリシーのトラブルシューティングでリクエストに関する追加のコンテキストが必要です。たとえば、日時属性に基づく条件をトラブルシューティングするには、ポリシーに関するトラブルシューティングにリクエストの時間が必要です。

gcloud CLI と REST API では、この追加のコンテキストを手動で指定します。

Google Cloud コンソールでは、管理アクティビティ監査ログまたはデータアクセス監査ログから直接トラブルシューティングすることで、この追加のコンテキストを提供できます。各監査ログエントリは、Google Cloud API に対する 1 つのリクエスト、または Google Cloud が自動的に行う 1 つのアクションに対応します。監査ログからトラブルシューティングすると、ポリシーに関するトラブルシューティングはリクエストの追加情報(日時など)を自動的に取得します。これにより、ポリシーに関するトラブルシューティングによる条件付きロール バインディングの分析およびルールの拒否が可能になります。

コンソール

条件付きロール バインディングと拒否ルールのトラブルシューティングを行うには、次の手順を行います。

  1. Google Cloud コンソールで、[ログ エクスプローラ] ページに移動します。

    ログ エクスプローラに移動

  2. ページタイトルが [以前のログビューア] の場合は、[アップグレード] のプルダウン リストをクリックし、[新しいログ エクスプローラにアップグレード] を選択します。

  3. 管理アクティビティ監査ログとデータアクセス監査ログのみを表示するには、クエリビルダーで次のクエリを入力して、[クエリを実行] をクリックします。

    logName=("RESOURCE_TYPE/RESOURCE_ID/logs/cloudaudit.googleapis.com%2Factivity" OR "RESOURCE_TYPE/RESOURCE_ID/logs/cloudaudit.googleapis.com%2Fdata_access")
    

    次の値を置き換えます。

    • RESOURCE_TYPE: 監査ログを一覧表示するリソースタイプ。projectsfolders または organizations を使用します。
    • RESOURCE_ID: リソースの ID。
  4. トラブルシューティングするリクエストに対応する監査ログエントリを探します。ログ エクスプローラを使用して特定のログエントリを検索する方法については、ログ エクスプローラの使用をご覧ください。

  5. ログエントリの [概要] 列で [IAM] をクリックしてから、[アクセスに関する問題のトラブルシューティング] をクリックします。

    ポリシーに関するトラブルシューティングは、ログエントリの情報を使用してアクセス権のトラブルシューティングを行い、その結果を表示します。追加のコンテキストは、[条件コンテキスト] の下の評価の詳細に表示されます。コンテキストの詳細を表示するには、[条件コンテキストを表示] をクリックします。ポリシーに関するトラブルシューティングの結果ページの詳細については、このページのアクセス権のトラブルシューティングをご覧ください。

  6. 省略可: 条件付きロール バインディングと拒否ルールを含む別のリクエストのトラブルシューティングを行う場合は、[ログ エクスプローラ] ページに戻って前の手順を繰り返します。

gcloud

条件付きロール バインディングと拒否ルールのトラブルシューティングを行うには、gcloud policy-troubleshoot iam コマンドを使用します。

後述のコマンドデータを使用する前に、次のように置き換えます。

  • EMAIL: 権限をトラブルシューティングする対象のプリンシパルのメールアドレス。
  • RESOURCE: 権限が付与されているリソース。
  • PERMISSION: トラブルシューティングする対象となる権限。
  • DESTINATION_IP: 省略可。条件付きロール バインディングを確認するときに使用するリクエストの宛先 IP アドレス。例: 198.1.1.1
  • DESTINATION_PORT: 省略可。条件付きロール バインディングを確認するときに使用するリクエストの宛先ポート。例えば、「8080」です。
  • REQUEST_TIME: 省略可。条件付きロール バインディングを確認するときに使用するリクエストのタイムスタンプ。RFC 3339 形式のタイムスタンプを使用します(例: 2099-02-01T00:00:00Z)。
  • RESOURCE_NAME: 省略可。条件付きロール バインディングを確認するときに使用するリソース名の値。承認されたリソース名の形式の一覧については、リソース名の形式をご覧ください。
  • RESOURCE_SERVICE: 省略可。条件付きロール バインディングを確認するときに使用するリソース サービスの値。使用可能なサービス名の一覧については、リソース サービスの値をご覧ください。
  • RESOURCE_TYPE: 省略可。使用可能なリソースタイプのリストについては、リソースタイプの値をご覧ください。

gcloud policy-troublewriting iam コマンドを実行します。

Linux、macOS、Cloud Shell

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL \
    --permission=PERMISSION --destination-ip=DESTINATION_IP \
    --destination-port=DESTINATION_PORT --request-time=REQUEST_TIME \
    --resource-name=RESOURCE_NAME --resource-service=RESOURCE_SERVICE \
    --resource-type=RESOURCE_TYPE

Windows(PowerShell)

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL `
    --permission=PERMISSION --destination-ip=DESTINATION_IP `
    --destination-port=DESTINATION_PORT --request-time=REQUEST_TIME `
    --resource-name=RESOURCE_NAME --resource-service=RESOURCE_SERVICE `
    --resource-type=RESOURCE_TYPE

Windows(cmd.exe)

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL ^
    --permission=PERMISSION --destination-ip=DESTINATION_IP ^
    --destination-port=DESTINATION_PORT --request-time=REQUEST_TIME ^
    --resource-name=RESOURCE_NAME --resource-service=RESOURCE_SERVICE ^
    --resource-type=RESOURCE_TYPE

レスポンスには、プリンシパルのアクセス権の説明が含まれます。条件付きロール バインディングと拒否ルールごとに、指定した条件コンテキストに基づいて条件が true または false と評価されるかどうかを示す conditionExplanation フィールドがレスポンスに含まれます。

たとえば、リソースタイプとリソース サービスを指定する条件を持つロール バインディングの評価は次のとおりです。

...
{
  "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
  "combinedMembership": {
    "membership": "MEMBERSHIP_MATCHED",
    "relevance": "HEURISTIC_RELEVANCE_HIGH"
  },
  "condition": {
    "expression": " resource.type \u003d\u003d \"compute.googleapis.com/Instance\" \u0026\u0026 resource.service \u003d\u003d \"compute.googleapis.com\"",
    "title": "Compute instances only",
    "description": "Condition that limits permissions to only Compute instances"
  },
  "conditionExplanation": {
    "evaluationStates": [{
      "end": 51,
      "start": 1,
      "value": true
    }, {
      "end": 99,
      "start": 55,
      "value": true
    }],
    "value": true,
  },
  "memberships": {
    "user:my-user@example.com": {
      "membership": "MEMBERSHIP_MATCHED",
      "relevance": "HEURISTIC_RELEVANCE_HIGH"
    }
  },
  "relevance": "HEURISTIC_RELEVANCE_HIGH",
  "role": "roles/compute.viewer",
  "rolePermission": "ROLE_PERMISSION_INCLUDED",
  "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH"
}
...

REST

条件付きロール バインディングと拒否ルールのトラブルシューティングを行うには、Policy Troubleshooter API の iam.troubleshoot メソッドを使用します。

リクエストのデータを使用する前に、次のように置き換えます。

  • EMAIL: 権限をトラブルシューティングする対象のプリンシパルのメールアドレス。
  • RESOURCE: 権限が付与されているリソース。
  • PERMISSION: トラブルシューティングする対象となる権限。
  • DESTINATION_IP: 省略可。条件付きロール バインディングを確認するときに使用するリクエストの宛先 IP アドレス。例: 198.1.1.1
  • DESTINATION_PORT: 省略可。条件付きロール バインディングを確認するときに使用するリクエストの宛先ポート。例えば、「8080」です。
  • REQUEST_TIME: 省略可。条件付きロール バインディングを確認するときに使用するリクエストのタイムスタンプ。RFC 3339 形式のタイムスタンプを使用します(例: 2099-02-01T00:00:00Z)。
  • RESOURCE_NAME: 省略可。条件付きロール バインディングを確認するときに使用するリソース名の値。承認されたリソース名の形式の一覧については、リソース名の形式をご覧ください。
  • RESOURCE_SERVICE: 省略可。条件付きロール バインディングを確認するときに使用するリソース サービスの値。使用可能なサービス名の一覧については、リソース サービスの値をご覧ください。
  • RESOURCE_TYPE: 省略可。使用可能なリソースタイプのリストについては、リソースタイプの値をご覧ください。

HTTP メソッドと URL:

POST https://policytroubleshooter.googleapis.com/v3/iam:troubleshoot

JSON 本文のリクエスト:

{
  "accessTuple": {
    "principal": "EMAIL",
    "fullResourceName": "RESOURCE",
    "permission": "PERMISSION",
    "conditionContext": {
      "destination": {
        "ip": DESTINATION_IP,
        "port": DESTINATION_PORT
      },
      "request": {
        "receiveTime": REQUEST_TIME
      },
      "resource": {
        "name": RESOURCE_NAME,
        "service": RESOURCE_SERVICE,
        "type": RESOURCE_TYPE
      }
    }
  }
}

リクエストを送信するには、次のいずれかのオプションを展開します。

レスポンスには、プリンシパルのアクセス権の説明が含まれます。条件付きロール バインディングと拒否ルールごとに、指定した条件コンテキストに基づいて条件が true または false と評価されるかどうかを示す conditionExplanation フィールドがレスポンスに含まれます。

たとえば、リソースタイプとリソース サービスを指定する条件を持つロール バインディングの評価は次のとおりです。

...
{
  "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
  "role": "roles/compute.viewer",
  "rolePermission": "ROLE_PERMISSION_INCLUDED",
  "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH",
  "combinedMembership": {
    "membership": "MEMBERSHIP_MATCHED",
    "relevance": "HEURISTIC_RELEVANCE_HIGH"
  },
  "memberships": {
    "user:my-user@example.com": {
      "membership": "MEMBERSHIP_MATCHED",
      "relevance": "HEURISTIC_RELEVANCE_HIGH"
    }
  },
  "relevance": "HEURISTIC_RELEVANCE_HIGH",
  "condition": {
    "expression": " resource.type \u003d\u003d \"compute.googleapis.com/Instance\" \u0026\u0026 resource.service \u003d\u003d \"compute.googleapis.com\"",
    "title": "Compute instances only",
    "description": "Condition that limits permissions to only Compute instances"
  },
  "conditionExplanation": {
    "value": true,
    "evaluationStates": [{
      "start": 1,
      "end": 51,
      "value": true
    }, {
      "start": 55,
      "end": 99,
      "value": true
    }]
  }
}
...

次のステップ