Summary
| Forestall ACL Alias | GCP_SET_ORG_IAMPOLICY |
| GCP Alias | IAM & Hierarchy Control |
| Affected Object Types | Organizations |
| Exploitation Certainty | Certain |
| Granting Roles | roles/owner, roles/resourcemanager.organizationAdmin, roles/iam.securityAdmin |
Description
GCP_SET_ORG_IAMPOLICY indicates that an identity can call setIamPolicy on the GCP Organization resource. This is the highest-privilege IAM write operation in the GCP resource hierarchy — a principal with this edge can grant any role to any identity at the organization root, which propagates down to every folder and project beneath it.
An attacker who obtains this permission can instantly escalate to full organization control by granting themselves (or a backdoor identity) roles/owner at the org level, effectively compromising every resource in the organization.
Key abuse scenarios:
- Grant
roles/ownerto a controlled identity at org scope. - Add an external attacker-controlled service account as
roles/resourcemanager.organizationAdmin. - Grant
roles/iam.serviceAccountTokenCreatoron a high-privilege SA to enable token generation from anywhere.
Identification
gcloud CLI
# List the organization's IAM policy and find who can set itORG_ID=$(gcloud organizations list --format="value(name)" | head -1)gcloud organizations get-iam-policy $ORG_ID --format=json | \ jq '.bindings[] | select(.role == "roles/owner" or .role == "roles/resourcemanager.organizationAdmin" or .role == "roles/iam.securityAdmin") | {role: .role, members: .members}'GCP Console
- Open GCP Console → IAM & Admin → IAM.
- Select the Organization from the resource selector at the top.
- Review all principals with
Owner,Organization Admin, orSecurity Adminroles.
Exploitation
With setIamPolicy on the organization, an attacker can grant themselves or a backdoor identity any role organization-wide.
gcloud CLI
# Grant owner to attacker-controlled account at org levelORG_ID=$(gcloud organizations list --format="value(name)" | head -1)gcloud organizations add-iam-policy-binding $ORG_ID \ --role="roles/owner"
# Add a backdoor service account as org admin.ORG_ID=$(gcloud organizations list --format="value(name)" | head -1)gcloud organizations add-iam-policy-binding $ORG_ID \ --role="roles/resourcemanager.organizationAdmin"Compound path: GCP_SET_ORG_IAMPOLICY → grant roles/iam.serviceAccountTokenCreator on a high-privilege SA → GCP_IMPERSONATE_SA → full org access via token generation.
Mitigation
-
Restrict org IAM admin roles to break-glass accounts only: Remove
roles/owner,roles/resourcemanager.organizationAdmin, androles/iam.securityAdminfrom user accounts where not strictly required. -
Enable
constraints/iam.managed.allowedPolicyMembersorg policy — restrict IAM bindings to your organization’s domain. -
Audit org-level bindings regularly.
-
Enable VPC Service Controls and Access Context Manager to contain blast radius even if org IAM is compromised.
Detection
Monitor Cloud Audit Logs for SetIamPolicy calls on organization resources.
| Log Type | Method | Key Fields |
|---|---|---|
| Admin Activity | SetOrgPolicy SetIamPolicy |
resource.type=organization, methodName=SetIamPolicy |
| Data Access | IAM policy reads | methodName=GetIamPolicy on org |
# Query Cloud Audit Logs for org-level IAM policy changesORG_ID=$(gcloud organizations list --format="value(name)" | head -1)gcloud logging read \ 'resource.type="organization" AND protoPayload.methodName="SetIamPolicy"' \ --organization=$ORG_ID \ --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.request.policy.bindings)"Alert on:
- Any
SetIamPolicycall on the organization resource. - New bindings adding
roles/owner,roles/resourcemanager.organizationAdmin, orroles/iam.securityAdminat org scope.