From 222e8924d58cef9b1d38afbc74e829b318c180db Mon Sep 17 00:00:00 2001 From: celia-oai Date: Wed, 27 May 2026 16:48:07 -0700 Subject: [PATCH] changes --- codex-rs/app-server/src/mcp_refresh.rs | 40 +++++++++++++++++++++ codex-rs/core/src/mcp_skill_dependencies.rs | 1 + codex-rs/core/src/session/mcp.rs | 32 ++++++++++++++--- codex-rs/core/src/session/mod.rs | 1 + codex-rs/core/src/session/tests.rs | 3 ++ codex-rs/protocol/src/protocol.rs | 1 + 6 files changed, 73 insertions(+), 5 deletions(-) diff --git a/codex-rs/app-server/src/mcp_refresh.rs b/codex-rs/app-server/src/mcp_refresh.rs index d11678ff5a..6d3d3d38c9 100644 --- a/codex-rs/app-server/src/mcp_refresh.rs +++ b/codex-rs/app-server/src/mcp_refresh.rs @@ -74,6 +74,8 @@ async fn build_refresh_config( config.mcp_oauth_credentials_store_mode, ) .map_err(io::Error::other)?, + auth_keyring_backend_kind: serde_json::to_value(config.auth_keyring_backend_kind()) + .map_err(io::Error::other)?, }) } @@ -108,6 +110,7 @@ mod tests { use codex_config::ThreadConfigLoadErrorCode; use codex_config::ThreadConfigLoader; use codex_config::ThreadConfigSource; + use codex_config::types::AuthKeyringBackendKind; use codex_core::config::ConfigOverrides; use codex_core::init_state_db; use codex_core::thread_store_from_config; @@ -145,6 +148,39 @@ mod tests { Ok(()) } + #[tokio::test] + async fn refresh_config_uses_latest_auth_keyring_backend() -> anyhow::Result<()> { + let (temp_dir, thread_manager, config_manager, _loader) = refresh_test_state().await?; + std::fs::write( + temp_dir.path().join(codex_config::CONFIG_TOML_FILE), + "[features]\nsecret_auth_storage = true\n", + )?; + + let mut good_thread = None; + for thread_id in thread_manager.list_thread_ids().await { + let thread = thread_manager.get_thread(thread_id).await?; + let thread_config = thread.config().await; + if thread_config.cwd.ends_with("good") { + good_thread = Some((thread, thread_config)); + break; + } + } + let (thread, thread_config) = good_thread.expect("good test thread should exist"); + + let refresh_config = + build_refresh_config(&thread_manager, &config_manager, thread_config).await?; + let backend = serde_json::from_value::( + refresh_config.auth_keyring_backend_kind, + )?; + + assert_eq!( + thread.config().await.auth_keyring_backend_kind(), + AuthKeyringBackendKind::Direct + ); + assert_eq!(backend, AuthKeyringBackendKind::Secrets); + Ok(()) + } + async fn refresh_test_state() -> anyhow::Result<( TempDir, Arc, @@ -156,6 +192,10 @@ mod tests { let bad_cwd = temp_dir.path().join("bad"); std::fs::create_dir_all(&good_cwd)?; std::fs::create_dir_all(&bad_cwd)?; + std::fs::write( + temp_dir.path().join(codex_config::CONFIG_TOML_FILE), + "[features]\nsecret_auth_storage = false\n", + )?; let initial_config_manager = ConfigManager::without_managed_config_for_tests(temp_dir.path().to_path_buf()); diff --git a/codex-rs/core/src/mcp_skill_dependencies.rs b/codex-rs/core/src/mcp_skill_dependencies.rs index b40952de0b..f1fec3e3d7 100644 --- a/codex-rs/core/src/mcp_skill_dependencies.rs +++ b/codex-rs/core/src/mcp_skill_dependencies.rs @@ -212,6 +212,7 @@ pub(crate) async fn maybe_install_mcp_dependencies( turn_context, refresh_servers, config.mcp_oauth_credentials_store_mode, + config.auth_keyring_backend_kind(), elicitation_reviewer, ) .await; diff --git a/codex-rs/core/src/session/mcp.rs b/codex-rs/core/src/session/mcp.rs index da967df900..ae3f8d69f5 100644 --- a/codex-rs/core/src/session/mcp.rs +++ b/codex-rs/core/src/session/mcp.rs @@ -285,6 +285,7 @@ impl Session { turn_context: &TurnContext, mcp_servers: HashMap, store_mode: OAuthCredentialsStoreMode, + keyring_backend_kind: AuthKeyringBackendKind, elicitation_reviewer: Option, ) { let auth = self.services.auth_manager.auth().await; @@ -303,7 +304,6 @@ impl Session { effective_mcp_servers_from_configured(mcp_servers, &mcp_config, auth.as_ref()); let host_owned_codex_apps_enabled = host_owned_codex_apps_enabled(&mcp_config, auth.as_ref()); - let keyring_backend_kind = config.auth_keyring_backend_kind(); let auth_statuses = compute_auth_statuses( mcp_servers.iter(), store_mode, @@ -372,6 +372,7 @@ impl Session { let McpServerRefreshConfig { mcp_servers, mcp_oauth_credentials_store_mode, + auth_keyring_backend_kind, } = refresh_config; let mcp_servers = @@ -391,9 +392,23 @@ impl Session { return; } }; + let keyring_backend_kind = + match serde_json::from_value::(auth_keyring_backend_kind) { + Ok(kind) => kind, + Err(err) => { + warn!("failed to parse MCP auth keyring backend refresh config: {err}"); + return; + } + }; - self.refresh_mcp_servers_inner(turn_context, mcp_servers, store_mode, elicitation_reviewer) - .await; + self.refresh_mcp_servers_inner( + turn_context, + mcp_servers, + store_mode, + keyring_backend_kind, + elicitation_reviewer, + ) + .await; } pub(crate) async fn refresh_mcp_servers_now( @@ -401,10 +416,17 @@ impl Session { turn_context: &TurnContext, mcp_servers: HashMap, store_mode: OAuthCredentialsStoreMode, + keyring_backend_kind: AuthKeyringBackendKind, elicitation_reviewer: Option, ) { - self.refresh_mcp_servers_inner(turn_context, mcp_servers, store_mode, elicitation_reviewer) - .await; + self.refresh_mcp_servers_inner( + turn_context, + mcp_servers, + store_mode, + keyring_backend_kind, + elicitation_reviewer, + ) + .await; } #[cfg(test)] diff --git a/codex-rs/core/src/session/mod.rs b/codex-rs/core/src/session/mod.rs index 8424ce216f..84ba3ab522 100644 --- a/codex-rs/core/src/session/mod.rs +++ b/codex-rs/core/src/session/mod.rs @@ -47,6 +47,7 @@ use codex_analytics::SubAgentThreadStartedInput; use codex_analytics::TurnCodexErrorFact; use codex_app_server_protocol::McpServerElicitationRequest; use codex_app_server_protocol::McpServerElicitationRequestParams; +use codex_config::types::AuthKeyringBackendKind; use codex_config::types::OAuthCredentialsStoreMode; use codex_exec_server::Environment; use codex_exec_server::EnvironmentManager; diff --git a/codex-rs/core/src/session/tests.rs b/codex-rs/core/src/session/tests.rs index 29de7ca662..61bbae7f50 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -7065,9 +7065,12 @@ async fn refresh_mcp_servers_is_deferred_until_next_turn() { let mcp_oauth_credentials_store_mode = serde_json::to_value(OAuthCredentialsStoreMode::Auto).expect("serialize store mode"); + let auth_keyring_backend_kind = + serde_json::to_value(AuthKeyringBackendKind::Secrets).expect("serialize keyring backend"); let refresh_config = McpServerRefreshConfig { mcp_servers: json!({}), mcp_oauth_credentials_store_mode, + auth_keyring_backend_kind, }; { let mut guard = session.pending_mcp_server_refresh_config.lock().await; diff --git a/codex-rs/protocol/src/protocol.rs b/codex-rs/protocol/src/protocol.rs index 01e664c734..ee3a6f691c 100644 --- a/codex-rs/protocol/src/protocol.rs +++ b/codex-rs/protocol/src/protocol.rs @@ -179,6 +179,7 @@ pub struct W3cTraceContext { pub struct McpServerRefreshConfig { pub mcp_servers: Value, pub mcp_oauth_credentials_store_mode: Value, + pub auth_keyring_backend_kind: Value, } #[derive(Debug, Clone, PartialEq)]