Support auth-less custom Anthropic providers via apiKeyOptional - #109
Merged
Merged
Conversation
Custom anthropic entries in providers.json can now declare apiKeyOptional: true for endpoints that need no API key (e.g. a localhost SSO-authenticating enterprise proxy): - ai-config: the field on the custom anthropic variant and the custom-fragment shape; ResolvedProvider carries the resolved policy (kind default OR authored value) with its provenance (kind-default | default | user | enforced); the catalog watcher classifies an auth-policy-only change as connectionChanged. - ai-credentials: resolveCustomAuthMapping() applies kind default OR entry value; the kind-level map stays for back-compat. A shape-guard assertion pins ai-config's mirrored kind defaults to the descriptors. - ai-provider-bridge: apiKey === "" is the canonical anonymous signal. Anthropic discovery proceeds keyless (only anthropic-version is sent); chat passes the SDK a non-empty sentinel (preventing ANTHROPIC_API_KEY fallback) and strips x-api-key/Authorization in fetch middleware before raw HTTP logging, so neither sentinel nor key reaches the wire or the logs.
This was referenced Sep 8, 2026
Open
The per-key mapped-type union absorbed `never` mismatch branches (`true | never` collapses to `true`, and `[never] extends [true]` passes), so the guard type-checked even when every mirrored default disagreed. Mismatch branches now produce `false`, so any divergence turns the union into `boolean` and fails the final assertion.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR lets a custom Anthropic provider in
providers.jsonbe used without an API key, via a new optionalapiKeyOptional: truefield. The motivating case is an endpoint that handles authentication itself — for example, a local enterprise proxy that injects SSO credentials — so asking the user for a key is unnecessary (reported in posit-dev/assistant-feedback#91).Custom OpenAI-compatible entries already worked this way. Custom Anthropic entries always required a key, which made this kind of proxy impossible to configure.
How it works
Deciding whether a key is required. A provider is key-optional if its provider type is inherently key-optional (as OpenAI-compatible already is) OR the individual entry sets
apiKeyOptional: true. Like otherproviders.jsonsettings, the field can come from the user's config file or from admin-managed default/enforced config, so an administrator can pin the policy fleet-wide.Each resolved catalog entry records both the effective policy and where it came from (built-in default, admin default, user config, or admin-enforced). Consumers need this to tell an overridable default apart from an enforced value, even when the two happen to be equal. Editing only this field in
providers.jsontriggers a live reload: the file watcher treats it as a connection change, so the provider is re-registered and its credentials are re-resolved without a restart.What "no key" means on the wire. When the policy is on, an empty API key string is the signal for "send no credentials":
anthropic-versionheader — no auth headers.ANTHROPIC_API_KEYenvironment variable when given an empty key. We hand the SDK a non-empty placeholder to prevent that, then strip bothx-api-keyandAuthorizationfrom the request before it is sent (and before raw HTTP logging captures it). Neither a real key nor the placeholder ever reaches the endpoint or the log files.Changes
providers.jsonschema: the custom Anthropic variant, and the admin default/enforced fragment shape, now acceptapiKeyOptional; the generated JSON schema is regenerated.Testing
ANTHROPIC_API_KEYset in the test process to prove it isn't inherited.This supports the auth-less custom provider feature in posit-dev/assistant; the companion Positron change (teaching the host's own provider management about the new field) is specced separately.