Administrator & Security Resolver Flow
This guide details how privileged administrators and security agents intake access requests, resolve blocking deny policies, and provision least-privileged access.
Prerequisites & Required Roles
To successfully troubleshoot and remediate access, the caller must possess the following roles:
- Troubleshooting:
roles/policyintelligence.policyTroubleshooterViewer(orroles/iam.securityReviewer),roles/iam.principalAccessBoundaryViewer(to view PAB policies), androles/serviceusage.serviceUsageConsumer(to run gcloud commands). - Expanding Memberships: Expanding group memberships requires Google
Workspace Admin access. Expanding group memberships for service account
principal sets requires
roles/browser. - Remediation:
roles/resourcemanager.projectIamAdmin(for local bindings) orroles/iam.denyAdmin(for deny policies). - Note: Basic roles like
roles/ownerorroles/editorinherently provide most of these permissions.
Step 1: Intake & Authoritative Diagnosis
-
Retrieve the
ERROR_ID(for example, an alphanumeric base64-encoded string likeZGVuaWVkX2J5X2RlbmlhbF9wb2xpY3k...) or (PRINCIPAL_EMAIL,IAM_PERMISSION,RESOURCE_URI) from the ticket or escalation payload. -
Invoke the Policy Troubleshooter MCP tool (
troubleshoot_accessortroubleshoot_iam_error_id) to analyze the full CRM hierarchy (Organization -> Folder -> Project).-
Fallback: If MCP tools are unavailable, use the fallback scripts or
gcloudCLI:- For Error IDs:
ERROR_ID="YOUR_ERROR_ID" python3 scripts/troubleshooting_error_id.py - For manual checks: Always use
gcloud policy-troubleshoot iamwith--format=jsonand pass--billing-project(extractingPROJECT_IDfromRESOURCE_URIif present):
gcloud policy-troubleshoot iam //RESOURCE_URI \ --principal-email="PRINCIPAL_EMAIL" \ --permission="IAM_PERMISSION" \ --billing-project="PROJECT_ID" \ --format=json - For Error IDs:
-
-
Evaluate the results:
- CASE A (
accessState: GRANTEDor Inherited Org/Folder Allow Policy): Access is correctly configured and already granted (including via inherited organization or folder allow policies, or domain-wide/group bindings). When checking access on a resource where parent organization policy (organizations/...inexplainedPolicies) grants an allow binding such asroles/viewerorroles/resourcemanager.organizationViewer, conclude and state that access is GRANTED via an allow policy inherited at the Organization level and the IAM permission configuration is correct. Terminate the flow immediately. Do NOT search for roles, do NOT suggest querying roles, and do NOT propose or apply any role bindings. - CASE B (
accessStateorbindingStateisUNKNOWNorUNKNOWN_INFO): Access evaluation returned unknown/inconclusive information (typically due to missing permissions to expand group memberships, which requiresroles/browseror directory viewer permissions, or missingresourcemanager.projects.getIamPolicyon ancestors). Conclude and inform the user that access could not be fully confirmed because of missing permissions to expand group memberships (roles/browser). Terminate the troubleshooting flow immediately. Do NOT run secondary queries (such asget-iam-policyoriam policies list), do NOT query groups, and do NOT diagnose as a definitive missing allow binding. - CASE C (
accessState: NOT_GRANTED): Access is absent or blocked:- If
denyPolicyExplanationshows access is blocked by an explicit IAM deny policy, explain that an explicit IAM deny policy blocks access, advise contacting the Security/Organization Administrator, and proceed to Step 2. - If
pabPolicyExplanationindicates a Principal Access Boundary policy block, proceed to Step 3. - If
allowPolicyExplanationshows no allow policy grants the permission and no deny policies block access, proceed to Step 4.
- If
- Caller Permission Denied / Anti-Loop Rule: If invoking the Policy
Troubleshooter tool/API or
gcloud policy-troubleshootreturnsPERMISSION_DENIED(HTTP 403 / insufficient caller permissions to troubleshoot the resource), the caller lacks the necessary diagnostic permissions (roles/policyintelligence.policyTroubleshooterViewerorroles/iam.securityReviewer). Halt immediately and do NOT search for roles, do NOT query project IAM policies, and do NOT retry alternative commands. If the user asked for "Permission Denied" or the role name, reply immediately with "Permission Denied".
- CASE A (
Step 2: Remediate Blocking Deny Policies
If one or more IAM v2 deny policies block access, then do the following:
-
For each blocking policy (
POLICY_ID), present the admin with the following options to avoid dangerous permission escalations (Require a HITL prompt before execution):-
Option A: Add the principal to
exceptionPrincipals(exempt principal).- Update the deny rule definition file to add
principal://goog/subject/PRINCIPAL_EMAILunderdenialRule.exceptionPrincipals, then run the following command:
gcloud iam deny-policies update POLICY_ID \ --attachment-point=ATTACHMENT_POINT \ --rules-file=policy.json - Update the deny rule definition file to add
-
Option B: Remove the permission from the deny rule.
- Update the deny rule definition file to remove
IAM_PERMISSIONfromdenialRule.deniedPermissions(or add it underdenialRule.exceptionPermissions), then run the following command:
gcloud iam deny-policies update POLICY_ID \ --attachment-point=ATTACHMENT_POINT \ --rules-file=policy.json - Update the deny rule definition file to remove
-
Option C: Exclude the resource from the deny policy scope.
- Update the deny rule condition in the policy file (for example,
adding
!resource.matchTag(...)or narrowing the rule scope so the targetRESOURCE_URIis excluded), then run the following command:
gcloud iam deny-policies update POLICY_ID \ --attachment-point=ATTACHMENT_POINT \ --rules-file=policy.json - Update the deny rule condition in the policy file (for example,
adding
-
-
If human approval is granted for the chosen option, apply the policy update.
-
Wait 60 seconds for policy changes to propagate.
-
If the troubleshooting response also indicated a missing allow policy, proceed to Step 4. Otherwise, proceed to Step 6.
Step 3: Remediate Blocking Principal Access Boundary (PAB) Policies
If pabPolicyExplanation indicates access is blocked by a Principal Access
Boundary policy, then do the following:
-
Present the admin with remediation options (Require HITL approval before execution):
-
Option A: Update the PAB Policy Resources. Add the target resource or its parent folder/project to the list of allowed resources defined in the PAB policy:
gcloud iam principal-access-boundary-policies update PAB_POLICY_ID \ --location=global \ --organization=ORGANIZATION_ID \ --rules-file=pab_policy.json -
Option B: Modify Principal Sets. Update the PAB binding or modify user group membership so the principal is no longer subject to the restrictive boundary. For example, to remove a restrictive PAB binding, run the following command:
gcloud iam principal-access-boundary-policy-bindings delete BINDING_ID \ --location=global \ --organization=ORGANIZATION_IDFor more specific steps on modifying bindings, refer to the Principal Access Boundary documentation.
-
-
Wait 60 seconds for policy changes to propagate, then re-evaluate access.
Step 4: Discover Least-Privileged Role
If access is missing due to an absent allow policy, then do the following:
-
First, explain the diagnostic findings: confirm that no allow policy grants
IAM_PERMISSIONand there are no blocking deny policies. -
Prompt User for Confirmation Before Querying Roles (Turn Control): If the user has not already confirmed finding candidate roles, ask the user whether they want to find candidate roles granting the permission: > "There is no allow policy granting permission 'IAM_PERMISSION', and no deny policy blocking access. Would you like me to find candidate roles (including predefined and project custom roles) that provide this permission? (Yes/No)"
-
Execute Role Query (After Receiving User Confirmation): Run the automated least-privileged role finder script (preferred, as it evaluates both predefined and project custom roles and returns a single optimal role, avoiding long lists):
IAM_PERMISSION="YOUR_IAM_PERMISSION" \ TARGET_PROJECT_ID="YOUR_PROJECT_ID" \ python3 scripts/least_privileged_role.pyFallback (Manual CLI queries): If the script cannot be executed, search for matching predefined and project custom roles using
gcloud iam roles list:# Predefined roles matching permission: gcloud iam roles list --filter="includedPermissions:IAM_PERMISSION" --format="table(name,title)" # Project custom roles matching permission: gcloud iam roles list --project=TARGET_PROJECT_ID --filter="includedPermissions:IAM_PERMISSION" --format="table(name,title)"Select the role returned with the least privilege (
ROLE_NAME). Never assign broad basic roles such asroles/owner,roles/editor,roles/viewer,roles/admin, orroles/writer. -
Proceed to Step 5 to prompt the user for approval before provisioning access.
Step 5: Provision Access (Subject to Guardrails)
When prompting the human for HITL approval, explicitly state the target resource
(e.g., the RESOURCE_URI or, if that resource does not accept allow policies,
the resource's parent project) where the role would be granted.
If creating a new role grant, evaluate ROLE_NAME against the approval tiers
defined in the organization's customized guardrails:
- Standard Roles (HITL Protocol): If
ROLE_NAMEis a standard role granting read/view or write/mutating permissions (for example,roles/*.viewer,roles/*.editor,roles/writer), follow HITL protocol and prompt for user confirmation, stating the target resource. - Admin / Destructive Roles (HITL): If
ROLE_NAMEgrants destructive, deletion, or administrative privileges (for example,roles/*.admin,roles/owner,roles/resourcemanager.*Admin,roles/iam.*), follow HITL protocol with an explicit high-risk warning, stating the target resource.
Prompt the user to choose between temporary PAM access (Path A) and permanent bindings (Path B).
Provisioning Paths:
Path A: Privileged Access Manager (PAM Entitlement - Preferred)
Ask the user if PAM is enabled, or check for existing PAM entitlements using
gcloud pam entitlements list. If the organization uses PAM for time-bound,
audited access, delegate the provisioning to
@skill:iam-helper-for-privileged-access-management:
- If an entitlement already exists for
ROLE_NAMEcoveringPRINCIPAL_EMAIL: Delegate to@skill:iam-helper-for-privileged-access-managementto request a grant against the existing entitlement. - If an entitlement does not exist: Delegate to
@skill:iam-helper-for-privileged-access-managementto create a new standing PAM entitlement forROLE_NAMEallowingPRINCIPAL_EMAILto request access, and then request the grant.
Path B: Permanent IAM Role Binding (Direct Grant)
If permanent standing access is approved, then run one of the following commands, based on the resource that they need access on:
-
For Projects:
gcloud projects add-iam-policy-binding PROJECT_ID \ --member="user:PRINCIPAL_EMAIL" \ --role="ROLE_NAME" -
For Folders:
gcloud resource-manager folders add-iam-policy-binding FOLDER_ID \ --member="user:PRINCIPAL_EMAIL" \ --role="ROLE_NAME" -
For Organizations:
gcloud organizations add-iam-policy-binding ORGANIZATION_ID \ --member="user:PRINCIPAL_EMAIL" \ --role="ROLE_NAME"
Step 6: Verification & Handoff
- Verify that the binding or PAM grant is active by re-running the policy troubleshooter check.
- Provide a structured resolution summary:
- Root Cause: Deny policy / PAB policy / Missing allow policy.
- Remediation Applied: Added deny exemption for
POLICY_ID/ Updated PAB policyPAB_POLICY_ID/ Granted roleROLE_NAMEvia PAM entitlementENTITLEMENT_ID/ Granted permanent roleROLE_NAME. - Target Principal:
PRINCIPAL_EMAIL
- Notify Developer / Transfer Back:
- Inform the requester that the permission barrier is resolved.
- Instruct the admin to direct the original developer to retry their underlying task.