Track MCP enterprise auth cancellation across config reloads (#55287)

## Why

Configuration loading can finish before a pending startup is visible to the thread manager. Reloads need a cancellation scope that also covers these configuration snapshots.

## What changed

- Capture an enterprise managed authentication (EMA) cancellation token before loading configuration and carry it through config layers, role overrides, runtime refreshes, and `McpConfig`.
- Cancel the previous scope on MCP or user configuration reloads and cloud config loader changes, then create a fresh scope for subsequent loads.
- Cancel the session's token when enterprise MCP authentication is disabled or a refresh leaves it unavailable.

## Testing

Extend the MCP reload test to verify that existing thread and pending startup tokens are cancelled while a fresh startup receives an uncancelled token.

GitOrigin-RevId: 5fc0658b74c360e7dc9ab3488339fcf19bfe9fae
This commit is contained in:
jif
2026-10-19 14:07:10 +00:00
committed by copyberry
parent b1fd48c48e
commit cca40e57a4
12 changed files with 120 additions and 1 deletions
+1
View File
@@ -258,6 +258,7 @@ mod role_overrides {
config.config_layer_stack.requirements_toml().clone(),
)?
.with_cloud_config_binding(config.config_layer_stack.cloud_config_binding().cloned())
.with_mcp_ema_cancellation(config.config_layer_stack.mcp_ema_cancellation().clone())
.with_user_and_project_exec_policy_rules_ignored(
config
.config_layer_stack
+1
View File
@@ -1878,6 +1878,7 @@ impl Config {
requires_read_only_mcp_tools: false,
codex_home: self.codex_home.to_path_buf(),
mcp_enterprise_managed_auth: self.mcp_enterprise_managed_auth.clone(),
mcp_ema_cancellation: self.config_layer_stack.mcp_ema_cancellation().clone(),
xaa_enabled: self.features.enabled(Feature::UseXaa)
&& self.mcp_enterprise_managed_auth.is_some(),
mcp_oauth_credentials_store_mode: self.mcp_oauth_credentials_store_mode,
+2 -1
View File
@@ -166,7 +166,8 @@ impl Config {
if !matches!(scope, RuntimeConfigRefresh::Mcp) {
config.tool_suggest = resolve_tool_suggest_config_from_layer_stack(&layers);
}
config.config_layer_stack = layers;
config.config_layer_stack = layers
.with_mcp_ema_cancellation(self.config_layer_stack.mcp_ema_cancellation().clone());
config.plugins = cfg.plugins;
if enterprise_retired {
config.disable_mcp_enterprise_auth();
@@ -20,6 +20,7 @@ impl Session {
.original_config_do_not_use
.as_ref()
.clone();
config.config_layer_stack.mcp_ema_cancellation().cancel();
config.disable_mcp_enterprise_auth();
state.session_configuration.original_config_do_not_use = Arc::new(config);
self.services.mcp_runtime.invalidate_resource_caches();
@@ -160,6 +161,9 @@ impl Session {
}
let previous_config = notify_contributors
.then(|| self.build_effective_session_config(&state.session_configuration));
if config.mcp_enterprise_managed_auth.is_none() {
config.config_layer_stack.mcp_ema_cancellation().cancel();
}
state.session_configuration.original_config_do_not_use = Arc::clone(&config);
drop(policy_guard);
if matches!(scope, RuntimeConfigRefresh::Mcp) {