Skip to content

fix(google): support gemini cli personal oauth#61260

Merged
vincentkoc merged 4 commits intomainfrom
fix/gemini-cli-personal-oauth
Apr 5, 2026
Merged

fix(google): support gemini cli personal oauth#61260
vincentkoc merged 4 commits intomainfrom
fix/gemini-cli-personal-oauth

Conversation

@vincentkoc
Copy link
Copy Markdown
Member

Summary

  • Problem: OpenClaw always routes Gemini CLI OAuth logins through Code Assist project discovery, even when the local Gemini CLI is configured for personal OAuth.
  • Why it matters: personal Google accounts fail login with loadCodeAssist 400 Bad Request, so the bundled Gemini CLI provider is unusable for that auth mode.
  • What changed: detect personal OAuth mode from local Gemini settings or GOOGLE_GENAI_USE_GCA, skip Code Assist project discovery for that path, and only persist projectId metadata when a workspace/project-backed login actually returned one.
  • What did NOT change (scope boundary): the existing workspace / Code Assist onboarding path, token exchange flow, and Gemini CLI credential discovery remain intact.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause (if applicable)

  • Root cause: the Gemini CLI plugin assumed every OAuth login was a Code Assist / project-backed login and unconditionally called loadCodeAssist after token exchange.
  • Missing detection / guardrail: we were not reading the local Gemini CLI auth mode, so personal OAuth users were forced down the wrong post-login identity path.
  • Contributing context (if known): Gemini CLI itself has a real oauth-personal mode and uses settings/env to decide it.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: extensions/google/oauth.test.ts
  • Scenario the test should lock in: personal OAuth logins never call loadCodeAssist, while workspace OAuth still does.
  • Why this is the smallest reliable guardrail: the bug lives in the post-token routing branch, so the OAuth seam test is enough to prove the mode split without needing real Google auth.
  • Existing test that already covers this (if any): existing workspace OAuth tests in extensions/google/oauth.test.ts.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • Google Gemini CLI OAuth now works when the local Gemini CLI is configured for personal Google login.
  • Workspace / project-backed Gemini CLI OAuth behavior is unchanged.

Diagram (if applicable)

Before:
[Gemini CLI personal OAuth token] -> [always loadCodeAssist] -> [400 Bad Request]

After:
[Gemini CLI personal OAuth token] -> [detect oauth-personal] -> [resolve email only] -> [login succeeds]

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22 / pnpm
  • Model/provider: google-gemini-cli
  • Integration/channel (if any): N/A
  • Relevant config (redacted): local ~/.gemini/settings.json with security.auth.selectedType = "oauth-personal"

Steps

  1. Configure Gemini CLI for personal OAuth.
  2. Start OpenClaw Gemini CLI OAuth login.
  3. Complete the browser flow.

Expected

  • Token exchange succeeds without any loadCodeAssist call.
  • The provider profile is stored without fake project metadata.

Actual

  • Before this PR, OpenClaw always called loadCodeAssist and personal OAuth logins failed with 400 Bad Request.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios: personal OAuth mode from local settings; legacy top-level settings fallback; existing workspace OAuth login path; optional projectId credential storage shape.
  • Edge cases checked: GOOGLE_GENAI_USE_GCA=true override; missing settings file; no accidental loadCodeAssist or onboardUser calls in personal mode.
  • What you did not verify: live Google OAuth with a real personal account in this session.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: a malformed or stale local Gemini settings file could mis-detect auth mode.
    • Mitigation: detection is intentionally narrow, falls back safely, and the existing workspace path remains the default when no explicit personal mode is found.

@vincentkoc vincentkoc self-assigned this Apr 5, 2026
@openclaw-barnacle openclaw-barnacle Bot added size: M maintainer Maintainer-authored PR labels Apr 5, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2231c27fb2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/google/oauth.settings.ts Outdated
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 5, 2026

Greptile Summary

This PR fixes personal Google account logins for the bundled Gemini CLI provider by detecting when the local Gemini CLI is configured in oauth-personal mode (via ~/.gemini/settings.json or a new env-var heuristic) and skipping the loadCodeAssist Code Assist discovery that was unconditionally called after token exchange, returning 400 Bad Request for personal accounts. The workspace / Code Assist path, token exchange flow, and credential discovery are unchanged. The new oauth.settings.ts module is well-structured with injectable FS seams, and the new integration test for the loginGeminiCliOAuth personal-OAuth scenario locks in the routing split correctly.

Notable concerns:

  • readString in oauth.settings.ts returns the raw (untrimmed) string while using value.trim() only for the truthiness guard. A settings value with incidental whitespace (e.g. \"oauth-personal \") would fail the strict === \"oauth-personal\" check in isGeminiCliPersonalOAuth(), silently re-enabling loadCodeAssist for a personal OAuth user and reproducing the 400 error.
  • The GOOGLE_GENAI_USE_GCA === \"true\" \u2192 \"oauth-personal\" mapping is counterintuitive: the env-var name reads as "Use Google Cloud Assist" (the enterprise Code Assist path). If the actual Gemini CLI interprets this flag as enabling Code Assist rather than personal OAuth, workspace users who have it set would bypass loadCodeAssist and receive a projectId-less credential. The settings-file detection path is unambiguous; the env-var shortcut should be cross-checked against the upstream Gemini CLI source before merging.

Confidence Score: 3/5

Conditionally safe — the settings-file detection path is solid, but the GOOGLE_GENAI_USE_GCA env-var mapping needs verification against actual Gemini CLI semantics before merging.

The fix logic and test coverage for the settings-file detection path are correct and well-structured. The two concerns — the readString untrimmed return that can silently mis-classify personal OAuth users, and the potentially inverted GOOGLE_GENAI_USE_GCA semantics — are both correctness risks for the exact scenario this PR aims to fix. If the env-var semantics are wrong, workspace users with that variable set would be misrouted.

extensions/google/oauth.settings.ts (readString return value, GOOGLE_GENAI_USE_GCA mapping); extensions/google/oauth.test.ts (env-var test should be confirmed against upstream Gemini CLI docs)

Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/google/oauth.settings.ts
Line: 34-36

Comment:
**`readString` returns untrimmed value — comparison to `"oauth-personal"` may silently fail**

The guard `value.trim()` is used only for the truthiness check; the raw (potentially whitespace-padded) `value` is what gets returned. If a user's `~/.gemini/settings.json` contains `selectedType: "oauth-personal "` (trailing space), `resolveGeminiCliSelectedAuthType()` returns `"oauth-personal "`, the strict equality check in `isGeminiCliPersonalOAuth()` fails, and the call falls through to `resolveGoogleOAuthIdentity` — invoking `loadCodeAssist` for what is actually a personal OAuth user and re-introducing the 400 error this PR aims to fix.

Return the trimmed string consistently:

```suggestion
function readString(value: unknown): string | undefined {
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
}
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: extensions/google/oauth.settings.ts
Line: 55-58

Comment:
**`GOOGLE_GENAI_USE_GCA=true` mapped to `"oauth-personal"` — please verify against actual Gemini CLI semantics**

The variable name `GOOGLE_GENAI_USE_GCA` reads as "Use Google Cloud Assist" (GCA = Code Assist / enterprise workspace path). In the broader Gemini CLI ecosystem this flag is typically associated with *enabling* the Code Assist / project-backed auth flow, not the personal OAuth flow — the opposite of what this mapping implies.

If the actual `@google/gemini-cli` treats `GOOGLE_GENAI_USE_GCA=true` as "use Code Assist / workspace auth", any workspace user who has this env var set will be incorrectly routed through `resolveGooglePersonalOAuthIdentity`, silently skipping `loadCodeAssist` and producing a `projectId`-less credential that will break downstream project-scoped API calls.

The settings-file path (reading `security.auth.selectedType === "oauth-personal"`) is unambiguous. This env-var shortcut should be verified against the Gemini CLI source or docs before merging. If the intent is to detect the *absence* of Code Assist (personal OAuth when the flag is not set), the condition and the test description should be inverted.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "Update CHANGELOG.md" | Re-trigger Greptile

Comment thread extensions/google/oauth.settings.ts
Comment thread extensions/google/oauth.settings.ts
@vincentkoc vincentkoc force-pushed the fix/gemini-cli-personal-oauth branch from 0aa0b2e to 43ae20e Compare April 5, 2026 09:11
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 43ae20ee3a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/google/oauth.settings.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ad15a7b1a6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/google/oauth.settings.ts
@vincentkoc vincentkoc force-pushed the fix/gemini-cli-personal-oauth branch from ad15a7b to 463de2a Compare April 5, 2026 10:11
@vincentkoc vincentkoc merged commit f02e435 into main Apr 5, 2026
9 checks passed
@vincentkoc vincentkoc deleted the fix/gemini-cli-personal-oauth branch April 5, 2026 10:12
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 463de2af23

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +61 to +64
readString(auth?.selectedType) ??
readString(auth?.enforcedType) ??
readString(settings.selectedAuthType) ??
readString(settings.enforcedAuthType);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Prioritize enforced auth mode over selected auth mode

resolveGeminiCliSelectedAuthType currently checks selectedType before enforcedType, so a config that contains both values can ignore the required enterprise override and route OAuth through the wrong identity path. When enforcedType differs from selectedType, this can incorrectly skip (or force) Code Assist project discovery and produce invalid onboarding behavior for managed accounts.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer Maintainer-authored PR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

google-gemini-cli-auth plugin fails for personal OAuth accounts

1 participant