Home DevOps GCP Service Accounts: Authentication, Impersonation, and Workload Identity
Beginner 4 min · July 12, 2026

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..

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.

Follow
Verified
production tested
July 12, 2026
last updated
2,073
articles · all by Naren
Before you start⏱ 25 min
  • 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
Quick Answer

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.

✦ Definition~90s read
What is Service Accounts?

GCP Service Accounts are IAM identities for non-human actors—applications, VMs, or services—that authenticate and authorize API calls. They matter because they eliminate static credentials, enforce least-privilege access, and enable secure cross-service communication. Use them whenever a workload needs to interact with GCP resources without a human user.

Think of service accounts like a robot assistant with its own ID badge.
Plain-English First

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.

⚙ Browser compatibility
Latest versions — ✓ supported
ChromeFirefoxSafariEdge

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.

create_service_account.shBASH
1
2
3
4
5
6
gcloud iam service-accounts create my-sa \
    --display-name="My Service Account"

gcloud projects add-iam-policy-binding my-project \
    --member="serviceAccount:my-sa@my-project.iam.gserviceaccount.com" \
    --role="roles/storage.objectViewer"
Output
Created service account [my-sa].
Updated IAM policy for project [my-project].
🔥Service Account vs User Account
Service accounts are not users. They cannot sign in to the console. They are identified by their email, but that email is not a real Gmail address.
📊 Production Insight
In production, never use the default Compute Engine service account. It has overly broad permissions (editor role). Create a custom one with only the roles your workload needs.
🎯 Key Takeaway
Service accounts are machine identities—treat them like you treat API keys: rotate, restrict, and audit.
gcp-service-accounts THECODEFORGE.IO Service Account Authentication Flow Step-by-step process from key creation to token use Create Service Account Define in GCP IAM with unique ID Generate Key (JSON) Download private key for offline use Sign JWT Assertion Use private key to create signed token Request Access Token Exchange JWT for OAuth2 token via token endpoint Authenticate API Call Attach token in Authorization header ⚠ Key leakage risk: exposed keys can lead to account takeover Use workload identity federation instead of long-lived keys THECODEFORGE.IO
thecodeforge.io
Gcp Service Accounts

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.

auth_with_key.pyPYTHON
1
2
3
4
5
6
7
8
9
10
from google.oauth2 import service_account
from google.cloud import storage

credentials = service_account.Credentials.from_service_account_file(
    'path/to/key.json',
    scopes=['https://www.googleapis.com/auth/cloud-platform']
)
client = storage.Client(credentials=credentials, project='my-project')
buckets = list(client.list_buckets())
print(buckets)
Output
[<Bucket: my-bucket>, <Bucket: another-bucket>]
⚠ Never Commit Keys
Add key files to .gitignore immediately. Use tools like git-secrets or pre-commit hooks to prevent accidental commits.
📊 Production Insight
A common production failure: a developer commits a key to a public repo. Within hours, cryptominers use it to spin up expensive GPU instances. Always use a secrets manager and rotate keys on a schedule.
🎯 Key Takeaway
Service account keys are a necessary evil for external workloads, but they are a security risk. Minimize their use.

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.

auth_metadata.pyPYTHON
1
2
3
4
5
6
from google.cloud import storage

# No credentials needed—automatically uses metadata server
client = storage.Client()
buckets = list(client.list_buckets())
print(buckets)
Output
[<Bucket: my-bucket>]
💡Default Credentials
The Application Default Credentials (ADC) strategy first checks the environment variable GOOGLE_APPLICATION_CREDENTIALS, then the metadata server. For local development, set this env var to a key file; in production, rely on metadata.
📊 Production Insight
If your GCE instance can’t reach the metadata server (e.g., misconfigured firewall or custom network), authentication fails silently. Always test with a simple gcloud auth list from the instance.
🎯 Key Takeaway
On GCP, never use keys—let the metadata server handle authentication.
gcp-service-accounts THECODEFORGE.IO GCP Service Account Architecture Layered view of components and their interactions Identity Layer Service Account | IAM Policies | Custom Roles Authentication Layer Private Keys | Metadata Server | Workload Identity Authorization Layer OAuth2 Tokens | Access Scopes | Token Exchange Compute Layer GCE Instances | GKE Pods | Cloud Functions Resource Layer Cloud Storage | BigQuery | Pub/Sub THECODEFORGE.IO
thecodeforge.io
Gcp Service Accounts

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.

