This commit is contained in:
Khaled AbuShqear 2026-08-27 19:36:17 -05:00 committed by GitHub
commit bc56fe29d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 48 additions and 3 deletions

View file

@ -3638,12 +3638,25 @@ class MCPServerManager:
# arbitrary bearer upstream, so we keep the v2 spec and ignore the override for these; the
# REST tools preview supplies its not-yet-persisted token through the resolver
# (cred_provider), never this path.
#
# dcr_bridge is a different origin, not a caller override: for a client-forwarded-token
# server admitted through the gateway-DCR bridge, `_admit_dcr_bridge_delegate` has already
# opened the caller's signed envelope and injected the real upstream credential it sealed —
# `mcp_auth_header` here IS that unsealed credential, not an arbitrary bearer the caller
# attached. Keeping `spec` for PassthroughConfig in this case discards that credential and
# falls through to the v2 resolver's own passthrough headers, which the DCR caller has no
# way to populate (it only ever presents the one envelope bearer, which admission already
# strips before egress). So a dcr_bridge server always takes the v1 path here regardless of
# spec.config, same as the non-exempted modes above.
if (
spec is not None
and mcp_auth_header
and not isinstance(
spec.config,
(AuthorizationCodeConfig, IdJagConfig, PassthroughConfig, TokenExchangeConfig),
and (
server.is_dcr_bridge
or not isinstance(
spec.config,
(AuthorizationCodeConfig, IdJagConfig, PassthroughConfig, TokenExchangeConfig),
)
)
):
spec = None

View file

@ -76,3 +76,35 @@ async def test_mcp_server_config_auth_value_header_used(token_key):
emitted = next(client._resolved_auth.auth_flow(httpx.Request("POST", server.url)))
assert emitted.headers["Authorization"] == "Bearer example_token"
assert client.auth_type == MCPAuth.bearer_token
@pytest.mark.asyncio
async def test_dcr_bridge_oauth_delegate_uses_admission_injected_credential():
"""A dcr_bridge + oauth_delegate server's mcp_auth_header must not be discarded.
``_admit_dcr_bridge_delegate`` opens the caller's signed envelope during admission and
injects the real upstream credential it sealed as ``mcp_auth_header`` here -- it is not an
arbitrary caller-supplied override. oauth_delegate maps to PassthroughConfig in the v2
resolver (see outbound_credentials/adapter.py), which used to be exempted from the v1
override path regardless of origin, silently discarding this credential and leaving the
upstream MCP server with no Authorization header at all (regression: BerriAI/litellm#36358).
"""
server = MCPServer(
server_id="test-dcr-bridge-server",
name="Test DCR Bridge Server",
server_name="test_dcr_bridge_server",
alias="test_dcr_bridge",
url="https://internal-mcp-server.example.com/mcp",
transport=MCPTransport.http,
auth_type=MCPAuth.oauth_delegate,
dcr_bridge=True,
)
manager = MCPServerManager()
client = await manager._create_mcp_client(
server=server,
mcp_auth_header="Bearer unsealed_upstream_token",
)
assert client._mcp_auth_value == "Bearer unsealed_upstream_token"