Skip to content

GCP_SET_SA_IAMPOLICY

Copy page

Summary

Forestall ACL Alias GCP_SET_SA_IAMPOLICY
GCP Alias IAM & Hierarchy Control
Affected Object Types Service Accounts
Exploitation Certainty Certain
Granting Roles roles/owner, roles/iam.securityAdmin, roles/iam.serviceAccountAdmin

Description

GCP_SET_SA_IAMPOLICY indicates that an identity can call setIamPolicy on a specific GCP Service Account resource. Unlike setting IAM policy at the project or org level, this edge targets a single service account’s allow policy — but the impact is equally severe when the target SA holds elevated privileges.

The primary exploitation path is granting roles/iam.serviceAccountTokenCreator on the target SA to a controlled identity. This allows the attacker to generate short-lived OAuth2 access tokens and ID tokens for the target SA from anywhere, without needing to be running on GCP infrastructure.

Key abuse scenarios:

  • Grant roles/iam.serviceAccountTokenCreator on a high-privilege SA → directly generate tokens (GCP_IMPERSONATE_SA).
  • Grant roles/iam.serviceAccountUser → attach the SA to a VM you spin up (GCP_ACT_AS_SA).
  • Add a backdoor identity as a Service Account Admin for persistence.

Identification

gcloud CLI

# List IAM policy on a specific service account
PROJECT_ID="my-project"
SA_EMAIL="high-priv@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud iam service-accounts get-iam-policy $SA_EMAIL --format=json | \
jq '.bindings[] | {role: .role, members: .members}'
# Find all service accounts in a project and their IAM policies
for SA in $(gcloud iam service-accounts list --project=$PROJECT_ID --format="value(email)"); do
echo "=== $SA ==="
gcloud iam service-accounts get-iam-policy $SA --format=json 2>/dev/null | \
jq '.bindings[]? | {role: .role, members: .members}'
done

Exploitation

gcloud CLI

# Grant token creator on a privileged SA to escalate
gcloud iam service-accounts add-iam-policy-binding $SA_EMAIL \
--member="user:[email protected]" \
--role="roles/iam.serviceAccountTokenCreator"
# Now generate a token for the high-privilege SA
gcloud auth print-access-token --impersonate-service-account=$SA_EMAIL

Compound path: GCP_SET_SA_IAMPOLICY → grant roles/iam.serviceAccountTokenCreator → GCP_IMPERSONATE_SA → call any GCP API as the target SA.

Mitigation

  1. Restrict roles/iam.serviceAccountAdmin — this role includes setIamPolicy on service accounts; assign only to privileged automation.
  2. Audit SA-level IAM policies for unexpected members:
    for SA in $(gcloud iam service-accounts list --project=$PROJECT_ID --format="value(email)"); do
    POLICY=$(gcloud iam service-accounts get-iam-policy $SA --format=json 2>/dev/null)
    echo "$POLICY" | jq --arg sa "$SA" '. + {sa: $sa} | select(.bindings | length > 0)'
    done
  3. Use Workload Identity Federation instead of SA keys to reduce the need for broad SA IAM grants.
  4. Limit service account creation with constraints/iam.disableServiceAccountCreation where applicable.

Detection

Log Type Method Key Fields
Admin Activity SetIamPolicy resource.type=service_account, methodName=google.iam.admin.v1.SetIamPolicy
gcloud logging read \
'resource.type="service_account" AND protoPayload.methodName="google.iam.admin.v1.SetIamPolicy"' \
--project=$PROJECT_ID \
--format="table(timestamp, protoPayload.authenticationInfo.principalEmail, resource.labels.email_id)"

Alert on:

  • SetIamPolicy on service accounts by non-automation identities.
  • New roles/iam.serviceAccountTokenCreator or roles/iam.serviceAccountUser bindings on privileged SAs.

References

Was this page helpful?

Thank you for your feedback.