impersonate.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from google.cloud import iam_credentials
from google.oauth2 import service_account

# Caller credentials (low-privilege SA)
caller_creds = service_account.Credentials.from_service_account_file(
    'caller-key.json',
    scopes=['https://www.googleapis.com/auth/cloud-platform']
)

client = iam_credentials.IAMCredentialsClient(credentials=caller_creds)

# Request a token for the target SA
target_sa = 'target-sa@project.iam.gserviceaccount.com'
response = client.generate_access_token(
    name=f'projects/-/serviceAccounts/{target_sa}',
    scope=['https://www.googleapis.com/auth/cloud-platform'],
    lifetime=timedelta(seconds=3600)
)
print(response.access_token)
Output
ya29.c.c0... (access token)
⚠ Impersonation Is Not Free
Impersonation generates audit logs. Overuse can lead to rate limiting. Also, the caller must have the token creator role, which is a powerful permission—grant sparingly.
📊 Production Insight
A common pattern: a CI/CD pipeline uses a deploy SA with only 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.
🎯 Key Takeaway
Impersonation enables least-privilege by allowing temporary elevation without sharing keys.

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.

workload_identity_setup.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Enable Workload Identity on the cluster
gcloud container clusters update my-cluster \
    --workload-pool=my-project.svc.id.goog

# Create GSA
gcloud iam service-accounts create gke-sa

# Grant the KSA permission to impersonate the GSA
gcloud iam service-accounts add-iam-policy-binding gke-sa@my-project.iam.gserviceaccount.com \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:my-project.svc.id.goog[default/my-ksa]"

# Annotate the KSA
kubectl annotate serviceaccount my-ksa \
    iam.gke.io/gcp-service-account=gke-sa@my-project.iam.gserviceaccount.com
Output
Updated IAM policy for serviceAccount [gke-sa@my-project.iam.gserviceaccount.com].
serviceaccount/my-ksa annotated
🔥Workload Identity vs Node SA
Without Workload Identity, all pods on a node share the node’s service account. With Workload Identity, each pod can have its own identity, enabling fine-grained access control.
📊 Production Insight
A common mistake: forgetting to grant the 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.
🎯 Key Takeaway
Workload Identity is the gold standard for GKE authentication—no keys, no secrets, just IAM.

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.

aws_workload_identity.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Create workload identity pool
gcloud iam workload-identity-pools create my-pool \
    --location="global" \
    --display-name="My Pool"

# Create AWS provider
gcloud iam workload-identity-pools providers create-aws my-aws-provider \
    --location="global" \
    --workload-identity-pool="my-pool" \
    --account-id="123456789012"

# Grant pool access to GSA
gcloud iam service-accounts add-iam-policy-binding gsa@project.iam.gserviceaccount.com \
    --role roles/iam.workloadIdentityUser \
    --member "principalSet://iam.googleapis.com/projects/123/locations/global/workloadIdentityPools/my-pool/attribute.aws_role/arn:aws:sts::123456789012:assumed-role/my-role"
Output
Created workload identity pool [my-pool].
Created provider [my-aws-provider].
Updated IAM policy.
💡No Keys, No Secrets
Workload Identity Federation completely eliminates the need for service account keys in external workloads. This is a massive security improvement.
📊 Production Insight
When setting up federation, ensure the external identity’s token contains the expected attributes (e.g., AWS role ARN). Misconfigured attribute mappings are a common cause of authentication failures.
🎯 Key Takeaway
Workload Identity Federation extends keyless authentication to any cloud or on-premises workload.

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.

audit_sa_usage.shBASH
1
2
3
4
5
6
7
8
# List all service accounts in project
gcloud iam service-accounts list --project=my-project

# Get IAM policy for a specific SA
gcloud iam service-accounts get-iam-policy my-sa@my-project.iam.gserviceaccount.com

# View audit logs for SA key creation
gcloud logging read 'protoPayload.methodName="google.iam.admin.v1.CreateServiceAccountKey"' --limit=10
Output
---
account: my-sa@my-project.iam.gserviceaccount.com
displayName: My Service Account
...
bindings:
- members:
- user:admin@example.com
role: roles/iam.serviceAccountAdmin
...
⚠ Default SA Danger
The default Compute Engine service account has the editor role on the project. This means any VM using it can read/write almost everything. Always create a custom SA with minimal roles.
📊 Production Insight
A real incident: a team used the default SA on a GKE cluster. A compromised container was able to list all secrets in the project because the default SA had editor role. Always use custom SAs with Workload Identity.
🎯 Key Takeaway
Treat service accounts as sensitive resources—audit, rotate, and restrict them.

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.

