Skip to main content

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

  1. Install shell hooks (gcpctx init zsh) or manually eval "$(gcpctx activate --shell zsh)" in your login shell.
  2. Open the IDE from that shell (cursor ., code .) so new integrated terminals start activated.
  3. Confirm with gcpctx status in 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.toml in the current directory tree (exit 2 if missing).
  • Pre-approve for non-interactive terminals (gcpctx approve).
  • GOOGLE_APPLICATION_CREDENTIALS is 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)

  1. Add .gcpctx.toml to the repo (gcpctx init-project).

  2. Approve once interactively, or pre-approve for automation:

    gcpctx approve   # remembered approval for this directory/profile
    
  3. Activate in the shell that launches the agent:

    eval "$(gcpctx activate --shell zsh)"
    
  4. 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 (v0.2)

  • POSIX only — Windows is unsupported; the CLI fails closed until ACL checks land.
  • First-use approval with remember + TTL (default 30 days); schema v2 binds gcloud path and fingerprint
  • Config SHA-256 binding invalidates approval when project, service account, or config changes
  • Immutable project identityCLOUDSDK_CORE_PROJECT always matches profile.project (cannot set via env)
  • Isolated CLOUDSDK_CONFIG under ~/.cache/gcpctx/contexts/
  • Atomic, locked, symlink-safe writes for approvals and context state (0600/0700)
  • gcloud binary trust validation (repo-local shadowing, world-writable parents, optional allowlist)
  • Service account impersonation only (no long-lived key files in repo config)
  • GOOGLE_APPLICATION_CREDENTIALS unset by default in hook mode (restored on deactivate)
  • Optional policy.toml for org-style allowlists and strict mode
  • gcpctx doctor --strict --json for CI/agent compliance gates
  • Append-only audit.jsonl for security events (no credential material)

See SECURITY.md and Architecture decision records (ADR-0003 through ADR-0009).

Upgrading from v0.1

  • Remove any [profiles.*.env] CLOUDSDK_CORE_PROJECT entries — use profile.project instead.
  • Service account emails must use the same GCP project as profile.project (e.g. agent@my-dev-project.iam.gserviceaccount.com for project = "my-dev-project"). Cross-project impersonation is not supported in v0.2.
  • Re-run gcpctx approve after upgrade (approval schema v2 adds gcloud binding and expiry).
  • Pin gcloud per project if needed: add gcloud_path to .gcpctx.toml or run gcpctx config set-gcloud-path "$(which gcloud)" in the repo (optional; pinning overrides PATH — run gcpctx config unset-gcloud-path if you move or upgrade gcloud)

Policy file (optional)

~/.config/gcpctx/policy.toml or $GCPCTX_POLICY_PATH:

version = 1
[policy]
mode = "strict"
approval_ttl_days = 30
require_initialized_adc_for_hook = true
[allow]
projects = ["dev-*"]
[gcloud]
allowed_paths = ["/opt/google-cloud-sdk/bin/gcloud"]

Strict doctor

gcpctx doctor --strict --json

Non-zero exit when isolation, approval, ADC, IAM impersonation, or filesystem posture is unsafe.

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, gcpctx reset, or gcpctx clean (then gcpctx clean --reinit)
Corrupt isolated ADC / clutter gcpctx clean (project); gcpctx clean --all-contexts (all cache)
Reset remembered approvals gcpctx clean --approvals or gcpctx revoke
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

gcpctx-0.2.0.tar.gz (163.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gcpctx-0.2.0-py3-none-any.whl (55.4 kB view details)

Uploaded Python 3

File details

Details for the file gcpctx-0.2.0.tar.gz.

File metadata

  • Download URL: gcpctx-0.2.0.tar.gz
  • Upload date:
  • Size: 163.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for gcpctx-0.2.0.tar.gz
Algorithm Hash digest
SHA256 742a6fc2bc22d30ec4f6a82e8ee9b351a0589739822b37d32960c3f30e8118f9
MD5 050ae71fdb996bc410a58dc9e7974753
BLAKE2b-256 f5f5982e0092e1842a54aa9dfcd57c1e27a62601a2faa8d0c3bb9aa448e43cc9

See more details on using hashes here.

Provenance

The following attestation bundles were made for gcpctx-0.2.0.tar.gz:

Publisher: publish.yml on yu-iskw/gcpctx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gcpctx-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: gcpctx-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 55.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for gcpctx-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 379ae108f5f4f8a0e7fcc434a6dae78fab95e5b50ae9fa2ff292020cbaaae99f
MD5 99bf73f95ce9bbee7a09f004692b9cc3
BLAKE2b-256 69293993c3c2c920e3511398231b310dd368e3ab0d8f601d2e58f1556c928457

See more details on using hashes here.

Provenance

The following attestation bundles were made for gcpctx-0.2.0-py3-none-any.whl:

Publisher: publish.yml on yu-iskw/gcpctx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page