gcloud-ctx is a fast, kubectx-style context
switcher for the gcloud CLI. A context is a named gcloud configuration (account,
project, region/zone, impersonation) plus an optional per-context Application
Default Credentials (ADC) snapshot, so switching contexts also switches what
Terraform, client libraries, and anything else built on google-auth sees — and
keeps service account impersonation consistent across both the gcloud CLI and ADC,
instead of leaving them silently out of sync.
Via go install:
go install github.com/sakajunquality/gcloud-ctx@latest
Or download a prebuilt binary for your OS/arch from GitHub Releases.
Consider aliasing it, kubectx-style:
alias gctx=gcloud-ctx
gcloud-ctx List contexts (interactive fuzzy picker on a TTY)
gcloud-ctx <NAME> Switch to context NAME
gcloud-ctx - Switch to the previous context
gcloud-ctx -c, --current Print current context name
gcloud-ctx -l, --long List as a table: NAME, ACTIVE, ACCOUNT, PROJECT, IMPERSONATION, ADC
gcloud-ctx <NEW>=<OLD> Rename OLD to NEW ('.' = current)
gcloud-ctx -d, --delete <NAME>... Delete context(s) (refuses the active one, like gcloud)
gcloud-ctx -u, --unset Activate gcloud's virtual NONE configuration
gcloud-ctx create <NAME> [--project P] [--account A] [--impersonate SA] [--no-activate]
gcloud-ctx show [NAME] Show context details incl. impersonation and ADC status
gcloud-ctx impersonate <SA> [--delegates d1,d2] [--quota-project P] [--context NAME]
gcloud-ctx impersonate --clear [--context NAME]
gcloud-ctx adc save [NAME] Snapshot the live ADC file into the store for NAME (default: current)
gcloud-ctx env [NAME] Print exports that pin NAME for one shell only (see below)
gcloud-ctx env --unset Print the matching unset lines
gcloud-ctx refresh [NAME] Re-run ADC login and rebuild every same-account snapshot
gcloud-ctx completion bash|zsh|fish|powershell
gcloud-ctx --version
The interactive picker (bare gcloud-ctx on a TTY) shows a preview pane with
account/project/impersonation for the highlighted context; cancel with Esc/Ctrl-C
to exit without switching. Set GCLOUD_CTX_IGNORE_FZF to always fall back to a plain
sorted list instead (useful in scripts piping through a pager).
Known limitation: subcommand names (
create,show,impersonate,adc,env,refresh,completion,help) shadow context names at the root level — a context literally namedshowcan't be switched to viagcloud-ctx show. This is unlikely in practice givengcloud's config name charset (^[a-z][-a-z0-9]*$), but it's a known tradeoff of reusing the kubectx grammar.
ADC snapshots are file copies of refresh tokens. Tokens don't normally expire, but Workspace re-auth policies, revocation, or a password change kill them — and every snapshot copied from that token dies at once. One command recovers everything:
gcloud-ctx refresh # or: gcloud-ctx refresh workIt runs gcloud auth application-default login (browser), updates the
context's snapshot — preserving impersonation targets/delegates/quota
projects for impersonated snapshots — rebuilds every other context's
snapshot derived from the same account, and leaves the live ADC matching the
active context. Other accounts' snapshots are untouched.
The gcloud CLI's own login is a separate per-account token store; if gcloud
itself says Reauthentication required, also run gcloud auth login (once
per account — all contexts referencing that account share it).
No browser on this machine? Both of gcloud's login fallbacks are forwarded
verbatim: gcloud-ctx refresh --no-launch-browser (prints the URL to open
yourself) and gcloud-ctx refresh --no-browser (remote-bootstrap flow for
SSH hosts; requires gcloud on a browser-equipped machine too).
gcloud-ctx <NAME> switches machine-global state (active_config and the live
ADC file), which is what you want interactively — but several shells, terminal
tabs, or AI coding agents on one machine can't each hold a different context
that way. gcloud-ctx env pins a context to one shell only, using gcloud's
own per-process override plus the context's stored ADC snapshot, without
touching any global file:
eval "$(gcloud-ctx env prod)"
# exports for this shell and its children only:
# CLOUDSDK_ACTIVE_CONFIG_NAME=prod → gcloud CLI uses "prod"
# GOOGLE_APPLICATION_CREDENTIALS=…/adc/prod.json → ADC consumers use "prod"'s snapshotUndo with eval "$(gcloud-ctx env --unset)". The GOOGLE_APPLICATION_CREDENTIALS
line is emitted only when the context has a stored snapshot (gcloud-ctx adc save);
otherwise the variable is unset so it can't point at a stale snapshot. While these
variables are set, gcloud-ctx <NAME> switches in that shell have no visible
effect — the tool warns about exactly this on stderr.
gcloud-ctx only ever does local file manipulation — no network calls at switch
time, exactly like gcloud config configurations activate.
Files it reads and writes, all under your gcloud config directory
($CLOUDSDK_CONFIG, or the OS default gcloud uses):
configurations/config_<name>— the named configuration's INI properties (account, project, region, zone, impersonation), parsed and rewritten in place so unrelated keys survive.active_config— which configuration is active. Renaming the active context (includinggcloud-ctx NEW=.) is supported:active_configis rewritten to follow the new name, so the switch stays coherent.config_sentinel— touched (empty write) on every mutation — switch, create, delete, rename, or an impersonation/property change — so IDE plugins and credential helpers know to re-read config, exactly likegclouditself.application_default_credentials.json— the live ADC file, atomically replaced (temp file + rename, mode0600) when the target context has a stored ADC. The virtualNONEconfiguration (gcloud-ctx --unset) never has a stored ADC and gcloud-ctx never writes one for it — switching toNONEalways leaves the live ADC file untouched.gcloud-ctx/— gcloud-ctx's own state:gcloud-ctx/previous(forgcloud-ctx -) andgcloud-ctx/adc/<name>.json(one stored ADC snapshot per context). Living inside thegcloudconfig dir means test/sandbox isolation via$CLOUDSDK_CONFIGcovers gcloud-ctx's state too.
Files it never touches: credentials.db, access_tokens.db, or any other
gcloud-managed OAuth token store. Those are keyed by account email and shared
across configurations — obtaining or refreshing the underlying credentials stays
gcloud auth login / gcloud auth application-default login's job. gcloud-ctx never
performs an OAuth/browser flow.
There is no automatic ADC snapshotting: gcloud-ctx adc save is the explicit way to
bind the current live ADC to a context. Predictability over magic. adc save
validates the live ADC file first — it must parse as JSON and have one of the
credential types gcloud itself writes — and refuses rather than storing something
that can't later be installed or unwrapped.
Suppose you want context prod to use impersonation of a deploy service account.
-
Grant yourself (or the base credential) the right to impersonate it:
gcloud iam service-accounts add-iam-policy-binding \ deploy@my-project.iam.gserviceaccount.com \ --member="user:you@example.com" \ --role="roles/iam.serviceAccountTokenCreator" -
Point the context at it:
gcloud-ctx impersonate deploy@my-project.iam.gserviceaccount.com --context prodprod's stored ADC — or the live ADC if none is stored yet — is unwrapped (if necessary) and used assource_credentialsto synthesize animpersonated_service_accountADC JSON:{ "delegates": [], "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/deploy@my-project.iam.gserviceaccount.com:generateAccessToken", "source_credentials": { "...": "..." }, "type": "impersonated_service_account" }That JSON is saved to
gcloud-ctx/adc/prod.jsonand, ifprodis the active context, installed as the live ADC too — beforeauth/impersonate_service_accountis written toconfig_prod, so a failure at that last step is reported precisely (ADC updated for "prod" but the gcloud property was not set: ...) instead of leaving ADC and the gcloud property silently disagreeing. Once both succeed,gcloudCLI calls and ADC-based libraries agree on the same impersonated identity.If
--contextnames a context other than the one actually active, and that context has no stored ADC of its own, gcloud-ctx borrows the live ADC as the base credential and says so on stderr (using current live ADC (account ...) as base credentials for context "prod") — worth noticing, since it means the synthesized credential is based on whoever is currently logged in, not necessarilyprod's own identity.A delegation chain toward the target is
--delegates d1,d2: gcloud-ctx records it inauth/impersonate_service_accountthe same waygclouditself does — one comma-joined chain, delegates first, target last (d1,d2,deploy@my-project.iam.gserviceaccount.com) — and lists the same delegates (in order) in the synthesized ADC JSON'sdelegatesarray. -
gcloud-ctx show prodreports the impersonation target and delegates (parsed back out of that comma chain), and whether the live ADC matches the stored one, so aPERMISSION_DENIEDat token-generation time (missing the IAM binding from step 1) is easy to diagnose. -
gcloud-ctx impersonate --clear --context produndoes it: unwraps the stored ADC back to itssource_credentials(installing live too ifprodis active — and ifprodis the live active context, its live ADC file is unwrapped directly even if gcloud-ctx's own store has no record of the impersonation), then removesauth/impersonate_service_account. As withimpersonateitself, ADC moves first; a failure clearing the property is reported asADC updated for "prod" but the gcloud property was not cleared: ....
| Variable | Effect |
|---|---|
CLOUDSDK_CONFIG |
Overrides the gcloud config directory (same as gcloud itself). |
CLOUDSDK_ACTIVE_CONFIG_NAME |
Overrides the active configuration for the current shell; gcloud-ctx warns that a switch is shadowed while this is set. |
GOOGLE_APPLICATION_CREDENTIALS |
If set, ADC libraries read this file instead of the live ADC gcloud-ctx manages; gcloud-ctx only reads this to warn you it's set (on show/switch), it never reads or writes the file itself. |
GCLOUD_CTX_IGNORE_FZF |
Any non-empty value disables the interactive fuzzy picker; falls back to a plain sorted list. |
NO_COLOR |
Any non-empty value disables color output (per no-color.org); bold is kept. |
FORCE_COLOR |
Re-enables color even when stdout isn't a TTY. |
Several other tools in this space do switch ADC — the differentiator isn't "we're
the only one who touches ADC," it's keeping impersonation in sync across both
places gcloud tracks it (the auth/impersonate_service_account gcloud property and
the ADC JSON's impersonated_service_account wrapper) as part of the same kubectx-
faithful switch, rather than as a separate subcommand-driven flow:
| Tool | Grammar | Switches gcloud config | Switches ADC | Impersonation kept in sync |
|---|---|---|---|---|
ogerbron/gcloudctx |
kubectx grammar (bash port) | Yes | No | No |
uhinze/gconf |
kubectx-inspired (bash); list/switch/- only, no rename or delete |
Yes | No | No |
agadelshin/gcloudctx |
kubectx-ish (Go); its own README lists colorized output, completions, and interactive mode as still TODO | Yes | No | No |
xgourmandin/gcloud-switch |
subcommand (add/list/switch/edit/current) |
Yes | Yes — reuses valid credentials, re-authenticates when needed | Optional per-config SA flag; not documented as synced back to ADC |
k0wl0n/gctx |
subcommand (Cobra CLI) | Yes | Yes — a separate ADC snapshot per account, swapped on switch | No |
tjirsch/gcloud-switch |
TUI + scripting subcommands (Rust) | Yes (user credentials) | Yes | No |
| gcloud-ctx | kubectx grammar (gcloud-ctx <NAME>, -, -c, -l, ...) |
Yes | Yes | Yes — one switch keeps auth/impersonate_service_account and the ADC JSON in agreement |
(Table current as of 2026-08; verified each repo exists and read its README before
describing it here. Two tools previously listed here — under the names gcloudctx
at newkozlukov/gcloudctx and gcloud-switch at wshihadeh/gcloud-switch — no
longer resolve to a repository and have been dropped.)
The repo ships an Agent Skill that teaches AI
coding agents (Claude Code and other SKILL.md-compatible tools) how to operate
gcloud-ctx safely: non-interactive usage, credentials hygiene, impersonation
recipes, and how to sandbox experiments with CLOUDSDK_CONFIG.
Install for Claude Code (per project or globally):
mkdir -p .claude/skills/gcloud-ctx # or ~/.claude/skills/gcloud-ctx
curl -fsSL https://raw.githubusercontent.com/sakajunquality/gcloud-ctx/main/skills/gcloud-ctx/SKILL.md \
-o .claude/skills/gcloud-ctx/SKILL.mdApache-2.0, see LICENSE.