GCP_SET_FOLDER_IAMPOLICY
Summary
| Forestall ACL Alias | GCP_SET_FOLDER_IAMPOLICY |
| GCP Alias | IAM & Hierarchy Control |
| Affected Object Types | Folders |
| Exploitation Certainty | Certain |
| Granting Roles | roles/owner, roles/resourcemanager.organizationAdmin, roles/resourcemanager.folderAdmin, roles/resourcemanager.folderIamAdmin, roles/iam.securityAdmin |
Description
GCP_SET_FOLDER_IAMPOLICY indicates that an identity can call setIamPolicy on a GCP Folder. Folders are intermediate containers in the GCP resource hierarchy that sit between the Organization and Projects. A principal who can set IAM policy on a folder gains control over every project nested beneath that folder.
An attacker with this edge can grant themselves broad roles on the folder, which inherit down to all child projects and their resources. The blast radius depends on how many projects live under the targeted folder.
Key abuse scenarios:
- Grant
roles/ownerto a controlled identity at folder scope, inheriting to all child projects. - Add a backdoor service account as
roles/resourcemanager.folderAdminfor persistence. - Grant
roles/iam.serviceAccountTokenCreatoron service accounts scoped under the folder.
Identification
gcloud CLI
# List all folders in the organizationORG_ID=$(gcloud organizations list --format="value(name)" | head -1)gcloud resource-manager folders list --organization=$ORG_ID --format="table(name, displayName)"
# Get IAM policy for a specific folderFOLDER_ID="folders/123456789"gcloud resource-manager folders get-iam-policy $FOLDER_ID --format=json | \ jq '.bindings[] | select(.role | test("owner|folderAdmin|folderIamAdmin|iam.securityAdmin|organizationAdmin")) | {role: .role, members: .members}'
# Check who can set IAM policy across all foldersORG_ID=$(gcloud organizations list --format="value(name)" | head -1)for FOLDER in $(gcloud resource-manager folders list --organization=$ORG_ID --format="value(name)"); do echo "=== $FOLDER ===" gcloud resource-manager folders get-iam-policy $FOLDER \ --flatten="bindings[].members" \ --format="table(bindings.role,bindings.members)" \ --filter="bindings.role:(roles/owner OR roles/resourcemanager.folderAdmin OR roles/resourcemanager.folderIamAdmin)"doneGCP Console
- Open GCP Console → IAM & Admin → IAM.
- Select the target Folder from the resource selector.
- Review all principals with
Owner,Folder Admin, orFolder IAM Adminroles.
Exploitation
gcloud CLI
# Grant owner at folder scope (inherits to all child projects)FOLDER_ID="folders/123456789"gcloud resource-manager folders add-iam-policy-binding $FOLDER_ID \ --role="roles/owner"
# Grant folder IAM admin to backdoor service accountgcloud resource-manager folders add-iam-policy-binding $FOLDER_ID \ --role="roles/resourcemanager.folderIamAdmin"Compound path: Folder-level setIamPolicy → grant roles/iam.serviceAccountTokenCreator on all service accounts under the folder’s projects → impersonate high-privilege SAs.
Mitigation
- Limit folder IAM admin roles to dedicated admin accounts with MFA enforced.
- Use Privileged Access Manager for just-in-time elevation of folder-scoped roles.
- Apply
constraints/iam.allowedPolicyMemberDomainsat the org level to prevent granting access to external identities. - Regularly audit folder IAM policies:
gcloud resource-manager folders get-iam-policy $FOLDER_ID --format=json | \jq '.bindings[] | select(.role | test("Admin|owner"))'
Detection
| Log Type | Method | Key Fields |
|---|---|---|
| Admin Activity | SetIamPolicy |
resource.type=folder, methodName=SetIamPolicy |
gcloud logging read \ 'resource.type="folder" AND protoPayload.methodName="SetIamPolicy"' \ --organization=$ORG_ID \ --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, resource.labels.folder_id)"Alert on:
SetIamPolicycalls on folder resources.- New bindings adding
roles/owner,roles/resourcemanager.folderAdmin, orroles/resourcemanager.folderIamAdmin.