debug_auth.shBASH
1
2
3
4
5
6
7
8
9
10
# Test metadata server token
gcloud auth print-access-token --impersonate-service-account=target-sa@project.iam.gserviceaccount.com

# Check if SA has a role on a bucket
gcloud storage buckets get-iam-policy gs://my-bucket \
    | grep my-sa@project.iam.gserviceaccount.com

# Verify Workload Identity binding
gcloud iam service-accounts get-iam-policy gsa@project.iam.gserviceaccount.com \
    --format='json' | jq '.bindings[] | select(.role=="roles/iam.workloadIdentityUser")'
Output
ya29...
- members:
- serviceAccount:my-sa@project.iam.gserviceaccount.com
role: roles/storage.objectViewer
{
"role": "roles/iam.workloadIdentityUser",
"members": [
"serviceAccount:project.svc.id.goog[default/my-ksa]"
]
}
🔥403 vs 401
A 401 means the token is invalid or missing. A 403 means the token is valid but lacks permissions. Check roles first.
📊 Production Insight
A common debugging pitfall: testing with a user account that has Owner role, then wondering why the service account fails. Always test with the exact service account identity.
🎯 Key Takeaway
Most auth failures are permission issues—verify IAM bindings before blaming the token.

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.

rotate_key.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
# Create a new key with expiration
gcloud iam service-accounts keys create new-key.json \
    --iam-account=my-sa@my-project.iam.gserviceaccount.com \
    --key-expiration=2026-01-01T00:00:00Z

# Upload to Secret Manager
gcloud secrets versions add my-sa-key --data-file=new-key.json

# Update application to use new key (e.g., update env var)
# After confirming, delete old key
gcloud iam service-accounts keys delete OLD_KEY_ID \
    --iam-account=my-sa@my-project.iam.gserviceaccount.com
Output
Created key [new-key.json] for service account [my-sa@my-project.iam.gserviceaccount.com].
Deleted key [OLD_KEY_ID].
💡Automate Rotation
Use Cloud Scheduler + Cloud Functions to rotate keys automatically. Set up monitoring to alert if a key is older than 90 days.
📊 Production Insight
A company suffered a breach because a service account key in a CI/CD pipeline was never rotated. The key was valid for 3 years. Enforce a maximum key age of 1 year, or better, eliminate keys entirely.
🎯 Key Takeaway
Key rotation is not optional—treat it as a critical security control.

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.

cross_project_access.shBASH
1
2
3
4
# Grant SA access to a resource in another project
gcloud projects add-iam-policy-binding other-project \
    --member="serviceAccount:my-sa@my-project.iam.gserviceaccount.com" \
    --role="roles/storage.objectViewer"
