Skip to content

[Bug]: Stored OAuth credentials silently override explicit provider config #10950

Closed

Description

@timvw

Bug Description

Stored OAuth credentials in ~/.local/share/opencode/auth.json silently override explicit provider configuration in opencode.json, causing authentication failures when using custom provider endpoints (e.g., Azure Foundry).

Steps to Reproduce

  1. Log into OpenCode with Anthropic OAuth (Claude Code Max subscription):

    opencode auth login anthropic

    This stores OAuth credentials in ~/.local/share/opencode/auth.json

  2. Configure a custom Anthropic provider in ~/.config/opencode/opencode.json with Azure Foundry:

    {
      "provider": {
        "anthropic": {
          "options": {
            "baseURL": "https://{env:AZURE_RESOURCE_NAME}.services.ai.azure.com/anthropic",
            "apiKey": "{env:AZURE_OPENAI_API_KEY}"
          },
          "models": {
            "claude-sonnet-4-5": {
              "id": "claude-sonnet-4-5"
            }
          }
        }
      },
      "model": "anthropic/claude-sonnet-4-5"
    }
  3. Run OpenCode:

    opencode

Expected Behavior

OpenCode should use the explicit configuration from opencode.json (Azure Foundry endpoint + API key).

Actual Behavior

OpenCode ignores the explicit config and uses the stored OAuth credentials from auth.json, sending requests to Anthropic's API instead of Azure Foundry. This results in "Permission Denied" or "Resource Not Found" errors because:

  • The Azure API key is invalid for Anthropic's API
  • Or the Anthropic OAuth token is invalid for Azure's API

No warning or error message indicates that stored credentials are overriding the config.

Root Cause

Looking at packages/opencode/src/provider/provider.ts lines 823-832:

// load apikeys
for (const [providerID, provider] of Object.entries(await Auth.all())) {
  if (disabled.has(providerID)) continue
  if (provider.type === "api") {
    mergeProvider(providerID, {
      source: "api",
      key: provider.key,
    })
  }
}

The Auth.all() stored credentials are merged into the provider config after the user's explicit config is loaded, effectively overriding it.

Workaround

Manually remove stored credentials:

# Backup first
cp ~/.local/share/opencode/auth.json ~/.local/share/opencode/auth.json.backup

# Remove anthropic OAuth
cat ~/.local/share/opencode/auth.json | jq 'del(.anthropic)' > ~/.local/share/opencode/auth.json.tmp
mv ~/.local/share/opencode/auth.json.tmp ~/.local/share/opencode/auth.json

Proposed Solution

One of the following approaches:

  1. Prioritize explicit config: If a provider has explicit baseURL or apiKey in opencode.json, don't override with stored auth
  2. Add warning: Warn users when stored auth overrides explicit config
  3. Add config option: Allow users to specify "useStoredAuth": false in provider options
  4. Namespace providers: Allow custom provider names like "azure-anthropic" to avoid conflicts with stored auth

Environment

  • OpenCode version: 1.1.36
  • OS: macOS (Darwin 25.2.0)
  • Installation method: Homebrew

Impact

This makes it impossible to use custom provider endpoints (Azure Foundry, custom proxies, etc.) once OAuth credentials are stored, without manually editing auth.json.

Activity

  1. github-actions commented on Jan 28, 2026

    @github-actions
    Contributor

    This issue relates to several other authentication and provider configuration issues. While not exact duplicates, these may be related:

    Your issue specifically addresses how stored OAuth credentials override explicit provider configuration in opencode.json, which is a unique problem related to the config merge priority order.

  2. github-actions commented on Mar 30, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 90 days of no activity. If the issue is still relevant please open a new one.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions