GCP_CUSTOM_PRIVILEGED_ROLE
Summary
| Forestall ACL Alias | GCP_CUSTOM_PRIVILEGED_ROLE |
| GCP Alias | IAM & Hierarchy Control |
| Affected Object Types | Organizations, Folders, Projects |
| Exploitation Certainty | Likely |
| Granting Roles | Any custom IAM role flagged as privileged |
Description
GCP_CUSTOM_PRIVILEGED_ROLE represents an assignment of a GCP custom IAM role that is flagged as privileged and does not have an explicit, mapped attack path edge. Unlike predefined roles, custom roles are organization- or project-defined and can contain any combination of permissions. This makes them particularly dangerous because a custom role may appear innocuous by name but contain highly sensitive permissions, and the permissions are not covered by specific attack path mappings.
Custom privileged roles are often created during migrations, automation setups, or in attempts to implement least-privilege but inadvertently combine dangerous permissions. They are also a common persistence mechanism: an attacker who creates or modifies a custom role can hide high-privilege access behind a benign-sounding role name.
Identification
gcloud CLI
# List all custom roles in a projectPROJECT_ID="my-project"gcloud iam roles list --project=$PROJECT_ID --format=json
# Inspect a specific custom role's permissionsCUSTOM_ROLE="projects/${PROJECT_ID}/roles/CustomProjectRole"gcloud iam roles describe $(basename $CUSTOM_ROLE) --project=$PROJECT_ID --format=json | \ jq '.includedPermissions[]'
# Find who is assigned custom roles in a projectgcloud projects get-iam-policy $PROJECT_ID --format=json | \ jq '.bindings[] | select(.role | contains("/roles/")) | {role: .role, members: .members}'GCP Console
- Open GCP Console → IAM & Admin → Roles.
- Select “Custom” tab.
- Click each role and review Included Permissions.
- Cross-reference against IAM page bindings.
Exploitation
The exact exploitation steps depend on the specific permissions present in the custom role.
Common dangerous permissions found in flagged custom roles and their attack vectors:
resourcemanager.projects.setIamPolicy→ privilege escalation via IAM policy manipulation → see GCP_SET_PROJECT_IAMPOLICYresourcemanager.folders.setIamPolicy→ privilege escalation via IAM policy manipulation → see GCP_SET_FOLDER_IAMPOLICYresourcemanager.organizations.setIamPolicy→ privilege escalation via IAM policy manipulation → see GCP_SET_ORG_IAMPOLICYiam.serviceAccounts.actAs→ SA attachment to compute resources → see GCP_ACT_AS_SA.iam.serviceAccounts.getAccessToken→ direct SA token generation → see GCP_IMPERSONATE_SA.compute.instances.create+ SA attachment → vehicle for token extraction → see GCP_CREATE_COMPUTE + GCP_ACT_AS_SA.
Mitigation
- Audit all custom roles flagged by this edge — identify what permissions each contains and whether they’re necessary.
- Remove or split roles containing dangerous permission combinations — do not allow a single custom role to include those permissions together.
- Enforce naming conventions and documentation for custom roles so their purpose is transparent and auditable.
- Restrict
roles/iam.roleAdminto dedicated automation accounts — this role controls custom role creation/modification. - Regularly review custom role bindings — custom roles should have a documented owner, business justification, and expiry policy.
Detection
| Log Type | Method | Key Fields |
|---|---|---|
| Admin Activity | CreateRole UpdateRole |
resource.type=iam_role, custom role modification |
| Admin Activity | SetIamPolicy |
New binding adding a custom role |
# Monitor for custom role creations and updates in a projectPROJECT_ID="my-project"gcloud logging read \ 'protoPayload.methodName=("google.iam.admin.v1.CreateRole" OR "google.iam.admin.v1.UpdateRole")' \ --project=$PROJECT_ID \ --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.resourceName, protoPayload.methodName)"
# Monitor for new custom role assignments in a projectgcloud logging read \ 'protoPayload.methodName="SetIamPolicy" AND protoPayload.serviceData.policyDelta.bindingDeltas.role:"/roles/"' \ --project=$PROJECT_ID \ --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.serviceData.policyDelta.bindingDeltas)"Alert on:
- Any creation or update of a custom role (
CreateRole,UpdateRole). - Modifications to custom roles adding dangerous permissions (
setIamPolicy,actAs,getAccessToken). - New bindings assigning custom roles to human users or external identities.
- Custom role assignments at org or folder scope.