Output
Updated IAM policy for project [other-project].
🔥User Account in Production?
If you find a user account being used in a production script, treat it as a security incident. Replace it with a service account immediately.
📊 Production Insight
A startup used a developer’s personal Gmail account as the service account for their production app. When the developer left, the account was deleted, and the app went down. Always use service accounts.
🎯 Key Takeaway
Service accounts are for machines; user accounts are for people. Never mix the two.
Service Account Keys vs Workload Identity Trade-offs between traditional and modern authentication Service Account Keys Workload Identity Credential Management Manual key creation and rotation Automatic token generation via metadata Security Risk High: keys can be leaked or stolen Low: no long-lived secrets stored Setup Complexity Simple: download and use JSON key Moderate: requires IAM binding and pool Use Case Offline or non-GCP workloads GCP-native workloads (GCE, GKE, Cloud Ru Scalability Poor: key rotation overhead per service Excellent: automatic token refresh per w THECODEFORGE.IO
thecodeforge.io
Gcp 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.

monitor_sa.shBASH
1
2
3
4
5
6
7
8
# Query audit logs for a specific SA
gcloud logging read 'protoPayload.authenticationInfo.principalEmail="my-sa@my-project.iam.gserviceaccount.com"' \
    --limit=10 --format=json

# Create a log-based metric for key creation
gcloud logging metrics create sa-key-created \
    --description="Service account key created" \
    --log-filter='protoPayload.methodName="google.iam.admin.v1.CreateServiceAccountKey"'
Output
[{...}] # log entries
Created metric [sa-key-created].
⚠ Audit Logs Cost
Data Access audit logs incur costs. Enable only for the services you need. Admin logs are free and cover IAM changes.
📊 Production Insight
A company detected a breach because a SA that normally only accessed Cloud Storage suddenly started calling Compute Engine APIs. The audit log showed the anomaly, and they revoked the SA’s keys within minutes.
🎯 Key Takeaway
You can’t secure what you don’t monitor—audit logs are your best friend for service account security.
⚙ Quick Reference
11 commands from this guide
FileCommand / CodePurpose
create_service_account.shgcloud iam service-accounts create my-sa \What Is a Service Account?
auth_with_key.pyfrom google.oauth2 import service_accountService Account Keys
auth_metadata.pyfrom google.cloud import storageMetadata Server Authentication
impersonate.pyfrom google.cloud import iam_credentialsService Account Impersonation
workload_identity_setup.shgcloud container clusters update my-cluster \Workload Identity for GKE
aws_workload_identity.shgcloud iam workload-identity-pools create my-pool \Workload Identity for Other Platforms
audit_sa_usage.shgcloud iam service-accounts list --project=my-projectBest Practices for Service Account Management
debug_auth.shgcloud auth print-access-token --impersonate-service-account=target-sa@project.i...Troubleshooting Authentication Failures
rotate_key.shgcloud iam service-accounts keys create new-key.json \Service Account Key Rotation and Lifecycle
cross_project_access.shgcloud projects add-iam-policy-binding other-project \Service Account vs User Account
monitor_sa.shgcloud logging read 'protoPayload.authenticationInfo.principalEmail="my-sa@my-pr...Auditing and Monitoring Service Account Activity

Key takeaways

1
Service accounts are machine identities
Use them for all automated workloads, never user accounts.
2
Prefer keyless authentication
On GCP, use metadata server; on GKE, use Workload Identity; off-GCP, use Workload Identity Federation.
3
Impersonation enables least privilege
Allow temporary privilege escalation without sharing keys, and audit all impersonation events.
4
Audit and rotate
Monitor service account activity with Cloud Audit Logs, rotate keys regularly, and disable unused accounts.

Common mistakes to avoid

3 patterns
×

Ignoring gcp service accounts best practices

Symptom
Production incidents and unexpected behavior
Fix
Follow GCP documentation and implement proper monitoring and testing
×

Over-provisioning without rightsizing analysis

Symptom
Wasted cloud spend and poor resource utilization
Fix
Use committed use discounts and rightsize based on actual usage metrics
×

Skipping IAM least-privilege principles

Symptom
Security vulnerabilities and compliance violations
Fix
Implement custom roles with minimum required permissions and use conditions
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What is a GCP service account and how is it different from a user accoun...
Q02SENIOR
How does Workload Identity on GKE eliminate the need for static service ...
Q03SENIOR
What is service account impersonation and when should you use it?
Q04SENIOR
How would you design a key rotation strategy for service account keys wi...
Q05SENIOR
What audit trails should you set up for service account monitoring?
Q01 of 05JUNIOR

What is a GCP service account and how is it different from a user account?

ANSWER
A service account is a Google-managed machine identity used by applications and VMs, not humans. Unlike user accounts, service accounts don't have passwords, can't sign in to the console, and are identified by an email address (e.g., my-sa@project.iam.gserviceaccount.com). They authenticate via keys or metadata server and survive personnel changes.
FAQ · 6 QUESTIONS

Frequently Asked Questions

01
Can I use a service account to log in to the GCP Console?
02
What's the difference between a service account key and an access token?
03
How do I grant a service account access to a resource in another project?
04
What is Workload Identity Federation and when should I use it?
05
How do I rotate a service account key without downtime?
06
Why does my pod on GKE get a 403 error when accessing Cloud Storage?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.

Follow
Verified
production tested
July 12, 2026
last updated
2,073
articles · all by Naren
🔥

That's Google Cloud. Mark it forged?

4 min read · try the examples if you haven't

Previous
Identity & Access Management (IAM)
6 / 55 · Google Cloud
Next
Quotas & Limits