Directory-scoped Google Cloud service account impersonation contexts
Project description
gcpctx
Directory-scoped Google Cloud service account impersonation contexts for terminals, IDEs, and coding agents.
What is gcpctx?
gcpctx automatically activates an isolated Google Cloud SDK and Application Default Credentials (ADC) environment when you enter a directory with a .gcpctx.toml file. Each profile maps to a GCP project and an impersonated service account. Activation exports a dedicated CLOUDSDK_CONFIG so your global ~/.config/gcloud is never mutated.
Why directory-scoped impersonation?
Developers and coding agents often inherit broad or wrong GCP credentials from the parent shell. gcpctx scopes authentication to the repository you are working in, with first-use approval and config-hash invalidation when trust-relevant settings change.
Installation
Choose one of these options:
| Method | Best for |
|---|---|
uvx |
Try without installing, CI one-offs, pinned versions |
pipx |
Daily CLI use on your machine |
| From source | Contributing or unreleased builds |
Run with uvx (no install)
uvx runs gcpctx in an ephemeral environment—no global install required.
# Latest from PyPI (when published)
uvx gcpctx --help
# Pin a version
uvx gcpctx@0.1.0 status
# Run from a local checkout (before publish)
uvx --from /path/to/gcpctx gcpctx --help
Typical workflow with uvx:
cd my-repo
uvx gcpctx init-project \
--project my-dev-project \
--service-account agent-dev@my-dev-project.iam.gserviceaccount.com
uvx gcpctx approve
eval "$(uvx gcpctx activate --shell zsh)"
uvx gcpctx status
uvx gcpctx doctor
Shell hooks installed via gcpctx init zsh call gcpctx on your PATH. After choosing uvx, either add a shell alias (alias gcpctx='uvx gcpctx') or install with pipx / uv tool install for hook integration.
pipx
pipx install gcpctx
gcpctx --help
From source
git clone <repo-url> && cd gcpctx
uv sync
uv run gcpctx --help
# optional: uv tool install -e .
Quick start
# 1. Create project config
gcpctx init-project --project my-dev-project \
--service-account agent-dev@my-dev-project.iam.gserviceaccount.com
# 2. Approve and activate (zsh example)
gcpctx approve
eval "$(gcpctx activate --shell zsh)"
# 3. Verify
gcpctx status
gcloud config list
.gcpctx.toml example
version = 1
default_profile = "dev"
[profiles.dev]
project = "my-dev-project"
service_account = "agent-dev@my-dev-project.iam.gserviceaccount.com"
quota_project = "my-billing-project"
region = "asia-northeast1"
Shell integration
gcpctx init zsh # or: gcpctx init bash
exec $SHELL # reload shell
The hook runs gcpctx hook eval on every directory change. Stdout is shell code only; diagnostics go to stderr.
Manual activation without hooks:
eval "$(gcpctx activate --shell zsh)"
eval "$(gcpctx deactivate --shell zsh)" # restore prior env
Switch profile (after gcpctx init installs the wrapper):
gcpctx-use prod-readonly
IDE usage (VS Code, Cursor, JetBrains)
Integrated terminals inherit the parent shell environment. Subprocesses started by the IDE (build tasks, debuggers, test runners) see the same CLOUDSDK_CONFIG, ADC, and GCPCTX_* variables as your shell.
Recommended setup
- Install shell hooks (
gcpctx init zsh) or manuallyeval "$(gcpctx activate --shell zsh)"in your login shell. - Open the IDE from that shell (
cursor .,code .) so new integrated terminals start activated. - Confirm with
gcpctx statusin an integrated terminal.
Verify isolation
gcpctx status
gcpctx doctor
gcpctx doctor --json # machine-readable for scripts
Doctor checks that CLOUDSDK_CONFIG lives under ~/.cache/gcpctx/contexts/, gcloud project/impersonation match your profile, and ADC is initialized.
GOOGLE_APPLICATION_CREDENTIALS
In hook mode, GOOGLE_APPLICATION_CREDENTIALS is unset while active (previous value restored on deactivate) so ADC impersonation is not overridden. If you must keep a key file in non-interactive sessions, pass --allow-google-application-credentials to activate.
Coding agents (Cursor, Claude Code, Codex, Copilot)
Agents run in terminals or sandboxes that inherit environment variables. Use either shell activation (whole session) or gcpctx run (one process only).
Process-scoped launch (recommended for agents)
Run a command with per-project credentials without changing your parent shell:
gcpctx approve
gcpctx run -- claude
uvx gcpctx run -- codex ...
gcpctx run --profile dev -- gcloud storage ls
- Requires
.gcpctx.tomlin the current directory tree (exit 2 if missing). - Pre-approve for non-interactive terminals (
gcpctx approve). GOOGLE_APPLICATION_CREDENTIALSis unset in the child by default (same as hook mode).- Access tokens are short-lived; client libraries refresh ADC automatically (no gcpctx supervisor).
Shell activation (whole session)
-
Add
.gcpctx.tomlto the repo (gcpctx init-project). -
Approve once interactively, or pre-approve for automation:
gcpctx approve # remembered approval for this directory/profile
-
Activate in the shell that launches the agent:
eval "$(gcpctx activate --shell zsh)"
-
Agents and their subprocesses inherit isolated credentials.
Non-interactive / fail-closed
Without a matching approval, gcpctx activate exits with code 3 in non-interactive mode (typical agent terminals). Pre-run gcpctx approve in CI or document that users must activate interactively once.
Agent-friendly diagnostics
gcpctx doctor --json
gcpctx status --json
Parse JSON for active, cloudsdk_config, approval, and per-check status from doctor.
When GOOGLE_APPLICATION_CREDENTIALS is required
Some tools insist on a key file path. Use --allow-google-application-credentials only when necessary; prefer impersonated ADC otherwise.
Security model
- First-use approval with optional remember; non-interactive mode fails closed without approval
- Config SHA-256 binding invalidates approval when project, service account, or config changes
- Isolated
CLOUDSDK_CONFIGunder~/.cache/gcpctx/contexts/ - Service account impersonation only (no long-lived key files in repo config)
- Restrictive file permissions on state directories and approvals
GOOGLE_APPLICATION_CREDENTIALSunset by default in hook mode (restored on deactivate)
See Architecture decision records for design rationale (ADR-0003 through ADR-0008).
Troubleshooting
| Symptom | Fix |
|---|---|
approval required in CI/agent |
Run gcpctx approve once, or activate interactively |
| Wrong project | gcpctx status; check .gcpctx.toml |
| Stale credentials | gcpctx refresh or gcpctx reset |
gcloud not found |
Install Google Cloud SDK |
| ADC issues | gcpctx doctor |
| IDE terminal not activated | Activate in parent shell before launching IDE, or use shell hooks |
Contributing
See CONTRIBUTING.md for developer setup, tests, and architecture notes.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gcpctx-0.1.0.tar.gz.
File metadata
- Download URL: gcpctx-0.1.0.tar.gz
- Upload date:
- Size: 129.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e1400cc8a1761c406b20e9005f23b59e52990765ff5a54a7e20b504beb1672f
|
|
| MD5 |
a5d660f594ba7376aa8f143393881101
|
|
| BLAKE2b-256 |
f4a7fbd687c7d0627842482ff05f9c2d547ab7205b80019849f5af6883658320
|
Provenance
The following attestation bundles were made for gcpctx-0.1.0.tar.gz:
Publisher:
publish.yml on yu-iskw/gcpctx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gcpctx-0.1.0.tar.gz -
Subject digest:
9e1400cc8a1761c406b20e9005f23b59e52990765ff5a54a7e20b504beb1672f - Sigstore transparency entry: 1919727657
- Sigstore integration time:
-
Permalink:
yu-iskw/gcpctx@ff5a3efb62f5c61443a3e7374dd691a73a5c648e -
Branch / Tag:
refs/tags/0.1.0 - Owner: https://github.com/yu-iskw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ff5a3efb62f5c61443a3e7374dd691a73a5c648e -
Trigger Event:
release
-
Statement type:
File details
Details for the file gcpctx-0.1.0-py3-none-any.whl.
File metadata
- Download URL: gcpctx-0.1.0-py3-none-any.whl
- Upload date:
- Size: 39.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
66672ef4f4bbf446621cb1e9e3d5540e612887cf703d7feaa23c3ce1c3bc852e
|
|
| MD5 |
fa4d0bedc70f89c0117e6fb84b676a13
|
|
| BLAKE2b-256 |
3fa37d6f32dee66269cd4697c5484407dbc1bf4a24fe1cab01eba8784359a78f
|
Provenance
The following attestation bundles were made for gcpctx-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on yu-iskw/gcpctx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gcpctx-0.1.0-py3-none-any.whl -
Subject digest:
66672ef4f4bbf446621cb1e9e3d5540e612887cf703d7feaa23c3ce1c3bc852e - Sigstore transparency entry: 1919728130
- Sigstore integration time:
-
Permalink:
yu-iskw/gcpctx@ff5a3efb62f5c61443a3e7374dd691a73a5c648e -
Branch / Tag:
refs/tags/0.1.0 - Owner: https://github.com/yu-iskw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ff5a3efb62f5c61443a3e7374dd691a73a5c648e -
Trigger Event:
release
-
Statement type: