mirror of
https://github.com/openai/codex.git
synced 2026-11-14 21:40:39 +00:00
Use runtime authentication for OpenAI MCP and app requests (#59749)
## What changed - Select fresh authentication for each HTTP operation on eligible OpenAI MCP connections while preserving the connection's credential source and account network policy. Stop redirects when requests carry runtime assertions. - Pass the owning thread's authentication and runtime context through app discovery, connector metadata, and trusted-access requests. Include the runtime authentication mode in MCP connection and tool-cache identities. - Give resumed actors analytics clients bound to their own authentication context, and serialize stored-credential reloads with token refresh while preserving host-provided credentials. ## Testing Add coverage for fresh request assertions, revoked account policies, redirect handling, resumed-actor isolation, and MCP uploads in dual-header and assertion-only modes. GitOrigin-RevId: f06900a6db61cd6cf53c3aa8075afeec4d5706d9
This commit is contained in:
@@ -915,6 +915,21 @@ impl ThreadManager {
|
||||
.map(|runtime| (runtime, config.runtime_auth_mode)))
|
||||
}
|
||||
|
||||
/// Initialize the selected thread owner's runtime, including after a feature enablement.
|
||||
pub fn runtime_auth_for_mcp_manager(
|
||||
&self,
|
||||
config: &Config,
|
||||
mcp_manager: &McpManager,
|
||||
) -> std::io::Result<Option<(Arc<RuntimeAuthManager>, codex_features::RuntimeAuthMode)>> {
|
||||
Ok(crate::runtime_auth::runtime_for_config(
|
||||
&mcp_manager.plugins_manager().runtime_auth_slot(),
|
||||
config,
|
||||
mcp_manager.auth_manager(),
|
||||
&self.state.installation_id,
|
||||
)
|
||||
.map(|runtime| (runtime, config.runtime_auth_mode)))
|
||||
}
|
||||
|
||||
pub fn skills_service(&self) -> Arc<HostSkillsService> {
|
||||
self.state.skills_service.clone()
|
||||
}
|
||||
@@ -2611,10 +2626,14 @@ impl ThreadManagerState {
|
||||
codex_sandboxing::WindowsSandboxProxySettingsMode::Reconcile
|
||||
};
|
||||
// A resumed actor and its descendants share an owner, not the harness default's credentials.
|
||||
let (runtime_auth, plugins_manager) = if Arc::ptr_eq(&auth_manager, &self.auth_manager) {
|
||||
let (runtime_auth, plugins_manager, analytics_events_client) = if Arc::ptr_eq(
|
||||
&auth_manager,
|
||||
&self.auth_manager,
|
||||
) {
|
||||
(
|
||||
inherited_runtime_auth.unwrap_or_else(|| Arc::clone(&self.runtime_auth)),
|
||||
Arc::clone(&self.plugins_manager),
|
||||
self.analytics_events_client.clone(),
|
||||
)
|
||||
} else {
|
||||
let threads = self.threads.read().await;
|
||||
@@ -2627,6 +2646,7 @@ impl ThreadManagerState {
|
||||
inherited_runtime_auth
|
||||
.unwrap_or_else(|| Arc::clone(&parent.session.services.runtime_auth)),
|
||||
Arc::clone(&parent.session.services.plugins_manager),
|
||||
Some(parent.session.services.analytics_events_client.clone()),
|
||||
)
|
||||
} else {
|
||||
let runtime_auth = inherited_runtime_auth.unwrap_or_default();
|
||||
@@ -2634,7 +2654,35 @@ impl ThreadManagerState {
|
||||
self.plugins_manager
|
||||
.for_auth_context(Arc::clone(&auth_manager), Arc::clone(&runtime_auth)),
|
||||
);
|
||||
(runtime_auth, plugins)
|
||||
let runtime_provider = config
|
||||
.features
|
||||
.enabled(Feature::RuntimeAgentInstances)
|
||||
.then(|| (Arc::clone(&runtime_auth), config.runtime_auth_mode));
|
||||
let analytics = self.analytics_events_client.as_ref().map(|client| {
|
||||
let api_key_headers = if codex_model_provider::provider_uses_first_party_auth_path(
|
||||
&config.model_provider,
|
||||
) {
|
||||
match config.model_provider.build_header_map() {
|
||||
Ok(headers) => headers,
|
||||
Err(error) => {
|
||||
tracing::warn!(%error, "failed to resolve analytics resource selectors");
|
||||
return codex_analytics::AnalyticsEventsClient::disabled();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
client.for_auth_context(
|
||||
Arc::clone(&auth_manager),
|
||||
config.chatgpt_base_url.clone(),
|
||||
runtime_provider,
|
||||
api_key_headers,
|
||||
)
|
||||
});
|
||||
if let Some(client) = &analytics {
|
||||
plugins.set_analytics_events_client(client.clone());
|
||||
}
|
||||
(runtime_auth, plugins, analytics)
|
||||
}
|
||||
};
|
||||
let mcp_manager = if Arc::ptr_eq(&plugins_manager, &self.plugins_manager) {
|
||||
@@ -2708,7 +2756,7 @@ impl ThreadManagerState {
|
||||
turn_extension_init,
|
||||
client_mcp_extensions,
|
||||
reserved_thread_id,
|
||||
analytics_events_client: self.analytics_events_client.clone(),
|
||||
analytics_events_client,
|
||||
image_store: Arc::clone(&self.image_store),
|
||||
thread_store: Arc::clone(&self.thread_store),
|
||||
attestation_provider: self.attestation_provider.clone(),
|
||||
|
||||
Reference in New Issue
Block a user