Skip to content

fix(providers): detect Anthropic OAuth credentials in provider status#591

Open
marcmantei wants to merge 1 commit into
spacedriveapp:mainfrom
marcmantei:fix/anthropic-oauth-provider-detection
Open

fix(providers): detect Anthropic OAuth credentials in provider status#591
marcmantei wants to merge 1 commit into
spacedriveapp:mainfrom
marcmantei:fix/anthropic-oauth-provider-detection

Conversation

@marcmantei
Copy link
Copy Markdown

Summary

  • The get_providers() endpoint only checks for ANTHROPIC_API_KEY env var or config file key to determine if Anthropic is available
  • It does not check for anthropic_oauth.json, causing the Settings UI to report Anthropic as "not configured" for OAuth users (Claude Pro/Max subscription)
  • This adds 3 lines to mirror the existing openai_oauth_configured pattern already in place for OpenAI

Minimal 3-line alternative to #430.

Changes

  • src/api/providers.rs: Check anthropic_oauth.json existence alongside API key checks

Test plan

  • Run spacebot auth login to authenticate via OAuth (no API key set)
  • Verify Settings page shows Anthropic as configured
  • Verify LLM calls work with OAuth token
  • Verify no regression when using API key auth

🤖 Generated with Claude Code
via Happy

The get_providers() endpoint only checks for ANTHROPIC_API_KEY env var
or config file key to determine if Anthropic is available. It does not
check for anthropic_oauth.json, causing the dashboard to report
Anthropic as "not configured" for users authenticating via OAuth
(Claude Pro/Max subscription).

This mirrors the existing pattern already used for OpenAI OAuth
detection via openai_oauth_configured.

Minimal alternative to spacedriveapp#430.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

Review Change Stack

Walkthrough

The change updates Anthropic provider availability detection in get_providers() to check for OAuth credentials on disk in addition to the existing ANTHROPIC_API_KEY environment variable check. This is applied consistently across both the config-based and fallback code paths.

Changes

Anthropic OAuth Configuration

Layer / File(s) Summary
Provider Detection Logic
src/api/providers.rs
The get_providers function computes anthropic_oauth_configured from the credentials file path and incorporates it to determine Anthropic provider availability in both the config-present and env-fallback branches, enabling the provider when either the API key or OAuth credentials exist.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • spacedriveapp/spacebot#197: Both PRs modify auth-related logic in src/api/providers.rs; this PR adds OAuth-credentials-on-disk check for Anthropic availability, while the retrieved PR threads is_auth_token through ProviderConfig and updates providers.rs to set is_auth_token for providers — they touch the same authentication/config handling.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: updating Anthropic provider detection to include OAuth credentials, which is the core fix in this changeset.
Description check ✅ Passed The description is directly related to the changeset, explaining why the change was needed (OAuth users seeing Anthropic as unconfigured) and what was modified to fix it.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/api/providers.rs (1)

1575-1616: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

delete_provider("anthropic") doesn't remove the OAuth credentials file — provider stays "configured" after deletion.

Now that get_providers returns anthropic: true whenever anthropic_oauth.json exists (line 377), a user who authenticates via OAuth and then removes the Anthropic provider through the Settings UI will find the provider is still shown as configured. The generic TOML-key removal path (lines 1600–1604) only removes anthropic_key from config.toml; it never touches the OAuth credentials file on disk.

The fix mirrors the existing "openai-chatgpt" branch (lines 1498–1514): handle "anthropic" specially before the generic path, remove the credentials file, and clear in-memory credentials if the llm_manager exposes a corresponding method.

🐛 Proposed fix
     if provider == "openai-chatgpt" {
         // ... existing block ...
     }

