Follow-up to #5466. That PR makes mergeForwardedHeaders fail loud when a passthroughHeaders name collides with a backend's static HeaderForward config (plaintext or secret). This issue covers the other half of the original Authorization footgun: a passthrough header whose canonical name is also managed by the backend's outgoing-auth strategy.
Problem
The transport chain runs header-forward (outer) → authRoundTripper (inner). The strategy's Authenticate calls Header.Set(...) and silently overwrites any forwarded value with the same name:
upstream_inject / token_exchange / aws_sts / obo → set Authorization
header_injection → sets its configured HeaderName
So forwarding Authorization (or a header_injection name) to such a backend is silently clobbered — no error, no warning.
The legitimate LiteLLM Zero Trust case is unaffected: those backends run the unauthenticated strategy, which manages no headers, so there is no collision.
Desired
Detect — at config validation or session creation — that a passthroughHeaders name collides with a header the backend's resolved outgoing strategy manages, and fail loud with a clear message. Same philosophy as the static-config collision check already in #5466.
Sketch
Add a way for a strategy to declare the header names it manages (e.g. ManagedHeaders() on the outgoing Strategy interface — header_injection returns its configured name; the bearer strategies return Authorization; unauthenticated returns none). Cross-check against cfg.PassthroughHeaders where the backend strategy is resolved.
Ref: #5466 discussion.
Follow-up to #5466. That PR makes
mergeForwardedHeadersfail loud when apassthroughHeadersname collides with a backend's staticHeaderForwardconfig (plaintext or secret). This issue covers the other half of the originalAuthorizationfootgun: a passthrough header whose canonical name is also managed by the backend's outgoing-auth strategy.Problem
The transport chain runs header-forward (outer) →
authRoundTripper(inner). The strategy'sAuthenticatecallsHeader.Set(...)and silently overwrites any forwarded value with the same name:upstream_inject/token_exchange/aws_sts/obo→ setAuthorizationheader_injection→ sets its configuredHeaderNameSo forwarding
Authorization(or aheader_injectionname) to such a backend is silently clobbered — no error, no warning.The legitimate LiteLLM Zero Trust case is unaffected: those backends run the
unauthenticatedstrategy, which manages no headers, so there is no collision.Desired
Detect — at config validation or session creation — that a
passthroughHeadersname collides with a header the backend's resolved outgoing strategy manages, and fail loud with a clear message. Same philosophy as the static-config collision check already in #5466.Sketch
Add a way for a strategy to declare the header names it manages (e.g.
ManagedHeaders()on the outgoingStrategyinterface —header_injectionreturns its configured name; the bearer strategies returnAuthorization;unauthenticatedreturns none). Cross-check againstcfg.PassthroughHeaderswhere the backend strategy is resolved.Ref: #5466 discussion.