GCP_HAS_SERVICE_ACCOUNT_KEY

Summary

FSProtect 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

GCP Console

  1. Open GCP ConsoleIAM & AdminService Accounts.

  2. Click a service account → Keys tab.

  3. Any key listed under User-managed keys represents a GCP_HAS_SERVICE_ACCOUNT_KEY edge.

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

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

Alert on:

  • Creation of SA keys on privileged service accounts.

  • SA keys created outside of known CI/CD systems or automation accounts.

References

  • https://cloud.google.com/iam/docs/service-account-creds

  • https://cloud.google.com/iam/docs/best-practices-service-accounts#avoid-key-risks

  • https://cloud.google.com/iam/docs/keys-create-delete

Last updated

Was this helpful?