Skip to content

GCP_SET_PROJECT_IAMPOLICY

Copy page

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/owner to a controlled identity at project scope.
  • Grant roles/iam.serviceAccountTokenCreator on a privileged service account within the project.
  • Grant roles/compute.admin to then create VMs attached to high-privilege service accounts.

Identification

gcloud CLI

# Get IAM policy for a project
PROJECT_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 project
gcloud projects get-iam-policy $PROJECT_ID \
--flatten="bindings[].members" \
--format="table(bindings.role,bindings.members)" \
--filter="bindings.members:user:[email protected]"

Exploitation

gcloud CLI

# Grant owner to attacker identity at project scope
PROJECT_ID="target-project"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="user:[email protected]" \
--role="roles/owner"
# Grant token creator on a high-privilege SA within the project
SA_EMAIL="high-priv-sa@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud iam service-accounts add-iam-policy-binding $SA_EMAIL \
--member="user:[email protected]" \
--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

  1. Remove roles/owner from human users in production projects; use purpose-specific roles.
  2. Restrict roles/resourcemanager.projectIamAdmin to automation accounts and break-glass identities only.
  3. Enable constraints/iam.managed.allowedPolicyMembers at the org level.
  4. Audit project IAM policies:
    gcloud projects get-iam-policy $PROJECT_ID --format=json | \
    jq '.bindings[] | select(.role | test("owner|IamAdmin|securityAdmin"))'
  5. 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/owner bindings on projects.
  • SetIamPolicy calls by identities not part of a known automation system.
  • Bindings added for external (non-org) identities.

References

Was this page helpful?

Thank you for your feedback.