GCP_SET_PROJECT_IAMPOLICY
Summary
| Forestall ACL Alias | GCP_SET_PROJECT_IAMPOLICY |
| GCP Alias | IAM & Hierarchy Control |
| Affected Object Types | Projects |
| Exploitation Certainty | Certain |
| Granting Roles | roles/owner, roles/resourcemanager.organizationAdmin, roles/resourcemanager.folderAdmin, roles/resourcemanager.projectIamAdmin, roles/iam.securityAdmin |
Description
GCP_SET_PROJECT_IAMPOLICY indicates that an identity can call setIamPolicy on a GCP Project. Projects are the primary security and billing boundary in GCP. A principal who can set IAM policy on a project can grant themselves or any identity any role within that project, gaining full control over all the project’s resources.
This is one of the most impactful privilege escalation paths in GCP. Even a project-scoped setIamPolicy is dangerous because projects typically contain service accounts, compute instances, Cloud Build pipelines, and Cloud Storage buckets that can be leveraged for further escalation.
Key abuse scenarios:
- Grant
roles/ownerto a controlled identity at project scope. - Grant
roles/iam.serviceAccountTokenCreatoron a privileged service account within the project. - Grant
roles/compute.adminto then create VMs attached to high-privilege service accounts.
Identification
gcloud CLI
# Get IAM policy for a projectPROJECT_ID="my-project"gcloud projects get-iam-policy $PROJECT_ID --format=json | \ jq '.bindings[] | select(.role | test("owner|projectIamAdmin|iam.securityAdmin|organizationAdmin")) | {role: .role, members: .members}'# Check a specific user's roles on a projectgcloud projects get-iam-policy $PROJECT_ID \ --flatten="bindings[].members" \ --format="table(bindings.role,bindings.members)" \GCP Console
- Open GCP Console → IAM & Admin → IAM.
- Ensure the target Project is selected.
- Review principals with
Owner,Project IAM Admin, orSecurity Adminroles.
Exploitation
gcloud CLI
# Grant owner to attacker identity at project scopePROJECT_ID="target-project"gcloud projects add-iam-policy-binding $PROJECT_ID \ --role="roles/owner"
# Grant token creator on a high-privilege SA within the projectSA_EMAIL="high-priv-sa@${PROJECT_ID}.iam.gserviceaccount.com"gcloud iam service-accounts add-iam-policy-binding $SA_EMAIL \ --role="roles/iam.serviceAccountTokenCreator"Compound path: GCP_SET_PROJECT_IAMPOLICY → grant roles/iam.serviceAccountUser + roles/compute.admin → GCP_ACT_AS_SA + GCP_CREATE_COMPUTE → spin up VM attached to privileged SA → extract SA token from metadata server.
Mitigation
- Remove
roles/ownerfrom human users in production projects; use purpose-specific roles. - Restrict
roles/resourcemanager.projectIamAdminto automation accounts and break-glass identities only. - Enable
constraints/iam.managed.allowedPolicyMembersat the org level. - Audit project IAM policies:
gcloud projects get-iam-policy $PROJECT_ID --format=json | \jq '.bindings[] | select(.role | test("owner|IamAdmin|securityAdmin"))'
- Use VPC Service Controls to limit data exfiltration even after project compromise.
Detection
| Log Type | Method | Key Fields |
|---|---|---|
| Admin Activity | SetIamPolicy |
resource.type=project, methodName=SetIamPolicy |
gcloud logging read \ 'resource.type="project" AND protoPayload.methodName="SetIamPolicy"' \ --project=$PROJECT_ID \ --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.serviceData.policyDelta)"Alert on:
- New
roles/ownerbindings on projects. SetIamPolicycalls by identities not part of a known automation system.- Bindings added for external (non-org) identities.