Service Account Impersonation vs Service Account Keys: Security Comparison for Google Cloud
Service Account impersonation generates short-lived OAuth 2.0 tokens on-demand without storing private keys, while Service Account keys distribute long-lived JSON credential files that create persistent security risks.
This guide examines the security differences between Service Account impersonation and Service Account keys based on the implementation patterns documented in the google/skills repository. Both approaches allow workloads to authenticate as service accounts, but they differ fundamentally in credential lifecycle, storage requirements, and audit capabilities.
Understanding the Credential Mechanisms
Before comparing security implications, you must understand how each method establishes identity.
Service Account Impersonation
Impersonation relies on the IAM Credentials API to generate short-lived access tokens. A principal with appropriate permissions calls projects.serviceAccounts.generateAccessToken or generateIdToken to obtain credentials valid for a limited duration—typically one hour. The workload never possesses long-term private key material. Instead, it relies on the source principal's identity (such as a Compute Engine service account, Workload Identity, or user credentials) to request temporary delegated access.
Service Account Keys
Service Account keys are long-lived JSON or PEM files containing static asymmetric key pairs. Administrators create these via gcloud iam service-accounts keys create or the Google Cloud Console, then distribute the files to workloads. The private key contained in these files remains valid indefinitely until explicitly deleted from the service account, and any copy of the file grants full service account privileges without additional authentication.
Security Analysis: Core Differences
The skills/cloud/google-cloud-recipe-auth/SKILL.md file documents several critical security differentiators between these approaches.
Credential Lifecycle and Storage
Impersonation eliminates persistent secrets from the workload environment. Because tokens are generated dynamically with a default lifetime of 3600 seconds, no private key material exists on disk or in environment variables. This removes the attack surface for credential exfiltration via compromised container images, source control leaks, or disk snapshots.
Service Account keys require secret management. The JSON key file must be stored somewhere accessible to the application—whether on local disk, environment variables, or external secret managers. According to the security guidelines in the repository, mishandling these files leads to credential compromise, as the key can be copied and reused indefinitely from any location.
Access Control and Least Privilege
Impersonation enforces fine-grained delegation through the roles/iam.serviceAccountTokenCreator role. Administrators can grant this permission to specific principals (such as a single CI/CD service account) while denying it to others. Revocation is immediate: removing this role from a principal instantly prevents further token generation, effectively cutting off access without waiting for token expiration.
Service Account keys provide no built-in usage restrictions. Anyone possessing the JSON file can authenticate as the service account from any network location. Deleting the key from the service account prevents future downloads but does not invalidate existing copies already distributed to workloads.
Auditability and Monitoring
Every impersonation request generates entries in Cloud Audit Logs, capturing the caller's identity, timestamp, and requested scopes. This creates a clear audit trail showing exactly who obtained credentials and when, as documented in the impersonation guidance within google-cloud-recipe-auth/SKILL.md.
Key usage appears only in service account activity logs, which do not reveal the originating source. Administrators can see that the service account performed an action, but cannot distinguish whether it was the intended workload, a compromised developer machine, or an attacker using a leaked key file.
Implementation Examples
The google/skills repository provides concrete implementation patterns for both approaches.
CLI Impersonation with gcloud
The skills/cloud/gcloud/SKILL.md file demonstrates session-based impersonation:
# Set the impersonation target for the current session
gcloud config set auth/impersonate_service_account my-impersonated-sa@my-project.iam.gserviceaccount.com
# Now any gcloud command runs as the impersonated service account
gcloud storage ls gs://my-bucket
This configuration directs the gcloud CLI to automatically request short-lived tokens for the target service account using the current user's credentials or the underlying service account identity.
Python Implementation
For applications using the Google Auth library, google-cloud-recipe-auth/SKILL.md provides this pattern:
from google.auth import impersonated_credentials
from google.auth import default
# Base credentials – e.g., user credentials or another service account
source_creds, _ = default()
# Create impersonated credentials
impersonated_creds = impersonated_credentials.Credentials(
source_credentials=source_creds,
target_principal="my-impersonated-sa@my-project.iam.gserviceaccount.com",
target_scopes=["https://www.googleapis.com/auth/cloud-platform"],
lifetime=3600,
)
# Use the impersonated credentials with any client library
from google.cloud import storage
client = storage.Client(credentials=impersonated_creds)
for bucket in client.list_buckets():
print(bucket.name)
This approach delegates the token refresh logic to the auth library, ensuring tokens remain fresh without manual intervention while never exposing private keys in the application environment.
Terraform Configuration
Infrastructure-as-code deployments can use impersonation through the Google provider:
provider "google" {
impersonate_service_account = "my-impersonated-sa@my-project.iam.gserviceaccount.com"
# Optionally set scopes
impersonate_service_account_scopes = ["cloud-platform"]
}
As noted in google-cloud-recipe-auth/SKILL.md, this prevents long-lived credentials from residing in state files or CI pipeline configurations.
Legacy Key Usage (Less Secure)
The skills/cloud/google-cloud-storage-basics/references/client-library-usage.md file shows the key-based approach for comparison:
from google.cloud import storage
# Path to the JSON key file
client = storage.Client.from_service_account_json("path/to/key.json")
for bucket in client.list_buckets():
print(bucket.name)
While functional, this pattern requires storing sensitive JSON files and lacks the auditability and revocation capabilities of impersonation.
When to Use Each Approach
The repository documentation recommends specific use cases for each method.
Prefer Service Account impersonation for:
- CI/CD pipelines running under Build service accounts
- Kubernetes pods using Workload Identity (documented in
skills/cloud/gke-workload-security/SKILL.md) - Human developers requiring temporary elevated permissions
- Any workload running within Google Cloud infrastructure
Restrict Service Account keys to:
- Legacy workloads that cannot use Workload Identity or the IAM Credentials API
- External client tools running outside Google Cloud infrastructure
- Third-party integrations requiring static credentials
Summary
- Service Account impersonation generates short-lived OAuth 2.0 tokens via the IAM Credentials API, eliminating persistent secrets while providing granular audit logs and immediate revocation capabilities.
- Service Account keys distribute long-lived JSON credential files that remain valid until manually deleted, creating risks of unauthorized copying and limiting audit visibility to service account actions without caller attribution.
- The
google/skillsrepository recommends impersonation as the default pattern, particularly when using Workload Identity for GKE or short-lived CI/CD credentials. - Reference implementations in
skills/cloud/google-cloud-recipe-auth/SKILL.mdandskills/cloud/gcloud/SKILL.mddemonstrate practical migration paths from keys to impersonation across CLI, Python, and Terraform workflows.
Frequently Asked Questions
What happens if someone steals a Service Account key file?
Any party possessing the JSON key file can authenticate as the service account indefinitely, from any location, until you manually delete the key from the service account in the IAM console. This differs fundamentally from impersonation tokens, which are bound to the source principal's permissions and expire automatically.
How do I revoke impersonation access immediately?
Remove the roles/iam.serviceAccountTokenCreator role from the source principal (user or service account). This instantly prevents the principal from generating new tokens, though existing valid tokens will expire naturally according to their lifetime (default 1 hour). For immediate termination of active sessions, you must also disable or delete the source principal's own credentials.
Can I use impersonation outside of Google Cloud?
Impersonation requires access to the IAM Credentials API, which typically necessitates running within Google Cloud or using user credentials with appropriate permissions. For workloads running entirely outside Google Cloud infrastructure without user interaction, you may need to use Service Account keys, though the repository recommends minimizing this practice and securing keys in Secret Manager with regular rotation.
Does impersonation work with Kubernetes Workload Identity?
Yes. According to skills/cloud/gke-workload-security/SKILL.md, Workload Identity is essentially an implementation of service account impersonation where Kubernetes service accounts act as the source principal to obtain Google Cloud access tokens. This allows pods to authenticate without storing any JSON key files in the cluster, achieving the same security benefits of short-lived, non-persisted credentials.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →