Software Engineer's Blog

Stop Using key.json: How to Configure GCP Service Account Impersonation

Stop Using key.json: How to Configure GCP Service Account Impersonation

Are you still downloading service-account-key.json files and setting them to your GOOGLE_APPLICATION_CREDENTIALS environment variable for local development?

If the answer is yes, you need to stop.

While this method was common in the past, Google Cloud Platform (GCP) now strongly discourages managing long-lived keys due to significant security risks. The modern industry standard is Service Account Impersonation.

In this post, I will explain why you should ditch the JSON keys and how to set up Impersonation step-by-step.

The Problem with Long-Lived Keys (key.json)

Using a physical key file comes with three major downsides:

  1. Security Risks (Key Leakage): It is terrifyingly easy to accidentally commit a JSON key to a public GitHub repository. Once leaked, anyone can access your cloud resources until you notice and revoke it.
  2. Management Overhead: When a developer leaves the company, you have to revoke the old keys and reissue new ones for the remaining team members.
  3. Lack of Auditability: In the logs, actions appear as if the “Service Account” performed them. You cannot easily distinguish which specific developer was using that key at the time.

Service Account Impersonation solves all of this. It allows your personal user account (which is authenticated via MFA) to temporarily “borrow” the permissions of a Service Account using short-lived tokens.

Step-by-Step Implementation Guide

The setup process involves two parts: one for the Admin (granting permission) and one for the Developer (configuring the local environment).

Step 1. Admin Configuration (Granting Permission)

Performed by: DevOps / Infrastructure Lead / Project Owner

First, the administrator must allow the developer’s personal Google account to impersonate the target service account.

gcloud iam service-accounts add-iam-policy-binding \
  TARGET_SA_EMAIL@PROJECT_ID.iam.gserviceaccount.com \
  --member=user:DEVELOPER_EMAIL@example.com \
  --role=roles/iam.serviceAccountTokenCreator

Key Explanation:

  • add-iam-policy-binding: Adds a policy to the specific resource (the Service Account).
  • --role=roles/iam.serviceAccountTokenCreator: This is the critical part. This role grants the developer the ability to generate access tokens on behalf of the service account.

Step 2. Developer Configuration (Local Setup)

Performed by: The Developer

Once permission is granted, you don’t need to download any files. You simply authenticate via the gcloud CLI with a special flag.

gcloud auth application-default login \
  --impersonate-service-account=TARGET_SA_EMAIL@PROJECT_ID.iam.gserviceaccount.com

Key Explanation:

  • auth application-default login: This generates ADC (Application Default Credentials). Your code (using Google Client Libraries) automatically looks for these credentials.
  • --impersonate-service-account: Instead of authenticating as “User A,” this tells GCP: “I am User A, but I have permission to act as Service Account B.”

Step 3. Verification

To ensure everything is working correctly, try to print an access token:

gcloud auth application-default print-access-token

If the command outputs a long string (the OAuth2 token) without errors, your impersonation setup is complete! Your local code will now run with the exact permissions of the Service Account.

Note: gcloud auth login does not provide credentials for Google Client Libraries. For local application development, you must use application-default login.

Why Is This the Industry Standard?

1. Keyless Security

There are no physical files to manage or lose. No more key.json files cluttering your project root or risking Git leaks.

2. Easy Revocation

If a developer leaves the team, the admin simply removes the IAM binding (roles/iam.serviceAccountTokenCreator). Access is revoked instantly. You don’t need to rotate keys for everyone else.

3. No Code Changes Required

This is the best part. You don’t need to change your application code.

As long as your code uses the standard pattern:

// Java Example
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();

It will automatically pick up the impersonated credentials locally, and use the instance credentials when deployed to the cloud.

Conclusion

It’s time to retire the key.json file. By switching to Service Account Impersonation, you secure your infrastructure, simplify onboarding/offboarding, and adhere to Google Cloud’s best practices.