Route MCP auth discovery through runtime HTTP clients (#35239)

## Why

MCP authentication checks need to use the same HTTP routing as the MCP
transport so servers reached through configured proxies can be discovered
reliably.

## What changed

- Resolve OAuth discovery and authentication status through each server's
  runtime HTTP client for both local and managed environments.
- Keep local discovery capped at five seconds while allowing explicit login
  requests to retain their requested timeout.
- Resolve refreshed MCP configuration and its runtime context from the same
  snapshot.

## Testing

- Cover OAuth discovery through an environment proxy and macOS system proxy
  resolution.
- Cover proxied MCP startup and runtime refresh with updated authorization
  headers.
- Verify capped and preserved OAuth discovery timeout policies.

GitOrigin-RevId: 461fb1d4786e547df8b1e6b2215a8ac40438a3aa
This commit is contained in:
Celia Chen authored and copyberry committed 2026-07-24 20:04:23 +00:00
1 parent 544007d006
commit 89a3b89c4c
9 files changed
+541 -49

No files matched your search

+25 -30
View File
@@ -10,8 +10,8 @@ use codex_config::types::OAuthCredentialsStoreMode;
use codex_exec_server::HttpClient;
use codex_login::CodexAuth;
use codex_rmcp_client::McpAuthState;
use codex_rmcp_client::OAuthDiscoveryTimeout;
use codex_rmcp_client::OAuthProviderError;
use codex_rmcp_client::determine_streamable_http_auth_status;
use codex_rmcp_client::determine_streamable_http_auth_status_with_http_client;
use codex_rmcp_client::discover_streamable_http_oauth;
use codex_rmcp_client::discover_streamable_http_oauth_with_http_client;
@@ -80,6 +80,7 @@ pub async fn oauth_login_support(transport: &McpServerTransportConfig) -> McpOAu
pub async fn oauth_login_support_with_http_client(
transport: &McpServerTransportConfig,
http_client: Arc<dyn HttpClient>,
discovery_timeout: OAuthDiscoveryTimeout,
) -> McpOAuthLoginSupport {
let Some(mut config) = oauth_login_candidate(transport) else {
return McpOAuthLoginSupport::Unsupported;
@@ -89,6 +90,7 @@ pub async fn oauth_login_support_with_http_client(
config.http_headers.clone(),
config.env_http_headers.clone(),
http_client,
discovery_timeout,
)
.await
{
@@ -134,8 +136,9 @@ pub async fn discover_supported_scopes(
pub async fn discover_supported_scopes_with_http_client(
transport: &McpServerTransportConfig,
http_client: Arc<dyn HttpClient>,
discovery_timeout: OAuthDiscoveryTimeout,
) -> Option<Vec<String>> {
match oauth_login_support_with_http_client(transport, http_client).await {
match oauth_login_support_with_http_client(transport, http_client, discovery_timeout).await {
McpOAuthLoginSupport::Supported(config) => config.discovered_scopes,
McpOAuthLoginSupport::Unsupported | McpOAuthLoginSupport::Unknown(_) => None,
}
@@ -255,35 +258,27 @@ async fn compute_auth_status(
http_headers,
env_http_headers,
} => {
if config.is_local_environment() {
determine_streamable_http_auth_status(
server_name,
url,
bearer_token_env_var.as_deref(),
http_headers.clone(),
env_http_headers.clone(),
store_mode,
keyring_backend_kind,
)
.boxed()
.await
let http_client = runtime_context
.resolve_http_client(server_name, config)
.map_err(anyhow::Error::msg)?;
let discovery_timeout = if config.is_local_environment() {
OAuthDiscoveryTimeout::LOCAL
} else {
let http_client = runtime_context
.resolve_http_client(server_name, config)
.map_err(anyhow::Error::msg)?;
determine_streamable_http_auth_status_with_http_client(
server_name,
url,
bearer_token_env_var.as_deref(),
http_headers.clone(),
env_http_headers.clone(),
store_mode,
keyring_backend_kind,
http_client,
)
.boxed()
.await
}
OAuthDiscoveryTimeout::Requested
};
determine_streamable_http_auth_status_with_http_client(
server_name,
url,
bearer_token_env_var.as_deref(),
http_headers.clone(),
env_http_headers.clone(),
store_mode,
keyring_backend_kind,
http_client,
discovery_timeout,
)
.boxed()
.await
}
}
}