Troubleshoot IAM permissions

Policy Troubleshooter for IAM helps you understand why a user has access to a resource or doesn't have permission to call an API. Given an email address, resource, and permission, Policy Troubleshooter examines all allow and deny policies that apply to the resource. Then, it uses those policies to tell you whether the principal has the permission. It also lists the role bindings and deny rules in the policies and explains how they affect the principal's access.

You can access Policy Troubleshooter using the Google Cloud console, the Google Cloud CLI, or the REST API. For simple queries, using the Google Cloud console is typically fastest. For more complex scenarios, consider the gcloud CLI or the REST API.

Before you begin

  • Enable the Policy Troubleshooter API.

    Enable the API

Required permissions

To fully troubleshoot your principals' access, you need the following permissions.

Permissions to troubleshoot access for individual principals

Policy Troubleshooter analyzes a principal's access to a resource based on the allow policies, deny policies, and roles that you have permission to view. If you don't have permission to view a policy that applies to a resource, or if you don't have permission to view a custom role, then you might not be able to tell whether a principal has access.

To get the permissions that you need to troubleshoot a principal's access, ask your administrator to grant you the following IAM roles on the organization:

For more information about granting roles, see Manage access.

You might also be able to get the required permissions through custom roles or other predefined roles.

Permissions to troubleshoot access for group members

If your allow and deny policies include groups, you need the Google Workspace Admin API permission groups.read to troubleshoot access for individual group members. Super Admins and Group Admins automatically have this permission. To give a user who is not a Super or Group admin this permission, create a custom Google Workspace administrator role that contains the groups.read privilege (located under Admin API Privileges) and grant it to the user.

If you don't have these permissions, role bindings and deny rules that contain groups or domains have an access result of Unknown, unless the role binding or deny rule also explicitly includes the principal.

Permissions to troubleshoot access for domain members

If your allow and deny policies includes a Google Workspace account or Cloud Identity domain, you must be a domain administrator to troubleshoot access for individual domain members.

If you don't have these permissions, role bindings and deny rules that contain groups or domains have an access result of Unknown, unless the role binding or deny rule also explicitly includes the principal.

Troubleshoot access

To troubleshoot access, you need the following information:

  • Principal: The email address to check. The email address must refer to a user or service account. Other types of principals, including groups, domains, workforce identities, and workload identities, are not supported.
  • Resource: The full name of the resource. For example, to check the project my-project, enter //cloudresourcemanager.googleapis.com/projects/my-project. For other types of resources, see the examples of full resource names.
  • Permission: The permission to check. If you use the Google Cloud console, it presents a list of suggestions as you type. For a complete list of permissions, see the permissions reference.

Console

To troubleshoot access, do the following:

  1. In the Google Cloud console, go to the Policy Troubleshooter page.

    Go to Policy Troubleshooter

  2. Enter the email of the principal whose access you want to check.

  3. Enter the full resource name of the resource to check.

    If you don't know the full resource name, do one of the following:

    • If you're troubleshooting access for a project, folder, or organization, start typing to see autocomplete options.
    • If you're troubleshooting access for another resource type, click Browse to open the resource search dialog, then search for the resource:

      1. In the Select scope box, select a project, folder, or organization to search within.
      2. In the Resource type box, select the resource types you want to search for.
      3. In the Search for resources box, enter a portion of the resource name.
      4. In the results section, select the resource you want to check.
      5. Click Select to choose the resource and close the dialog.
  4. Enter the permission to check.

    If you don't know the full permission name, start typing to see autocomplete options.

  5. Optional: To check multiple resources and permissions, select Add Another Pair and repeat the previous step.

  6. Click Check access.

gcloud

To find out why a principal has, or doesn't have, an IAM permission, use the gcloud policy-troubleshoot iam command.

Before using any of the command data below, make the following replacements:

  • EMAIL: The email address of the principal whose permissions you want to troubleshoot.
  • RESOURCE: The resource on which the permission is granted.
  • PERMISSION: The permission that you want to troubleshoot.

Execute the gcloud policy-troubleshoot iam command:

Linux, macOS, or 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

You should receive a response similar to the following:

{
  "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

To find out why a principal has, or doesn't have, an IAM permission, use the Policy Troubleshooter API's iam.troubleshoot method.

Before using any of the request data, make the following replacements:

  • EMAIL: The email address of the principal whose permissions you want to troubleshoot.
  • RESOURCE: The resource on which the permission is granted.
  • PERMISSION: The permission that you want to troubleshoot.
  • PROJECT_ID: The ID of the project that you want to use to make the request. Project IDs are alphanumeric strings, like my-project.

HTTP method and URL:

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

Request JSON body:

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

To send your request, expand one of these options:

You should receive a JSON response similar to the following:

{
  "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
  }
}

Understand Troubleshooter results

Console

The results page contains the following information:

Evaluation details

The Evaluation details section contains a summary of the access you're troubleshooting, including the specified principal, resource, and permission. If you're troubleshooting multiple resource permission pairs, you can use the Access Evaluation list to switch between them.

Policy details

The Policy details section contains details about how the relevant allow and deny policies affect the principal's access.

Relevant allow and deny policies include the following:

  • The resource's allow policy
  • The resource's deny policies, if any
  • The allow policies of the resource's parent project, folder, and organization, if any
  • The deny policies of the resource's parent project, folder, and organization, if any

The allow and deny policies of parent projects, folders, and organizations are relevant because of policy inheritance. When you attach an allow or deny policy to a project, folder, or organization, that policy also applies for all resources inside that project, folder, or organization.

For example, if a deny policy for an organization says that a principal can't use a specific permission, then the principal can't use that permission for any resource within the organization. This rule applies even if the folders and projects within that organization have more permissive deny policies, or allow policies that give the principal the permission.

Similarly, if an allow policy for a project gives a principal a specific permission, then the principal has that permission for any resource within the project, provided that they aren't denied that permission.

The Policy details section contains the following sections:

Access state

The Access state section contains a brief summary of the principal's access based on the relevant IAM allow and deny policies. This summary includes the impact of deny policies, the impact of allow policies, and the final access result based on the relevant deny and allow policies.

Deny policy

In the Deny policy section, you can view all relevant deny policies, identify deny rules that deny access to the principal, and understand why a deny rule denies or doesn't deny the principal the permission.

The Resources with deny policies pane lists all relevant deny policies, organized by the resources they're attached to. Next to each deny policy is an access evaluation. This evaluation only applies to that deny policy—it doesn't reflect any access from inherited policies. If you don't have permission to view a resource's deny policy, the resource list does not include that resource or its deny policies.

To view the relevant deny rules in these deny policies, click a deny policy. To view all deny rules in a resource's deny policies, click a resource. The deny rules appear in the Deny rules pane. This pane contains a table of all deny rules with the queried principal or permission for the resource or deny policy you've selected.

The Access column indicates whether the deny rule denies the principal the permission. To see more details about the deny rule, click See deny rule in that rule's row.

Allow policy

In the Allow policy section, you can navigate through all relevant allow policies, identify role bindings that grant access to the principal, and understand why a role binding gives or doesn't give the principal the permission.

The Resources pane lists the specified resource and its ancestors. Next to each resource is an access evaluation. This evaluation only applies to that resource's allow policy—it doesn't reflect any access from inherited policies. If you don't have permission to view a resource's allow policy, the resource list does not include that resource.

To view the relevant role bindings in a resource's allow policy and see how they do or don't give the principal the permission, click the resource. The allow policy's bindings appear in the Role bindings pane.

The Role bindings pane contains a table of role bindings in the selected resource's allow policy. By default, the table only contains role bindings that include a role with the specified permission. If the principal doesn't have access, the table also shows role bindings with editable custom roles. To see all role bindings, clear the Show only relevant bindings checkbox.

The Access column indicates whether the role binding gives the principal the permission. To see more details about the role binding, click See binding details in that binding's row.

gcloud

The response contains four main sections: a description of the access tuple in the request, the results of the allow policy evaluation, the results of the deny policy evaluation, and the overall access state.

  • accessTuple: A description of the access tuple in the request, including any condition context that you provided. This section also contains a summary of the tags that apply to the resource.
  • allowPolicyExplanation: A summary of whether the relevant allow policies grant the principal the permission, followed by a list of allow policies and their role bindings.

    For each allow policy, the response lists all role bindings in the policy and evaluates them based on the following criteria:

    • Whether the binding includes the permission.
    • Whether the binding includes the principal.
    • Whether the conditions in the binding, if any, are met.

    Then, the response prints the full JSON text of the allow policy.

  • denyPolicyExplanation: A summary of whether the relevant deny policies deny the principal the permission, followed by a list of resources with deny policies. For each resource, the response lists all deny policies attached to the resource.

    For each deny policy, the response prints the policy's metadata, lists the deny rules in the policy, then evaluates each rule based on the following criteria:

    • Whether the deny rule includes the permission.
    • Whether the permission is listed as an exception in the deny rule.
    • Whether the deny rule includes the principal.
    • Whether the principal is listed as an exception in the deny rule.
    • Whether the conditions in the deny rule, if any, are met.
  • overallAccessState: Whether the principal is able to use the specified permission to access the specified resource based on the relevant allow and deny policies.

    Relevant allow and deny policies include the following:

    • The resource's allow policy
    • The resource's deny policies, if any
    • The allow policies of the resource's parent project, folder, and organization, if any
    • The deny policies of the resource's parent project, folder, and organization, if any

    The allow and deny policies of parent projects, folders, and organizations are relevant because of policy inheritance. When you attach an allow or deny policy to a project, folder, or organization, that policy also applies for all resources inside that project, folder, or organization.

    For example, if a deny policy for an organization says that a principal can't use a specific permission, then the principal can't use that permission for any resource within the organization. This rule applies even if the folders and projects within that organization have more permissive deny policies, or allow policies that give the principal the permission.

    Similarly, if an allow policy for a project gives a principal a specific permission, then the principal has that permission for any resource within the project, provided that they aren't denied that permission.

  • Many objects in the response also have a relevance field. The value in this field indicates how much that object contributes to the overall access state. The relevance field can have the following values:

    • HEURISTIC_RELEVANCE_HIGH: Indicates that the object has a strong impact on the result. In other words, removing the object will likely change the overall access state. For example, a role binding that grants the principal the specified permission would have this relevance value.

    • HEURISTIC_RELEVANCE_NORMAL: Indicates that the object has a limited impact on the result. In other words, removing the object is unlikely to change the overall access state. For example, a deny rule that doesn't contain the permission or the principal would have this relevance value.

REST

The response contains four main sections: the overall access state, a description of the access tuple in the request, the results of the allow policy evaluation, and the results of the deny policy evaluation.

  • overallAccessState: Whether the principal is able to use the specified permission to access the specified resource based on the relevant allow and deny policies.

    Relevant allow and deny policies include the following:

    • The resource's allow policy
    • The resource's deny policies, if any
    • The allow policies of the resource's parent project, folder, and organization, if any
    • The deny policies of the resource's parent project, folder, and organization, if any

    The allow and deny policies of parent projects, folders, and organizations are relevant because of policy inheritance. When you attach an allow or deny policy to a project, folder, or organization, that policy also applies for all resources inside that project, folder, or organization.

    For example, if a deny policy for an organization says that a principal can't use a specific permission, then the principal can't use that permission for any resource within the organization. This rule applies even if the folders and projects within that organization have more permissive deny policies, or allow policies that give the principal the permission.

    Similarly, if an allow policy for a project gives a principal a specific permission, then the principal has that permission for any resource within the project, provided that they aren't denied that permission.

  • accessTuple: A description of the access tuple in the request, including any condition context that you provided. This section also contains a summary of the tags that apply to the resource.
  • allowPolicyExplanation: A summary of whether the relevant allow policies grant the principal the permission, followed by a list of allow policies and their role bindings.

    For each allow policy, the response lists all role bindings in the policy and evaluates them based on the following criteria:

    • Whether the binding includes the permission.
    • Whether the binding includes the principal.
    • Whether the conditions in the binding, if any, are met.

    Then, the response prints the full JSON text of the allow policy.

  • denyPolicyExplanation: A summary of whether the relevant deny policies deny the principal the permission, followed by a list of resources with deny policies. For each resource, the response lists all deny policies attached to the resource.

    For each deny policy, the response prints the policy's metadata, lists the deny rules in the policy, then evaluates each rule based on the following criteria:

    • Whether the deny rule includes the permission.
    • Whether the permission is listed as an exception in the deny rule.
    • Whether the deny rule includes the principal.
    • Whether the principal is listed as an exception in the deny rule.
    • Whether the conditions in the deny rule, if any, are met.
  • Many objects in the response also have a relevance field. The value in this field indicates how much that object contributes to the overall access state. The relevance field can have the following values:

    • HEURISTIC_RELEVANCE_HIGH: Indicates that the object has a strong impact on the result. In other words, removing the object will likely change the overall access state. For example, a role binding that grants the principal the specified permission would have this relevance value.

    • HEURISTIC_RELEVANCE_NORMAL: Indicates that the object has a limited impact on the result. In other words, removing the object is unlikely to change the overall access state. For example, a deny rule that doesn't contain the permission or the principal would have this relevance value.

Troubleshooting conditional role bindings

Policy Troubleshooter automatically troubleshoots conditional role bindings and deny rules based on tags. However, to troubleshoot other kinds of conditional role bindings or conditional deny rules, Policy Troubleshooter needs additional context about the request. For example, to troubleshoot conditions based on date/time attributes, Policy Troubleshooter needs the time of the request.

In the gcloud CLI and REST API, you provide this additional context manually.

In the Google Cloud console, you can provide this additional context by troubleshooting directly from any Admin Activity audit log or Data Access audit log. Each audit log entry corresponds to a request to a Google Cloud API, or an action that Google Cloud takes on your behalf. When you troubleshoot from an audit log, Policy Troubleshooter automatically gets additional information about the request, such as its date and time, which allows Policy Troubleshooter to analyze conditional role bindings and deny rules.

Console

To troubleshoot conditional role bindings and deny rules, do the following:

  1. In the Google Cloud console, go to the Logs Explorer page.

    Go to the Logs Explorer

  2. If the page title is Legacy Logs Viewer, click the Upgrade drop-down list and select Upgrade to the new Logs Explorer.

  3. To view only Admin Activity and Data Access audit logs, enter the following query in the query builder, then click Run query:

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

    Replace the following values:

    • RESOURCE_TYPE: The resource type that you are listing audit logs for. Use projects, folders, or organizations.
    • RESOURCE_ID: The ID of your resource.
  4. Locate the audit log entry that corresponds to the request that you want to troubleshoot. To learn how to use the Logs Explorer to find specific log entries, see Using the Logs Explorer.

  5. In the Summary column of the log entry, click IAM, then click Troubleshoot access issue.

    Policy Troubleshooter uses the information in the log entry to troubleshoot access, then shows you the results. The additional context is listed in the evaluation details under Condition context. To view the context details, click View condition context. To learn more about the Policy Troubleshooter results page, see Troubleshooting access on this page.

  6. Optional: To troubleshoot another request that involves conditional role bindings and deny rules, return to the Logs Explorer page and repeat the previous steps.

gcloud

To troubleshoot conditional role bindings and deny rules, use the gcloud policy-troubleshoot iam command.

Before using any of the command data below, make the following replacements:

  • EMAIL: The email address of the principal whose permissions you want to troubleshoot.
  • RESOURCE: The resource on which the permission is granted.
  • PERMISSION: The permission that you want to troubleshoot.
  • DESTINATION_IP: Optional. The request destination IP address to use when checking conditional role bindings. For example, 198.1.1.1.
  • DESTINATION_PORT: Optional. The request destination port to use when checking conditional role bindings. For example, `8080`.
  • REQUEST_TIME: Optional. The request timestamp to use when checking conditional role bindings. Use a timestamp in RFC 3339format—for example, 2099-02-01T00:00:00Z.
  • RESOURCE_NAME: Optional. The resource name value to use when checking conditional role bindings. For a list of accepted resource name formats, see Resource name format.
  • RESOURCE_SERVICE: Optional. The resource service value to use when checking conditional role bindings. For a list of accepted service names, see Resource service values.
  • RESOURCE_TYPE: Optional. For a list of accepted resource types, see Resource type values.

Execute the gcloud policy-troubleshoot iam command:

Linux, macOS, or 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

The response contains an explanation of the principal's access. For each role binding and deny rule with a condition, the response includes a conditionExplanation field describing whether the condition evaluates to true or false based on the condition context that you provided.

For example, the following is an evaluation of a role binding with a condition specifying the resource type and resource service:

...
{
  "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

To troubleshoot conditional role bindings and deny rules, use the Policy Troubleshooter API's iam.troubleshoot method.

Before using any of the request data, make the following replacements:

  • EMAIL: The email address of the principal whose permissions you want to troubleshoot.
  • RESOURCE: The resource on which the permission is granted.
  • PERMISSION: The permission that you want to troubleshoot.
  • DESTINATION_IP: Optional. The request destination IP address to use when checking conditional role bindings. For example, 198.1.1.1.
  • DESTINATION_PORT: Optional. The request destination port to use when checking conditional role bindings. For example, `8080`.
  • REQUEST_TIME: Optional. The request timestamp to use when checking conditional role bindings. Use a timestamp in RFC 3339format—for example, 2099-02-01T00:00:00Z.
  • RESOURCE_NAME: Optional. The resource name value to use when checking conditional role bindings. For a list of accepted resource name formats, see Resource name format.
  • RESOURCE_SERVICE: Optional. The resource service value to use when checking conditional role bindings. For a list of accepted service names, see Resource service values.
  • RESOURCE_TYPE: Optional. For a list of accepted resource types, see Resource type values.

HTTP method and URL:

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

Request JSON body:

{
  "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
      }
    }
  }
}

To send your request, expand one of these options:

The response contains an explanation of the principal's access. For each role binding and deny rule with a condition, the response includes a conditionExplanation field describing whether the condition evaluates to true or false based on the condition context that you provided.

For example, the following is an evaluation of a role binding with a condition specifying the resource type and resource service:

...
{
  "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
    }]
  }
}
...

What's next