Gemini API key incorrectly marks Google Gemini OAuth as configured
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 19.9k
- Forks
- 2.3k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 30
Description
Summary
When GEMINI_API_KEY is configured but Gemini OAuth credentials are absent, the provider setup/login picker marks both Google Gemini (OAuth) and Gemini API (API key) as configured.
Logging out of Google Gemini OAuth successfully removes ~/.jcode/gemini_oauth.json, but the OAuth row remains configured as long as GEMINI_API_KEY is present. This makes it impossible to tell from the UI whether Code Assist OAuth is actually active, which matters because OAuth and Gemini Developer API access have different endpoints and terms.
Environment
- Jcode:
v0.76.0(bbef1f6a8) - OS: Windows x86_64
- Also reproduces in current
mastersource at8fc780b
Reproduction
- Configure
GEMINI_API_KEY. - Ensure native Gemini OAuth is absent:
~/.jcode/gemini_oauth.jsondoes not exist.- No trusted external Gemini OAuth source is enabled.
- Open the provider setup picker.
- Observe the rows for Google Gemini and Gemini API.
Alternative reproduction:
- Configure both Gemini OAuth and
GEMINI_API_KEY. - Log out of Google Gemini from Jcode.
- Reopen the provider setup picker.
Actual behavior
- Google Gemini | OAuth |
configured - Gemini API | API key |
configured jcode auth status --jsonreports the Gemini OAuth provider as available even though its credential source isnone.
The OAuth logout itself succeeds and removes ~/.jcode/gemini_oauth.json.
Expected behavior
With only GEMINI_API_KEY configured:
- Google Gemini | OAuth |
setup - Gemini API | API key |
configured
With only OAuth configured, the inverse should be shown. With both configured, both rows should be configured.
Root cause
crates/jcode-base/src/auth/mod.rs, in build_auth_status_uncached, combines the two authentication methods:
status.gemini = if gemini::has_api_key() {
AuthState::Available
} else {
token_state(gemini::load_tokens().map(|tokens| tokens.is_expired()))
};
The OAuth descriptor in crates/jcode-provider-metadata/src/catalog.rs uses that combined state:
pub const GEMINI_LOGIN_PROVIDER: LoginProviderDescriptor = LoginProviderDescriptor {
id: "gemini",
display_name: "Google Gemini",
auth_kind: LoginProviderAuthKind::OAuth,
auth_state_key: LoginProviderAuthStateKey::Gemini,
// ...
};
A separate GEMINI_API_LOGIN_PROVIDER already exists and checks the gemini-api OpenAI-compatible profile, so an API key can independently make that row configured.
Suggested fix
Keep provider runtime credential resolution separate from login-method status. The provider setup/account surfaces need method-specific state:
- Gemini OAuth state should be derived only from trusted OAuth tokens.
- Gemini API state should be derived only from
GEMINI_API_KEY/ thegemini-apiprofile. - If the native Gemini runtime intentionally supports both methods, split the status fields/keys, for example
GeminiOauthandGeminiApiKey, rather than using a combined state for the OAuth descriptor.
Regression tests
Cover all four combinations in the provider assessment/picker:
- Neither configured: both rows show setup.
- OAuth only: OAuth configured, API setup.
- API key only: OAuth setup, API configured.
- Both configured: both rows configured.
Also verify that logging out of OAuth while retaining GEMINI_API_KEY changes only the OAuth row to setup and does not remove or disable the API key.
Policy-sensitive distinction
This is more than a cosmetic status-label issue. Google's current Antigravity Terms of Service explicitly state that using third-party software, tools, or services to access Antigravity, for example OpenClaw with Antigravity OAuth, is a breach that may result in account suspension or termination. The Antigravity FAQ likewise explains why third-party tools such as Claude Code, OpenClaw, and OpenCode cannot use an Antigravity login:
This report is not requesting removal of the OAuth provider. Removing, deprecating, or relabeling it in light of the current Antigravity CLI/IDE policy is a separate product decision. However, Jcode should accurately distinguish the Google OAuth/Code Assist path from the sanctioned Gemini Developer API-key path so users can verify which credential and endpoint are configured and active. Maintainers may also want to confirm whether the exposed OAuth integration remains intended under the current Antigravity terms.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in crates/jcode-base/src/auth/mod.rs and inspect build_auth_status_uncached, then compare its Gemini state with the descriptors in crates/jcode-provider-metadata/src/catalog.rs. Trace the provider assessment and picker status, and add regression coverage for neither, OAuth-only, API-key-only, and both configured. Done means OAuth logout changes only the OAuth row to setup while the API row remains configured.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, authentication, cli, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100