Context
#109 added apiKeyOptional: true for custom Anthropic entries only. The anthropic-only scoping was deliberate — it's the only additional kind with wire-level anonymous support — but it introduces per-kind special cases that would disappear if the option were general:
schema.ts: the field is bolted onto the anthropic variant via .extend() instead of living in the shared customProviderVariantSchema factory; fragments may carry it for any kind but only anthropic survives merged validation.
resolve-catalog.ts: resolveAuthPolicies needs the entry.type === "anthropic" ? entry.apiKeyOptional : undefined conditional.
Generalizing would remove those, but most of #109's bulk is scoping-independent and stays: ResolvedCustomAuthPolicy + provenance resolution, the CUSTOM_KIND_API_KEY_OPTIONAL_DEFAULT mirror + shape guard, the watcher classification, and the wire-level client handling.
What generalizing requires
The per-kind work relocates rather than vanishes: each newly-supported kind needs its own anonymous-mode wire handling (the Anthropic sentinel/header-strip exists because the SDK falls back to ANTHROPIC_API_KEY; the OpenAI SDK has the same OPENAI_API_KEY fallback problem), plus wire-level tests proving no auth header or ambient env var leaks. Kinds already key-optional by default (openai-compatible, litellm, portkey) would treat the field as redundant-but-harmless.
Why do it
Not urgent — file for future consideration.
Context
#109 added
apiKeyOptional: truefor custom Anthropic entries only. The anthropic-only scoping was deliberate — it's the only additional kind with wire-level anonymous support — but it introduces per-kind special cases that would disappear if the option were general:schema.ts: the field is bolted onto the anthropic variant via.extend()instead of living in the sharedcustomProviderVariantSchemafactory; fragments may carry it for any kind but only anthropic survives merged validation.resolve-catalog.ts:resolveAuthPoliciesneeds theentry.type === "anthropic" ? entry.apiKeyOptional : undefinedconditional.Generalizing would remove those, but most of #109's bulk is scoping-independent and stays:
ResolvedCustomAuthPolicy+ provenance resolution, theCUSTOM_KIND_API_KEY_OPTIONAL_DEFAULTmirror + shape guard, the watcher classification, and the wire-level client handling.What generalizing requires
The per-kind work relocates rather than vanishes: each newly-supported kind needs its own anonymous-mode wire handling (the Anthropic sentinel/header-strip exists because the SDK falls back to
ANTHROPIC_API_KEY; the OpenAI SDK has the sameOPENAI_API_KEYfallback problem), plus wire-level tests proving no auth header or ambient env var leaks. Kinds already key-optional by default (openai-compatible,litellm,portkey) would treat the field as redundant-but-harmless.Why do it
apiKeyOptionalon built-in providers (built-inanthropic/openai/geminipointed at a pre-authenticated corporate gateway). The layered-config provenance machinery from Support auth-less custom Anthropic providers via apiKeyOptional #109 already generalizes; the remaining work is per-protocol wire behavior and UI surfaces accepting a blank key.Not urgent — file for future consideration.