Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions tests/tools/test_local_env_blocklist.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,29 @@ def test_bedrock_bearer_token_is_stripped(self):
"AWS_BEARER_TOKEN_BEDROCK leaked into subprocess env (see #32314)"
)

def test_vertex_credentials_path_is_stripped(self):
"""The Vertex AI service-account JSON path must not leak into
subprocesses, even though it is filesystem path metadata rather
than a bare API key.

Regression: ``vertex`` authenticates via OAuth2 (service-account
JSON / ADC), not PROVIDER_REGISTRY, and OPTIONAL_ENV_VARS marks
VERTEX_CREDENTIALS_PATH as ``password=False`` (it's a path, not a
secret string) with ``category="provider"`` — a category the
registry-derived loop above never checks — so it fell through both
blocklist sources. GOOGLE_APPLICATION_CREDENTIALS (the ADC fallback
the adapter also reads) had the same gap. A leaked path discloses
the on-disk location of a GCP service-account key to every spawned
subprocess (terminal, codex/copilot app-server, browser workers).
"""
result_env = _run_with_env(extra_os_env={
"VERTEX_CREDENTIALS_PATH": "/home/user/.config/gcloud/sa-key.json",
"GOOGLE_APPLICATION_CREDENTIALS": "/home/user/.config/gcloud/adc.json",
})

assert "VERTEX_CREDENTIALS_PATH" not in result_env
assert "GOOGLE_APPLICATION_CREDENTIALS" not in result_env

def test_general_aws_credential_chain_is_preserved(self):
"""The GENERAL AWS credential chain must STILL pass through to
subprocesses — this is the no-regression guard for #32314.
Expand Down
4 changes: 4 additions & 0 deletions tools/environments/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ def _build_provider_env_blocklist() -> frozenset:
"CLAUDE_CODE_OAUTH_TOKEN",
"LLM_MODEL",
"GOOGLE_API_KEY",
# Path to a GCP service-account JSON, not a bare key, so
# OPTIONAL_ENV_VARS marks it password=False and the loop above skips it.
"VERTEX_CREDENTIALS_PATH",
"GOOGLE_APPLICATION_CREDENTIALS",
"DEEPSEEK_API_KEY",
"MISTRAL_API_KEY",
"GROQ_API_KEY",
Expand Down
Loading