Repository navigation
feat(openclaw): resolve sandboxed Vertex credentials through ADC - #32
Merged
isadominguez314 merged 6 commits intoSep 11, 2026
Conversation
…o sandbox/026-openclaw-vertex-creds
… sandbox/026-openclaw-vertex-creds # Conflicts: # devops_bench/agents/cli/gemini_cli/agent.py # tests/unit/agents/test_agents_cli_antigravity.py
…ntial kubernetes-sigs#29 prepares openclaw's Vertex auth for the sandbox (routing env, metadata flag, headless auth profile) but never injects a credential source, so the metadata lookup aims at the real 169.254.169.254 -- which the sandbox boundary's DOCKER-USER rule rejects. Merge sandbox_credential_env(spec, project=...) into the sandboxed overlay for vertex-backend providers so the prepared auth resolves against the host-side metadata emulator instead (GCE_METADATA_HOST/IP + METADATA_SERVER_DETECTION=assume-present). The recipe is skipped when the run carries an explicit api_key: keyed google-vertex (express mode via GOOGLE_CLOUD_API_KEY) worked before this change and must not start requiring BENCH_VERTEX_SANDBOX_SA. Unsandboxed runs never reach _sandbox_provider_env, so the flag-off path is untouched.
The first live sandboxed google-vertex run against the kubernetes-sigs#25 emulator failed twice before it could reach the model, both times on pre-existing openclaw gaps rather than on the credential recipe: ProviderAuthError: No API key found for provider "google-vertex" Vertex AI requires a location. Set GOOGLE_CLOUD_LOCATION or pass location in options. The auth-profile gate is not plugin-specific. oc 2026.9.1-beta.1 consults its per-agent SQLite auth store for *every* provider before any ADC resolution happens, so a keyless google-vertex run aborts exactly as anthropic-vertex does. Generalize the workaround from the plugin to the whole vertex backend: _needs_anthropic_vertex_auth_profile becomes _vertex_auth_profile_provider, returning the oc provider id to seed. The pasted value is a marker, not a credential -- the transport still authenticates through ADC, and a real but wrong key would 401. The location comes from vertex_location() rather than the forwarding block, which only covered a host that had already set one of the two spellings. It applies to keyed runs too: a location is routing, not a credential. Assigning unconditionally does not clobber a forwarded value, since the chain reads GOOGLE_CLOUD_LOCATION first and resolves it back to itself. The auth profile is seeded on the unsandboxed path as well, which writes the marker to the operator's global oc store rather than the per-run state dir. That path fails the same way today, and scripts/bastion/configure-oc.sh already pastes the identical value for the same provider and agent, so on a configured host this rewrites the same row with the same bytes. With both fixes the pinned image returns a completed turn from google-vertex/gemini-3.8-flash through the sandboxed emulator credential.
…penclaw-vertex-creds
…penclaw-vertex-creds
This was referenced Sep 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Wires the #25 Vertex metadata-emulator credential recipe into the openclaw harness, so a keyless (ADC) sandboxed Vertex run works end to end.
What changed
devops_bench/agents/cli/openclaw/agent.pyonly:api_key,_sandbox_provider_envnow callssandbox_credential_env(spec, project=...)so the container reaches the host-side metadata emulator. Keyed runs are untouched.anthropic-vertex._needs_anthropic_vertex_auth_profileis replaced by_vertex_auth_profile_provider, which returns the oc provider id for any keyless Vertex backend, and_build_local_commandpastes thegcp-vertex-credentialsmarker for it. The marker is never sent as a credential — the transport resolves the real one through ADC; its only job is to satisfy oc's auth gate.overlay["GOOGLE_CLOUD_LOCATION"] = vertex_location()(fix(agents): default the CLI harnesses' Vertex location to global #24's shared chain). oc aborts with "Vertex AI requires a location" when this is unset, and forwarding alone misses the common case where the operator set neither spelling. Not a clobber: the chain readsGOOGLE_CLOUD_LOCATIONfirst, so a forwarded value resolves back to itself.No cloud CLI calls are added to
sandbox.py; the recipe stays incore/model_providers.pyand the wiring in the harness's own env builder.Validation
uv run pytest tests/unit→ 1852 passed; ruff clean. 8 new unit tests cover the seeded/skipped auth profile (keyless vs keyed vs non-Vertex) and the location default, explicit value, alternate spelling, keyed-Vertex and non-Vertex cases.Live on the bastion, sandboxed, keyless,
google-vertex/gemini-3.8-flash(run_20260911_172304_ocvertex-oc):bench-agent-vertexNo API key found for provider "google-vertex", zeroVertex AI requires a locationerrors: [], 149-step trajectory, OutcomeScore 0.866, IntegrityCatastrophic 1.0, cheating checks cleanhello-app.yaml+manifest.yaml(356 insertions)Known follow-ups (not in this PR)
OutcomeValidity 0.0on that run: oc itself stored[Malformed diagnostic JSON redacted]in place of the final assistant text, and the judge graded the placeholder. The redaction happens inside oc's own sqlite, not in this repo. Fix belongs in trajectory parsing (treat the placeholder as empty so theassistant.messagefallback engages) plus never letting the judge grade a placeholder.ocversion skew silently produces an empty trajectory reported asstatus: "success". Wants a cached version probe mirroringclaude_code/agent.py, and the bastion's three version pins collapsed into one.