+    if provider == "anthropic" {
+        let instance_dir = (**state.instance_dir.load()).clone();
+        let cred_path = crate::auth::credentials_path(&instance_dir);
+        if cred_path.exists() {
+            tokio::fs::remove_file(&cred_path).await.map_err(|error| {
+                tracing::error!(%error, path = %cred_path.display(), "failed to remove Anthropic OAuth credentials");
+                StatusCode::INTERNAL_SERVER_ERROR
+            })?;
+        }
+        // Fall through to also remove the TOML key if present.
+    }
+
     // GitHub Copilot ...
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api/providers.rs` around lines 1575 - 1616, The provider removal path
only removes the TOML key via provider_toml_key but doesn't delete the Anthropic
OAuth file, so delete_provider("anthropic") leaves anthropic_oauth.json present
causing get_providers to still report anthropic:true; fix by handling the
"anthropic" provider specially before the generic TOML removal: detect provider
== "anthropic", remove the on-disk OAuth file (anthropic_oauth.json) if it
exists, and if the state.llm_manager exposes an in-memory clearing call (e.g., a
method analogous to the ChatGPT branch such as
clear_anthropic_oauth/clear_anthropic_credentials) invoke it to clear
credentials from memory, then return the same ProviderUpdateResponse success
flow instead of falling through to only removing the toml key.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/api/providers.rs`:
- Line 377: delete_provider currently only removes the TOML key for the
"anthropic" provider leaving its OAuth file (anthropic_oauth.json) on disk so
anthropic_oauth_configured remains true; add a dedicated branch in
delete_provider (mirror the "github-copilot" handling) that checks for provider
== "anthropic", calls crate::auth::credentials_path(&instance_dir).remove_file()
(or std::fs::remove_file) to delete the OAuth file, and clear any in-memory
Anthropic state so the provider is fully unconfigured; place this block before
the generic fallback removal to ensure the OAuth file is removed when deleting
"anthropic".

---

Outside diff comments:
In `@src/api/providers.rs`:
- Around line 1575-1616: The provider removal path only removes the TOML key via
provider_toml_key but doesn't delete the Anthropic OAuth file, so
delete_provider("anthropic") leaves anthropic_oauth.json present causing
get_providers to still report anthropic:true; fix by handling the "anthropic"
provider specially before the generic TOML removal: detect provider ==
"anthropic", remove the on-disk OAuth file (anthropic_oauth.json) if it exists,
and if the state.llm_manager exposes an in-memory clearing call (e.g., a method
analogous to the ChatGPT branch such as
clear_anthropic_oauth/clear_anthropic_credentials) invoke it to clear
credentials from memory, then return the same ProviderUpdateResponse success
flow instead of falling through to only removing the toml key.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4408824a-3626-490d-a558-ec7dcbc53f4e

📥 Commits

Reviewing files that changed from the base of the PR and between 21868af and 8908008.

📒 Files selected for processing (1)
  • src/api/providers.rs

Comment thread src/api/providers.rs
let instance_dir = (**state.instance_dir.load()).clone();
let secrets_store = state.secrets_store.load();
let openai_oauth_configured = crate::openai_auth::credentials_path(&instance_dir).exists();
let anthropic_oauth_configured = crate::auth::credentials_path(&instance_dir).exists();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm crate::auth::credentials_path exists and returns an Anthropic-specific path.
rg -n "fn credentials_path" --type rust -C 5

Repository: spacedriveapp/spacebot

Length of output: 1930


🏁 Script executed:

#!/bin/bash
# Search for delete_provider function and examine handling for anthropic and openai-chatgpt providers
rg -n "fn delete_provider" --type rust -A 150 | head -300

Repository: spacedriveapp/spacebot

Length of output: 9296


Add dedicated handler for Anthropic OAuth credentials deletion in delete_provider.

The Anthropic provider uses OAuth credentials stored in anthropic_oauth.json, similar to OpenAI's openai_chatgpt_oauth.json and GitHub Copilot's token file. When a user deletes the Anthropic provider, only the TOML key is removed (line ~1603). The OAuth credentials file remains on disk, causing anthropic_oauth_configured to stay true on subsequent get_providers calls. The provider will incorrectly show as still configured after deletion.

Add special handling for "anthropic" in delete_provider before the generic fallback (after line 1530, following the "github-copilot" pattern) to remove the OAuth file via crate::auth::credentials_path and clear in-memory state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api/providers.rs` at line 377, delete_provider currently only removes the
TOML key for the "anthropic" provider leaving its OAuth file
(anthropic_oauth.json) on disk so anthropic_oauth_configured remains true; add a
dedicated branch in delete_provider (mirror the "github-copilot" handling) that
checks for provider == "anthropic", calls
crate::auth::credentials_path(&instance_dir).remove_file() (or
std::fs::remove_file) to delete the OAuth file, and clear any in-memory
Anthropic state so the provider is fully unconfigured; place this block before
the generic fallback removal to ensure the OAuth file is removed when deleting
"anthropic".

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant