Skip to content

GCP_IMPERSONATE_SA

Copy page

Summary

Forestall ACL Alias GCP_IMPERSONATE_SA
GCP Alias Persistence & Impersonation
Affected Object Types Service Accounts
Exploitation Certainty Certain
Granting Roles roles/iam.serviceAccountTokenCreator

Description

GCP_IMPERSONATE_SA indicates that an identity holds iam.serviceAccounts.getAccessToken on a GCP Service Account, typically via roles/iam.serviceAccountTokenCreator. This is the most direct path to full SA impersonation: the attacker can call the IAM generateAccessToken API from anywhere on the internet and receive a short-lived OAuth2 access token valid for 1 hour.

Unlike GCP_ACT_AS_SA (which requires a compute vehicle), GCP_IMPERSONATE_SA enables direct API-based token generation with no infrastructure dependency. An attacker needs only network access to the IAM API to fully impersonate the target SA.

Key abuse scenarios:

  • Generate access tokens for a high-privilege SA and call any GCP API as that SA.
  • Chain impersonation: generate a token for SA-A, then use SA-A’s token to impersonate SA-B (if SA-A has token creator on SA-B).
  • Generate ID tokens for service-to-service authentication to GCP-hosted services.

Identification

gcloud CLI

# Find who has token creator role at project level
PROJECT_ID="my-project"
gcloud projects get-iam-policy $PROJECT_ID --format=json | \
jq '.bindings[] | select(.role | test("serviceAccountTokenCreator")) | {role: .role, members: .members}'
# Check SA-level token creator grants
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)
BINDINGS=$(echo $POLICY | jq '.bindings[] | select(.role == "roles/iam.serviceAccountTokenCreator")')
if [ ! -z "$BINDINGS" ]; then
echo "=== $SA ===" && echo $BINDINGS
fi
done

Exploitation

gcloud CLI

# Generate an access token for a target SA directly (no infrastructure needed)
TARGET_SA="[email protected]"
# Using gcloud (works if current identity has token creator on target SA)
gcloud auth print-access-token --impersonate-service-account=$TARGET_SA
# Using the IAM API directly
ACCESS_TOKEN=$(gcloud auth print-access-token)
curl -X POST \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"scope": ["https://www.googleapis.com/auth/cloud-platform"], "lifetime": "3600s"}' \
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${TARGET_SA}:generateAccessToken"
# Chain impersonation through multiple SAs
gcloud auth print-access-token \
--impersonate-service-account=sa-a@project.iam.gserviceaccount.com,[email protected]

With the resulting token, all GCP API calls are made as the target SA.

Mitigation

  1. Restrict roles/iam.serviceAccountTokenCreator — this role should only be granted to specific, audited automation identities that explicitly require delegation.
  2. Avoid project-level token creator grants — scope to specific SA resources rather than all SAs in a project.
  3. Monitor for chained impersonation paths using Policy Analyzer.
  4. Use Workload Identity Federation for external workloads instead of granting token creator to service accounts.

Detection

Log Type Method Key Fields
Data Access GenerateAccessToken resource.type=service_account, methodName=GenerateAccessToken
gcloud logging read \
'protoPayload.methodName="GenerateAccessToken"' \
--project=$PROJECT_ID \
--format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.resourceName)"

Alert on:

  • GenerateAccessToken calls on privileged SAs by non-automation identities.
  • Impersonation chains — token generation where the caller is itself a service account.

References

Was this page helpful?

Thank you for your feedback.