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 levelPROJECT_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 grantsfor 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 fidoneGCP Console
- Open GCP Console → IAM & Admin → IAM.
- Check for principals with
Service Account Token Creatorrole. - Go to IAM & Admin → Service Accounts.
- Select a service account → Permissions tab.
- Check for principals with
Service Account Token Creatorrole.
Exploitation
gcloud CLI
# Generate an access token for a target SA directly (no infrastructure needed)
# 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 directlyACCESS_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 SAsgcloud 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
- Restrict
roles/iam.serviceAccountTokenCreator— this role should only be granted to specific, audited automation identities that explicitly require delegation. - Avoid project-level token creator grants — scope to specific SA resources rather than all SAs in a project.
- Monitor for chained impersonation paths using Policy Analyzer.
- 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:
GenerateAccessTokencalls on privileged SAs by non-automation identities.- Impersonation chains — token generation where the caller is itself a service account.