gcloud config configurations works fine if you’re switching between regions or clusters in the same project. It breaks down the moment you’re working across different projects, identities, or service accounts — because application_default_credentials.json is global, not per-configuration.

The actual problem

Two separate things need authenticating: gcloud CLI commands (via gcloud auth login) and third-party tools like Terraform (via gcloud auth application-default login). The second command writes credentials to ~/.config/gcloud/application_default_credentials.json, and that file is shared across all named configurations.

Switching configurations updates your gcloud context, but your ADC still points to whatever project you last ran auth application-default login against. In practice this means Terraform API calls, quota attribution, and impersonation all silently use the wrong identity until you re-authenticate. When you’re jumping between a work project and a personal one, this gets tedious fast.

The fix: one directory per identity

The key insight is that CLOUDSDK_CONFIG controls the entire gcloud state directory — including where application_default_credentials.json is written. Set it to a per-project path and you get complete isolation.

Setup (once per configuration)

1
2
3
4
export CLOUDSDK_CONFIG=~/.config/gcp-configurations/project-foo
gcloud init
gcloud auth login
gcloud auth application-default login

Repeat for each project or identity. Each directory is fully self-contained: config, credentials, access tokens, and ADC.

Per-directory activation with direnv

In any repo or directory where you want a specific configuration active, create an .envrc:

1
2
export CLOUDSDK_CONFIG=${HOME}/.config/gcp-configurations/project-foo
export GOOGLE_APPLICATION_CREDENTIALS=${HOME}/.config/gcp-configurations/project-foo/application_default_credentials.json

CLOUDSDK_CONFIG covers gcloud commands. GOOGLE_APPLICATION_CREDENTIALS is needed explicitly for Terraform and other third-party tools — they don’t read CLOUDSDK_CONFIG, they look for the ADC file at its default path unless you override it directly.

Run direnv allow once per directory. From that point, cd-ing in is enough — correct identity, correct project, correct Terraform credentials, nothing to run.

What you end up with

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
~/.config/gcp-configurations/
  work-project/
    active_config
    application_default_credentials.json
    credentials/
    ...
  personal-project/
    active_config
    application_default_credentials.json
    credentials/
    ...

A clean separation with zero shared state between identities. No wrapper scripts, no aliases, no risk of the wrong credentials leaking into a Terraform run.