Pin Gemini CLI auth type so api-proxy runs stop failing with exit 41 - #8916
Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The unsafe file write and incorrect backend/environment handling must be fixed before approval.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 1
Open (4)
What changed in this PR
Pins Gemini CLI API-key authentication for API-proxy runs to prevent exit 41.
Changes:
- Adds and injects AWF-owned Gemini system settings.
- Adds authentication-mode regression tests.
- Updates compatibility and troubleshooting documentation.
| File | Review |
|---|---|
src/workdir-setup.test.ts |
Tests settings-file creation and exclusions. |
src/services/credentials/gemini-credential-env.ts |
Moderate: Settings are unavailable on sbx/Cloud Hypervisor backends, and auth flags are resolved from the wrong environment source. |
src/services/credentials/gemini-credential-env.test.ts |
Tests environment injection and gating. |
src/services/credentials/gemini-cli-settings.ts |
Moderate: Vertex/GCA predicates do not use the agent’s effective configured environment. |
src/chroot-home-setup.ts |
Critical: The root-side write follows symlinks, permitting redirection and ownership changes to arbitrary host files. |
docs/environment.md |
Nit: Compatibility claims do not account for unsupported external guest backends. |
docs/api-proxy-sidecar.md |
Nit: Existing exit-41 guidance contradicts the new diagnosis. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| fs.writeFileSync(settingsPath, buildGeminiSystemSettingsContent(), { mode: 0o644 }); | ||
| fs.chownSync(settingsPath, uid, gid); | ||
| fs.chmodSync(settingsPath, 0o644); |
| export function shouldPinGeminiAuthType(env: NodeJS.ProcessEnv = process.env): boolean { | ||
| return env.GOOGLE_GENAI_USE_VERTEXAI !== 'true' && env.GOOGLE_GENAI_USE_GCA !== 'true'; |
| extraEnv: isGeminiProxyRoutingEnabled(config) && shouldPinGeminiAuthType() | ||
| ? { GEMINI_CLI_SYSTEM_SETTINGS_PATH: getGeminiSystemSettingsPath(getRealUserHome()) } |
| @@ -677,6 +680,28 @@ When `GEMINI_API_KEY` is provided to the AWF runner, `GOOGLE_GEMINI_BASE_URL`, ` | |||
|
|
|||
| > **Note:** Exit code 41 ("no auth method") should no longer occur since the placeholder key satisfies the CLI's pre-flight check. If you see exit 41, verify `GEMINI_API_KEY` is exported in the AWF runner environment. | |||
|
@copilot address review feedback |
|
✅ Copilot review passed with no inline comments. @copilot Add the |
Documentation PreviewDocumentation has been built for this PR. To view locally:
Built from commit 33fffe8 |
|
🔌 Smoke Services — All services reachable! ✅
|
|
✅ Smoke Claude passed Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "api.anthropic.com"See Network Configuration for more information.
|
|
✅ Smoke Gemini completed. All facets verified. 💎 Warning Firewall blocked 2 domainsThe following domains were blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "github.com"
- "play.googleapis.com"See Network Configuration for more information.
|
|
✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟 Warning Firewall blocked 12 domainsThe following domains were blocked by the firewall during workflow execution:
[!TIP] tools:
github:
mode: gh-proxySee GitHub Tools for more information on To allow these domains, add them to the network:
allowed:
- defaults
- "ab.chatgpt.com"
- "accounts.google.com"
- "api.github.com"
- "clients2.google.com"
- "collector.github.com"
- "contentautofill.googleapis.com"
- "github.com"
- "github.githubassets.com"
- "msfeed25.pkgs.visualstudio.com"
- "update.googleapis.com"
- "www.google.com"
- "www.gstatic.com"See Network Configuration for more information.
|
|
✅ Build Test Suite completed successfully! Warning Firewall blocked 8 domainsThe following domains were blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "api.nuget.org"
- "bun.sh"
- "dc.services.visualstudio.com"
- "deno.land"
- "dl.deno.land"
- "github.com"
- "releaseassets.githubusercontent.com"
- "repo.maven.apache.org"See Network Configuration for more information.
|
|
🚀 Security Guard has started processing this pull request |
|
❌ Smoke Copilot BYOK AOAI (Entra) reports failed. AOAI BYOK (Entra) mode investigation needed...
|
Smoke Test: Claude Engine Validation
Overall result: PASS Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "api.anthropic.com"See Network Configuration for more information.
|
Smoke Test: Cloud Hypervisor + Copilot
All checks PASS. Warning Firewall blocked 2 domainsThe following domains were blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "example.com"
- "github.com"See Network Configuration for more information.
|
|
Smoke Test: Copilot BYOK (Direct Mode) — PASS ✅
Mode: Direct BYOK (COPILOT_PROVIDER_API_KEY) with api-proxy sidecar credential injection cc/
|
|
EGRESS_RESULT allow=pass deny=pass ✅ Allowed domain (github.com) reachable: Overall status: PASS Warning Firewall blocked 2 domainsThe following domains were blocked by the firewall during workflow execution:
[!TIP] tools:
github:
mode: gh-proxySee GitHub Tools for more information on To allow these domains, add them to the network:
allowed:
- defaults
- "api.github.com"
- "example.com"See Network Configuration for more information.
|
|
Smoke Test: Copilot Engine — cc
Overall: PASS
|
|
Smoke Test: Services Connectivity
Overall: PASS
|
🏗️ Build Test Suite Results
Overall: 8/8 ecosystems passed — ✅ PASS Notes:
All 18 test projects across all 8 ecosystems built and passed successfully through the firewall proxy. Warning Firewall blocked 8 domainsThe following domains were blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "api.nuget.org"
- "bun.sh"
- "dc.services.visualstudio.com"
- "deno.land"
- "dl.deno.land"
- "github.com"
- "releaseassets.githubusercontent.com"
- "repo.maven.apache.org"See Network Configuration for more information.
|
Chroot Version Comparison Results
Overall: ❌ FAILED — Node.js version mismatch between host and chroot environment. The
|
|
feat: add NVX Phase 3f promotion evidence Warning Firewall blocked 12 domainsThe following domains were blocked by the firewall during workflow execution:
[!TIP] tools:
github:
mode: gh-proxySee GitHub Tools for more information on To allow these domains, add them to the network:
allowed:
- defaults
- "ab.chatgpt.com"
- "accounts.google.com"
- "api.github.com"
- "clients2.google.com"
- "collector.github.com"
- "contentautofill.googleapis.com"
- "github.com"
- "github.githubassets.com"
- "msfeed25.pkgs.visualstudio.com"
- "update.googleapis.com"
- "www.google.com"
- "www.gstatic.com"See Network Configuration for more information.
|
Smoke Test: Gemini Engine Validation
Warning Firewall blocked 2 domainsThe following domains were blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "github.com"
- "play.googleapis.com"See Network Configuration for more information.
|
Smoke Test: API Proxy OpenTelemetry Tracing — Results
Overall: ✅ All 5 scenarios pass. No unexpected failures detected. Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "o205451.ingest.us.sentry.io"See Network Configuration for more information.
|



Gemini CLI runs through
--enable-api-proxyabort at startup withInvalid auth method selected.(exit 41). This is an upstream regression, not a proxy routing or placeholder-key problem.Root cause
Since gemini-cli 0.44.0,
getAuthTypeFromEnv()maps any non-emptyGOOGLE_GEMINI_BASE_URLtoAuthType.GATEWAY, evaluated before theGEMINI_API_KEYcheck.validateAuthMethod()has nogatewaybranch, so it falls through toreturn 'Invalid auth method selected.', whichvalidateNonInteractiveAuthturns intoFatalAuthenticationError(exit 41). Upstream: google-gemini/gemini-cli#27550 (open, two closed fix PRs).AWF must set
GOOGLE_GEMINI_BASE_URLto route the CLI at the sidecar, so every proxied Gemini run hits this. Confirmed against thesmoke-geminiartifact from run 35862843304 (Invalid auth method selected.→exitCode=41) and by diffingcontentGenerator.ts/auth.tsbetween v0.43.0 and v0.55.1.Notably, the placeholder key format is irrelevant — gemini-cli performs no key-format validation anywhere, so adjusting
gemini-api-key-placeholder-for-credential-isolation(as the issue proposed) would not have helped.Changes
src/services/credentials/gemini-cli-settings.ts(new) — settings content, path helper, and the enable/skip predicates shared by the writer and the env builder.src/chroot-home-setup.ts— writes$HOME/.awf/gemini-cli-system-settings.jsoninto the empty chroot home volume, owned by the agent uid/gid. The host's real~/.geminiis untouched.src/services/credentials/gemini-credential-env.ts— injectsGEMINI_CLI_SYSTEM_SETTINGS_PATHunder the same gate (api-proxy enabled + Gemini routed + not Vertex/GCA), so the env var can never point at a file AWF didn't write.docs/api-proxy-sidecar.md; Gemini CLI compatibility matrix indocs/environment.md.The file AWF writes:
{ "security": { "auth": { "selectedType": "gemini-api-key" } } }The CLI resolves
settings.merged.security.auth.selectedType || getAuthTypeFromEnv(), and the system settings scope has the highest merge precedence, so API-key auth wins over thegatewayinference whileGOOGLE_GEMINI_BASE_URLis still honoured for request routing. The file sets onlysecurity.auth.selectedType, so gh-aw's workspacemcpServersblock deep-merges untouched. A missing file is a silent no-op in the CLI, so non-compose backends degrade to current behaviour rather than erroring.The pin is skipped when
GOOGLE_GENAI_USE_VERTEXAI=trueorGOOGLE_GENAI_USE_GCA=true— those auth types resolve before thegatewaybranch, and pinning API-key auth would break them.Not covered
Issue item 4 (a live
engine: geminiintegration test through the sidecar) is not added —smoke-gemini.lock.ymlalready exercises this path end-to-end and will exercise the fix once a release image ships. Since the fix is host-side only (nocontainers/agentchanges), it does not depend on a new agent image.