Skip to content

Provide a way for auth to be handled through custom headers #87

Description

@melissa-barca

A user behind an enterprise gateway that authenticates on Authorization: Bearer <jwt> cannot connect a provider. customHeaders excludes five header names (packages/ai-provider-bridge/src/custom-headers.ts:5-11), two of which carry credentials: authorization and x-api-key. Setting either produces no error and no header on the wire.

The exclusion exists because the direct-SDK request path overwrites its own headers with a user's on collision: sending a user header and the built-in credential together would put two conflicting credentials on one request (memory-bank/architecture.md:239). Lifting the exclusion for these two names means resolving that conflict instead of leaving it unhandled.

Proposal

Accept authorization and x-api-key in customHeaders, and suppress the built-in credential for that request when the user supplies either, so exactly one credential goes out.

Leave accept, anthropic-version, and content-type excluded — they carry no credential and overriding them breaks protocol negotiation.

Design constraints

The exclusion currently lives in the bridge at request time, so a caller that calls fetch directly bypasses it. Move the name exclusion into ai-config, applied at catalog resolution, so every consumer of a resolved connection gets the same set, and delete the bridge's copy. Keep collision de-duplication per-request, since it needs the request's actual base headers, which don't exist at resolution time. Log when a header is excluded so a surface can tell the user it's never sent rather than silently omitting it.

The editing modal reads the raw user-layer entry byte-for-byte, so an excluded header stays visible and editable in providers.json without reaching a request.

For direct-SDK providers, the SDK applies its own headers after the ones it's given, so suppression has to happen when the client is constructed, not when headers merge. The OpenAI-compatible path merges headers itself and can suppress at merge time.

Gemini authenticates with its own API-key header name, which doesn't collide with authorization, so validation would send a configured authorization header while chat drops it unless filtering happens at resolution rather than only at the direct-SDK/OpenAI-compatible merge points.

Open questions

Enforced settings merge per key rather than replacing the map (packages/ai-config/src/enforce.ts:64-85), so user-supplied keys always survive and an empty enforced map is a no-op. Once a user can override the credential, a Workbench admin has no way to stop them overriding the one their deployment issues. This needs a decision before the change ships.

Whether to warn or fail when a user sets both an auth header and an API key for the same provider, rather than silently preferring one.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    positronaffects positron or will be worked on by Positron team (if added to Positron project board)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions