GCP_CAN_MODIFY_CUSTOM_ROLES

Summary

FSProtect ACL Alias

GCP_CAN_MODIFY_CUSTOM_ROLES

GCP Alias

IAM & Hierarchy Control

Affected Object Types

Organizations, Folders, Projects

Exploitation Certainty

Certain

Granting Roles

roles/owner, roles/iam.roleAdmin

Description

GCP_CAN_MODIFY_CUSTOM_ROLES indicates that an identity holds iam.roles.update on a GCP project or organization, granting the ability to create and modify custom IAM roles. This is a particularly stealthy privilege escalation path: instead of creating new IAM bindings (which are visible in policy diffs), an attacker can silently add dangerous permissions to a custom role that is already bound to their identity.

If the attacker's identity already holds a custom role binding, modifying that role to include resourcemanager.projects.setIamPolicy or iam.serviceAccounts.getAccessToken escalates privileges without any change to the IAM policy bindings — the escalation is not visible in SetIamPolicy audit logs.

Key abuse scenarios:

  • Add resourcemanager.projects.setIamPolicy to a custom role the attacker already holds → instant project-level IAM takeover.

  • Add iam.serviceAccounts.getAccessToken → directly impersonate any SA in the project.

  • Add iam.serviceAccounts.actAs + compute.instances.create → create VMs attached to privileged SAs.

Identification

gcloud CLI

GCP Console

  1. Open GCP ConsoleIAM & AdminRolesCustom tab.

  2. Click each custom role and review Included Permissions for dangerous entries.

  3. Check IAM & AdminIAM for principals with IAM Role Admin or Owner.

Exploitation

gcloud CLI

Alternatively, add token creator permission for direct SA impersonation:

Compound path: GCP_CAN_MODIFY_CUSTOM_ROLES → add setIamPolicy to a role already bound to the attacker → GCP_CAN_SET_PROJECT_IAMPOLICY → full project takeover with no new IAM binding visible in policy diff logs.

Mitigation

  1. Restrict roles/iam.roleAdmin to dedicated automation accounts; never assign to human users in production.

  2. Separate role definition from role assignment — use different principals for iam.roles.update and iam.bindings.update.

  3. Audit custom role permission changes with the same urgency as IAM policy changes — UpdateRole does not appear in IAM policy diff alerts.

  4. Use constraints/iam.allowedPolicyMemberDomains to limit who can be added to bindings even if a role is escalated.

Detection

Log Type
Method
Key Fields

Admin Activity

google.iam.admin.v1.UpdateRole

resource.type=iam_role, permission additions in request

Admin Activity

google.iam.admin.v1.CreateRole

New custom role created with dangerous permissions

Alert on:

  • Any UpdateRole call adding permissions containing setIamPolicy, actAs, or getAccessToken.

  • New custom roles created with dangerous permission combinations.

  • Role updates by identities outside of a known infrastructure automation pipeline.

References

  • https://cloud.google.com/iam/docs/creating-custom-roles

  • https://cloud.google.com/iam/docs/understanding-custom-roles

Last updated

Was this helpful?