mirror of
https://github.com/openai/codex.git
synced 2026-11-14 06:48:26 +00:00
Honor attachment-owned permissions for MCP servers (#40728)
## Why MCP servers attached to executor environments must retain their owner's permission profile instead of inheriting the thread-wide sandbox authority. ## What changed - Resolve and capture a permission profile for each enabled MCP server when publishing the runtime, and reject calls or elicitations when that authority is unavailable. - Use the captured server profile for tool approval decisions, elicitation, and sandbox metadata, including after runtime refreshes. - Materialize `:workspace_roots` from `PathUri` values so permissions preserve the path convention of remote executor environments. - Give threadless app discovery and resource reads an explicit default permission profile. ## Testing Added coverage for per-server elicitation authority, unresolved attachments, runtime refreshes, restricted tool calls, and foreign-platform workspace roots. GitOrigin-RevId: 6b188d4b08b29e9971ff7aa68a7785a0cdf9e394
This commit is contained in:
1 parent
0b94751cc4
commit
4213b38f3c
25 files changed
+805
-136
No files matched your search
@@ -178,6 +178,24 @@ impl Session {
|
||||
return;
|
||||
};
|
||||
loop {
|
||||
let environments = self.services.turn_environments.snapshot().await;
|
||||
let ready_environments = environments
|
||||
.turn_environments()
|
||||
.map(|environment| {
|
||||
(
|
||||
environment.selection.environment_id.clone(),
|
||||
Arc::clone(&environment.environment),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
// Attachment resolution can finish after the owner's configuration callback.
|
||||
if !self
|
||||
.services
|
||||
.mcp_runtime
|
||||
.current_environments_match(&ready_environments)
|
||||
{
|
||||
self.mark_mcp_runtime_dirty();
|
||||
}
|
||||
let auth = self.services.auth_manager.auth_cached();
|
||||
if !self
|
||||
.services
|
||||
@@ -232,9 +250,6 @@ impl Session {
|
||||
)
|
||||
.await;
|
||||
refresh_invalidation.published = true;
|
||||
if !self.mcp_refresh.is_pending() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -813,9 +828,14 @@ async fn review_guardian_mcp_elicitation(
|
||||
let approval_policy = mcp_config.approval_policy.value();
|
||||
match approval_policy {
|
||||
AskForApproval::Never => {
|
||||
let Some(permission_profile) =
|
||||
mcp_config.permission_profile_for_server(&request.server_name)
|
||||
else {
|
||||
return Ok(Some(mcp_elicitation_decline_without_message()));
|
||||
};
|
||||
if codex_mcp::mcp_permission_prompt_is_auto_approved(
|
||||
approval_policy,
|
||||
&mcp_config.permission_profile,
|
||||
permission_profile,
|
||||
codex_mcp::McpPermissionPromptAutoApproveContext::default(),
|
||||
) && matches!(
|
||||
&request.elicitation,
|
||||
|
||||
Reference in new issue
Block a user