GCP Service Accounts: Authentication, Impersonation, and Workload Identity
A production-focused guide to GCP Service Accounts: Authentication, Impersonation, and Workload Identity on Google Cloud Platform..
20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.
- ✓GCP project with billing enabled, gcloud CLI installed and configured, basic understanding of IAM roles, familiarity with Kubernetes (for Workload Identity sections), Python 3.6+ for code examples, jq for JSON parsing in bash examples
GCP Service Accounts are machine identities that let applications authenticate to Google Cloud without human credentials. Use keyless authentication (metadata server on GCP, Workload Identity on GKE) to avoid static keys. Impersonation enables temporary privilege escalation without sharing secrets.
Think of service accounts like a robot assistant with its own ID badge. You wouldn't give your personal badge to a robot—you'd make it a separate badge with exactly the permissions it needs. Service accounts are those robot badges for your apps and servers.
| Chrome | Firefox | Safari | Edge |
|---|---|---|---|
| ✓ | ✓ | ✓ | ✓ |
You deployed a microservice that pulls from Cloud Storage. It worked in dev. In prod, it silently failed for three hours—because the service account had Viewer on the bucket, not Object Viewer. That’s the kind of outage that makes you hate IAM. Service accounts are the backbone of GCP authentication, but most teams get them wrong: they over-provision roles, share keys via Slack, or ignore impersonation. This isn’t theory—it’s the difference between a secure pipeline and a breach waiting to happen. We’ll cover what service accounts are, how to authenticate without keys, when to impersonate, and how Workload Identity kills the need for static credentials on Kubernetes.
What Is a Service Account?
A service account is a Google-managed identity that belongs to your project, not a user. It has an email address (e.g., my-sa@project.iam.gserviceaccount.com) and can be assigned IAM roles. Unlike user accounts, it doesn’t have a password—it authenticates via keys (JSON or P12) or through metadata server on GCP compute. Service accounts are the recommended way to give workloads access to GCP resources. They are not for human login; they are for automated processes. Every GCP resource (Compute Engine, Cloud Run, GKE) can be attached to a service account, which then governs what that resource can do. The key principle: one service account per logical component, with the minimum roles needed.
Service Account Keys: The Old Way
Service account keys are RSA private keys that allow external applications (outside GCP) to authenticate as the service account. They come in JSON or P12 format. You download the key, store it securely, and use it to sign JWTs for OAuth2 access tokens. This is the most common—and most dangerous—pattern. Keys can leak via git commits, CI logs, or developer laptops. Once leaked, an attacker can impersonate the service account until the key is rotated. GCP recommends avoiding keys entirely. If you must use them, enforce short-lived keys, rotate frequently, and use a secrets manager like Secret Manager or HashiCorp Vault.
Metadata Server Authentication
When your workload runs on GCP compute (Compute Engine, GKE, Cloud Run, Cloud Functions), you don’t need keys. GCP provides a metadata server at 169.254.169.254 that automatically issues short-lived access tokens for the attached service account. The client libraries (gcloud, SDKs) automatically fetch tokens from this endpoint. This is the most secure way to authenticate on GCP because there are no static credentials to leak. The tokens are valid for typically 1 hour and are automatically refreshed. To use this, simply create your client without passing credentials—the library will discover the service account from the environment.
Service Account Impersonation
Impersonation allows one service account (the caller) to act as another (the target) for a limited time. This is useful for privilege escalation patterns: a CI/CD pipeline uses a low-privilege service account to deploy, but needs to temporarily act as a high-privilege account to create resources. Impersonation is done by granting the caller the roles/iam.serviceAccountTokenCreator role on the target. The caller then calls the generateAccessToken API to get a token for the target. This is more secure than sharing keys because the target’s key is never exposed, and the impersonation is audited.
storage.objectViewer on the artifact bucket. To deploy to Cloud Run, it impersonates a deployer SA that has run.admin. This limits blast radius if the CI SA is compromised.Workload Identity for GKE
Workload Identity is the recommended way for GKE workloads to access GCP services. Instead of using the node’s service account (which gives all pods on that node the same permissions), Workload Identity maps a Kubernetes service account (KSA) to a GCP service account (GSA). Pods running as that KSA automatically get tokens for the GSA via the metadata server. This eliminates the need to store GCP keys in Kubernetes secrets. Setup involves enabling Workload Identity on the cluster, creating a GSA, granting it the roles/iam.workloadIdentityUser role on the GSA, and annotating the KSA with the GSA email.
workloadIdentityUser role on the GSA. The pod will fail to authenticate with a 403 error. Always verify with gcloud iam service-accounts get-iam-policy.Workload Identity for Other Platforms
Workload Identity isn’t limited to GKE. GCP offers Workload Identity Federation for AWS, Azure, and on-premises workloads. This allows workloads running outside GCP to exchange tokens from their identity provider (e.g., AWS IAM roles, Azure managed identities) for GCP access tokens—without any service account keys. You create a workload identity pool and provider, then grant the pool access to a GSA. The external workload presents its native credential, and GCP validates it against the provider. This is the future of multi-cloud authentication.
Best Practices for Service Account Management
Managing service accounts at scale requires discipline. First, use descriptive names that indicate purpose (e.g., web-app-sa, data-pipeline-sa). Second, apply the principle of least privilege: start with no roles and add only what’s needed. Third, use custom roles instead of primitive roles (owner, editor, viewer). Fourth, rotate keys regularly—GCP can enforce key rotation policies. Fifth, monitor service account usage with Cloud Audit Logs and set up alerts for unusual activity. Sixth, disable unused service accounts. Finally, never use the default service account—it has the editor role by default, which is too permissive.
Troubleshooting Authentication Failures
Authentication failures with service accounts often manifest as 403 or 401 errors. Common causes: the service account doesn’t have the required role on the resource, the token is expired, or the metadata server is unreachable. For metadata server issues, check that the instance has the correct scopes and that the metadata server IP (169.254.169.254) is not blocked. For Workload Identity, verify the KSA annotation and the IAM binding. Use gcloud auth print-access-token to test token generation. Enable Cloud Audit Logs to see denied requests. For impersonation, ensure the caller has the iam.serviceAccountTokenCreator role on the target.
Service Account Key Rotation and Lifecycle
Service account keys should have a limited lifetime. GCP allows you to set a key expiration policy at the project level. You can also create keys with an expiration time. For automated rotation, use a script that creates a new key, deploys it, and deletes the old one. Integrate with Secret Manager to store keys securely. GCP’s IAM Recommender can suggest when keys are old or unused. Disable keys that are not in use. Remember: deleting a key is irreversible—if the key is still in use, you’ll break things. Always verify that the new key works before deleting the old one.
Service Account vs User Account: When to Use What
Service accounts are for automated processes; user accounts are for humans. Never use a user account for a production workload. User accounts have MFA, session limits, and are tied to a person. Service accounts have no MFA, can have unlimited keys, and are not tied to a person. If a person leaves, their user account is disabled—but if that account was used in a script, the script breaks. Service accounts survive personnel changes. Also, service accounts can be granted roles across projects, while user accounts are typically limited to a single project. For cross-project access, use service accounts.
Auditing and Monitoring Service Account Activity
Cloud Audit Logs record all service account activity: key creation, token generation, impersonation, and API calls. Enable Data Access audit logs for the services your SAs access. Use Logs Explorer to search for specific SAs. Set up alerts for suspicious patterns, like a SA creating keys from an unexpected IP or a SA accessing resources outside business hours. Use the IAM Recommender to identify unused SAs or over-permissioned roles. The Security Command Center can flag risky SAs. Regularly review the list of SAs and their roles.
| File | Command / Code | Purpose |
|---|---|---|
| create_service_account.sh | gcloud iam service-accounts create my-sa \ | What Is a Service Account? |
| auth_with_key.py | from google.oauth2 import service_account | Service Account Keys |
| auth_metadata.py | from google.cloud import storage | Metadata Server Authentication |
| impersonate.py | from google.cloud import iam_credentials | Service Account Impersonation |
| workload_identity_setup.sh | gcloud container clusters update my-cluster \ | Workload Identity for GKE |
| aws_workload_identity.sh | gcloud iam workload-identity-pools create my-pool \ | Workload Identity for Other Platforms |
| audit_sa_usage.sh | gcloud iam service-accounts list --project=my-project | Best Practices for Service Account Management |
| debug_auth.sh | gcloud auth print-access-token --impersonate-service-account=target-sa@project.i... | Troubleshooting Authentication Failures |
| rotate_key.sh | gcloud iam service-accounts keys create new-key.json \ | Service Account Key Rotation and Lifecycle |
| cross_project_access.sh | gcloud projects add-iam-policy-binding other-project \ | Service Account vs User Account |
| monitor_sa.sh | gcloud logging read 'protoPayload.authenticationInfo.principalEmail="my-sa@my-pr... | Auditing and Monitoring Service Account Activity |
Key takeaways
Common mistakes to avoid
3 patternsIgnoring gcp service accounts best practices
Over-provisioning without rightsizing analysis
Skipping IAM least-privilege principles
Interview Questions on This Topic
What is a GCP service account and how is it different from a user account?
Frequently Asked Questions
20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.
That's Google Cloud. Mark it forged?
4 min read · try the examples if you haven't