Skip to content

Conversation

@toastdriven
Copy link

Context

My situation is this:

  • I have a personal Claude Code Pro subscription, which is Oauth-ed (just like Claude Code the agent does).
  • My work uses Anthropic Claude Enterprise, with multiple API keys (one key for each client). Those are usually set in the config via provider.anthropic.options.apiKey.

Using fake "profiles" (individually managed custom config files), I'd like to be able to use opencode with either type.

Expected

When configured to use the Anthropic Claude provider, if an (enterprise) apiKey is provided, it should take precedence over the stored Oauth (Claude Code Pro) credentials. If not provided, opencode should use the Oauth credentials.

Actual

Because of the way the configurations merging happens, the Oauth credentials (from ~/.local/share/opencode/auth.json) always "win", and the manually set apiKey is ignored.

This means all usage, even when I provide an enterprise API key, always ends up pointed at my personal Claude Pro subscription.

Solution

If an apiKey is configured & present, assume the user knows better & skip the loading of the Oauth credentials.


Deeper Explanation of Setup/Situation

  • I'm simulating having different "profiles" (one-per-client + a personal) by creating a bunch of custom config files within ~/.config/opencode/my_profiles/<profile-name>.jsonc.
  • In the work-based config files, under the provider.anthropic.options.apiKey path, I supply {file:~/.secrets/<profile-name>.apikey}, with different key paths for each work config.
  • I then launch opencode with: OPENCODE_CONFIG=~/.config/opencode/my_profiles/<profile-name>.jsonc opencode.
  • (Assuming I've renamed/moved the ~/.local/share/opencode/auth.json away) This works great for all the different clients/keys... but because that file is gone, I can no longer use my personal subscription (e.g. OPENCODE_CONFIG=~/.config/opencode/my_profiles/personal.jsonc opencode).
  • (Assuming I move the ~/.local/share/opencode/auth.json back) My personal Claude Pro subscription is back, but now takes over everything, & the client API keys are never used.

This adds a small skip (non-specific to Anthropic/Claude) to the provider code, only if an apiKey is set/present. It includes a new passing test that demonstrates the behavior.

@toastdriven
Copy link
Author

toastdriven commented Dec 18, 2025

Also, this may help with (or completely) resolve #4291.

@rekram1-node
Copy link
Collaborator

/review

@github-actions
Copy link
Contributor

lgtm

@rekram1-node
Copy link
Collaborator

hm im not sure this is proper fix, ik it prolly works but doesnt this skip all plugins that have auth in them? ik some people pass custom fetch implementations to their providers and this skips loading the plugin altogether i think

@toastdriven
Copy link
Author

Ah, that's a good point. So from there, while still trying to solve this, I'd propose two options:

  1. Reorder the loading so that the plugins come first, before the apiKey. Not sure that this will work, but I will give it a try.
  2. Introduce a new configuration option. In looking through the schema, there only seems to be the top-level plugins, with nothing under the provider. So maybe:
    a. An explicit plugins list under provider or provider.options (might be painful to keep in-sync long-term?)
    b. A disabled_plugins list under provider or provider.options (just disabling the specific Oauth plugin opencode-anthropic-auth for this instance, while not blocking other plugins)
    c. An ignore_oauth setting covering this specific case.

Maybe there's a different approach I'm not seeing.

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.

2 participants