From caacc39d9d2e27d0c1e11147f9b4b7746318e7cd Mon Sep 17 00:00:00 2001 From: viyatb-oai Date: Thu, 5 Mar 2026 13:09:47 -0800 Subject: [PATCH] feat: add opt-in chromium seatbelt extension --- ...CommandExecutionRequestApprovalParams.json | 6 +++++ .../schema/json/EventMsg.json | 6 +++++ .../schema/json/ServerRequest.json | 6 +++++ .../codex_app_server_protocol.schemas.json | 12 +++++++++ .../codex_app_server_protocol.v2.schemas.json | 6 +++++ .../schema/typescript/MacOsPermissions.ts | 2 +- .../v2/AdditionalMacOsPermissions.ts | 2 +- .../app-server-protocol/src/protocol/v2.rs | 2 ++ codex-rs/app-server/README.md | 2 +- codex-rs/core/README.md | 3 +++ codex-rs/core/src/seatbelt.rs | 3 +++ codex-rs/core/src/seatbelt_permissions.rs | 26 +++++++++++++++++++ codex-rs/core/src/skills/loader.rs | 4 +++ codex-rs/core/src/skills/permissions.rs | 5 ++++ codex-rs/protocol/src/models.rs | 3 +++ 15 files changed, 85 insertions(+), 3 deletions(-) diff --git a/codex-rs/app-server-protocol/schema/json/CommandExecutionRequestApprovalParams.json b/codex-rs/app-server-protocol/schema/json/CommandExecutionRequestApprovalParams.json index 891946fd94..7a00bfab2a 100644 --- a/codex-rs/app-server-protocol/schema/json/CommandExecutionRequestApprovalParams.json +++ b/codex-rs/app-server-protocol/schema/json/CommandExecutionRequestApprovalParams.json @@ -52,6 +52,12 @@ "null" ] }, + "chromiumMachPortRendezvous": { + "type": [ + "boolean", + "null" + ] + }, "preferences": { "anyOf": [ { diff --git a/codex-rs/app-server-protocol/schema/json/EventMsg.json b/codex-rs/app-server-protocol/schema/json/EventMsg.json index 526d852a2e..4221593348 100644 --- a/codex-rs/app-server-protocol/schema/json/EventMsg.json +++ b/codex-rs/app-server-protocol/schema/json/EventMsg.json @@ -3689,6 +3689,12 @@ "null" ] }, + "chromium_mach_port_rendezvous": { + "type": [ + "boolean", + "null" + ] + }, "preferences": { "anyOf": [ { diff --git a/codex-rs/app-server-protocol/schema/json/ServerRequest.json b/codex-rs/app-server-protocol/schema/json/ServerRequest.json index fce6ec6190..600552adff 100644 --- a/codex-rs/app-server-protocol/schema/json/ServerRequest.json +++ b/codex-rs/app-server-protocol/schema/json/ServerRequest.json @@ -52,6 +52,12 @@ "null" ] }, + "chromiumMachPortRendezvous": { + "type": [ + "boolean", + "null" + ] + }, "preferences": { "anyOf": [ { diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json index 86cbda2810..5d21c01426 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json @@ -48,6 +48,12 @@ "null" ] }, + "chromiumMachPortRendezvous": { + "type": [ + "boolean", + "null" + ] + }, "preferences": { "anyOf": [ { @@ -5138,6 +5144,12 @@ "null" ] }, + "chromium_mach_port_rendezvous": { + "type": [ + "boolean", + "null" + ] + }, "preferences": { "anyOf": [ { diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json index 3428205999..8a4a8a0189 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json @@ -7252,6 +7252,12 @@ "null" ] }, + "chromium_mach_port_rendezvous": { + "type": [ + "boolean", + "null" + ] + }, "preferences": { "anyOf": [ { diff --git a/codex-rs/app-server-protocol/schema/typescript/MacOsPermissions.ts b/codex-rs/app-server-protocol/schema/typescript/MacOsPermissions.ts index 5c0792412c..8af9bbda9a 100644 --- a/codex-rs/app-server-protocol/schema/typescript/MacOsPermissions.ts +++ b/codex-rs/app-server-protocol/schema/typescript/MacOsPermissions.ts @@ -4,4 +4,4 @@ import type { MacOsAutomationValue } from "./MacOsAutomationValue"; import type { MacOsPreferencesValue } from "./MacOsPreferencesValue"; -export type MacOsPermissions = { preferences: MacOsPreferencesValue | null, automations: MacOsAutomationValue | null, accessibility: boolean | null, calendar: boolean | null, }; +export type MacOsPermissions = { preferences: MacOsPreferencesValue | null, automations: MacOsAutomationValue | null, accessibility: boolean | null, calendar: boolean | null, chromium_mach_port_rendezvous: boolean | null, }; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/AdditionalMacOsPermissions.ts b/codex-rs/app-server-protocol/schema/typescript/v2/AdditionalMacOsPermissions.ts index eae1ad810c..dd0536b4f1 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/AdditionalMacOsPermissions.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/AdditionalMacOsPermissions.ts @@ -4,4 +4,4 @@ import type { MacOsAutomationValue } from "../MacOsAutomationValue"; import type { MacOsPreferencesValue } from "../MacOsPreferencesValue"; -export type AdditionalMacOsPermissions = { preferences: MacOsPreferencesValue | null, automations: MacOsAutomationValue | null, accessibility: boolean | null, calendar: boolean | null, }; +export type AdditionalMacOsPermissions = { preferences: MacOsPreferencesValue | null, automations: MacOsAutomationValue | null, accessibility: boolean | null, calendar: boolean | null, chromiumMachPortRendezvous: boolean | null, }; diff --git a/codex-rs/app-server-protocol/src/protocol/v2.rs b/codex-rs/app-server-protocol/src/protocol/v2.rs index 185d74fad4..def55035ba 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2.rs @@ -840,6 +840,7 @@ pub struct AdditionalMacOsPermissions { pub automations: Option, pub accessibility: Option, pub calendar: Option, + pub chromium_mach_port_rendezvous: Option, } impl From for AdditionalMacOsPermissions { @@ -849,6 +850,7 @@ impl From for AdditionalMacOsPermissions { automations: value.automations, accessibility: value.accessibility, calendar: value.calendar, + chromium_mach_port_rendezvous: value.chromium_mach_port_rendezvous, } } } diff --git a/codex-rs/app-server/README.md b/codex-rs/app-server/README.md index f7d7628761..20643620f4 100644 --- a/codex-rs/app-server/README.md +++ b/codex-rs/app-server/README.md @@ -742,7 +742,7 @@ Certain actions (shell commands or modifying files) may require explicit user ap Order of messages: 1. `item/started` — shows the pending `commandExecution` item with `command`, `cwd`, and other fields so you can render the proposed action. -2. `item/commandExecution/requestApproval` (request) — carries the same `itemId`, `threadId`, `turnId`, optionally `approvalId` (for subcommand callbacks), and `reason`. For normal command approvals, it also includes `command`, `cwd`, and `commandActions` for friendly display. When `initialize.params.capabilities.experimentalApi = true`, it may also include experimental `additionalPermissions` describing requested per-command sandbox access; any filesystem paths in that payload are absolute on the wire, and network access is represented as `additionalPermissions.network.enabled`. For network-only approvals, those command fields may be omitted and `networkApprovalContext` is provided instead. Optional persistence hints may also be included via `proposedExecpolicyAmendment` and `proposedNetworkPolicyAmendments`. Clients can prefer `availableDecisions` when present to render the exact set of choices the server wants to expose, while still falling back to the older heuristics if it is omitted. +2. `item/commandExecution/requestApproval` (request) — carries the same `itemId`, `threadId`, `turnId`, optionally `approvalId` (for subcommand callbacks), and `reason`. For normal command approvals, it also includes `command`, `cwd`, and `commandActions` for friendly display. When `initialize.params.capabilities.experimentalApi = true`, it may also include experimental `additionalPermissions` describing requested per-command sandbox access; any filesystem paths in that payload are absolute on the wire, network access is represented as `additionalPermissions.network.enabled`, and macOS-specific flags such as `additionalPermissions.macos.chromiumMachPortRendezvous` are exposed in camelCase. For network-only approvals, those command fields may be omitted and `networkApprovalContext` is provided instead. Optional persistence hints may also be included via `proposedExecpolicyAmendment` and `proposedNetworkPolicyAmendments`. Clients can prefer `availableDecisions` when present to render the exact set of choices the server wants to expose, while still falling back to the older heuristics if it is omitted. 3. Client response — for example `{ "decision": "accept" }`, `{ "decision": "acceptForSession" }`, `{ "decision": { "acceptWithExecpolicyAmendment": { "execpolicy_amendment": [...] } } }`, `{ "decision": { "applyNetworkPolicyAmendment": { "network_policy_amendment": { "host": "example.com", "action": "allow" } } } }`, `{ "decision": "decline" }`, or `{ "decision": "cancel" }`. 4. `serverRequest/resolved` — `{ threadId, requestId }` confirms the pending request has been resolved or cleared, including lifecycle cleanup on turn start/complete/interrupt. 5. `item/completed` — final `commandExecution` item with `status: "completed" | "failed" | "declined"` and execution output. Render this as the authoritative result. diff --git a/codex-rs/core/README.md b/codex-rs/core/README.md index 8a66b47b48..bf55d1c305 100644 --- a/codex-rs/core/README.md +++ b/codex-rs/core/README.md @@ -37,6 +37,9 @@ Seatbelt also supports macOS permission-profile extensions layered on top of enables `com.apple.axserver` mach lookup. - `macos_calendar = true`: enables `com.apple.CalendarAgent` mach lookup. +- `macos_chromium_mach_port_rendezvous = true`: + enables scoped Chromium Mach rendezvous `mach-register` and `mach-lookup` + permissions for `org.chromium.Chromium.MachPortRendezvousServer.*`. ### Linux diff --git a/codex-rs/core/src/seatbelt.rs b/codex-rs/core/src/seatbelt.rs index c9c2801209..67acd5395c 100644 --- a/codex-rs/core/src/seatbelt.rs +++ b/codex-rs/core/src/seatbelt.rs @@ -571,6 +571,7 @@ mod tests { ]), macos_accessibility: true, macos_calendar: true, + macos_chromium_mach_port_rendezvous: true, }), ); let policy = &args[1]; @@ -579,6 +580,8 @@ mod tests { assert!(policy.contains("(appleevent-destination \"com.apple.Notes\")")); assert!(policy.contains("com.apple.axserver")); assert!(policy.contains("com.apple.CalendarAgent")); + assert!(policy.contains("(allow mach-register")); + assert!(policy.contains("org.chromium.Chromium.MachPortRendezvousServer.")); } #[test] diff --git a/codex-rs/core/src/seatbelt_permissions.rs b/codex-rs/core/src/seatbelt_permissions.rs index 93bc0965aa..2da3c01e4e 100644 --- a/codex-rs/core/src/seatbelt_permissions.rs +++ b/codex-rs/core/src/seatbelt_permissions.rs @@ -103,6 +103,17 @@ pub(crate) fn build_seatbelt_extensions( clauses.push("(allow mach-lookup (global-name \"com.apple.CalendarAgent\"))".to_string()); } + if extensions.macos_chromium_mach_port_rendezvous { + clauses.push( + "(allow mach-register\n (global-name-prefix \"org.chromium.Chromium.MachPortRendezvousServer.\"))" + .to_string(), + ); + clauses.push( + "(allow mach-lookup\n (global-name-prefix \"org.chromium.Chromium.MachPortRendezvousServer.\"))" + .to_string(), + ); + } + if clauses.is_empty() { SeatbeltExtensionPolicy::default() } else { @@ -215,6 +226,21 @@ mod tests { assert!(policy.policy.contains("com.apple.CalendarAgent")); } + #[test] + fn chromium_rendezvous_emits_scoped_mach_rules() { + let policy = build_seatbelt_extensions(&MacOsSeatbeltProfileExtensions { + macos_chromium_mach_port_rendezvous: true, + ..Default::default() + }); + assert!(policy.policy.contains("(allow mach-register")); + assert!(policy.policy.contains("(allow mach-lookup")); + assert!( + policy + .policy + .contains("org.chromium.Chromium.MachPortRendezvousServer.") + ); + } + #[test] fn default_extensions_emit_preferences_read_only_policy() { let policy = build_seatbelt_extensions(&MacOsSeatbeltProfileExtensions::default()); diff --git a/codex-rs/core/src/skills/loader.rs b/codex-rs/core/src/skills/loader.rs index 751fa07200..5e770d5da0 100644 --- a/codex-rs/core/src/skills/loader.rs +++ b/codex-rs/core/src/skills/loader.rs @@ -1471,6 +1471,7 @@ permissions: - "com.apple.Notes" accessibility: true calendar: true + chromium_mach_port_rendezvous: true "#, ); @@ -1495,6 +1496,7 @@ permissions: )), accessibility: Some(true), calendar: Some(true), + chromium_mach_port_rendezvous: Some(true), }), ..Default::default() }) @@ -1518,6 +1520,7 @@ permissions: - "com.apple.Notes" accessibility: true calendar: true + chromium_mach_port_rendezvous: true "#, ); @@ -1542,6 +1545,7 @@ permissions: )), accessibility: Some(true), calendar: Some(true), + chromium_mach_port_rendezvous: Some(true), }), ..Default::default() }) diff --git a/codex-rs/core/src/skills/permissions.rs b/codex-rs/core/src/skills/permissions.rs index 53b1f7bd93..6a46590960 100644 --- a/codex-rs/core/src/skills/permissions.rs +++ b/codex-rs/core/src/skills/permissions.rs @@ -149,6 +149,9 @@ fn build_macos_seatbelt_profile_extensions( .accessibility .unwrap_or(defaults.macos_accessibility), macos_calendar: permissions.calendar.unwrap_or(defaults.macos_calendar), + macos_chromium_mach_port_rendezvous: permissions + .chromium_mach_port_rendezvous + .unwrap_or(defaults.macos_chromium_mach_port_rendezvous), }; Some(extensions) } @@ -414,6 +417,7 @@ mod tests { ])), accessibility: Some(true), calendar: Some(true), + chromium_mach_port_rendezvous: Some(true), }), ..Default::default() })) @@ -431,6 +435,7 @@ mod tests { ],), macos_accessibility: true, macos_calendar: true, + macos_chromium_mach_port_rendezvous: true, } ) ); diff --git a/codex-rs/protocol/src/models.rs b/codex-rs/protocol/src/models.rs index 90d9945b06..b749c764c3 100644 --- a/codex-rs/protocol/src/models.rs +++ b/codex-rs/protocol/src/models.rs @@ -73,6 +73,7 @@ pub struct MacOsPermissions { pub automations: Option, pub accessibility: Option, pub calendar: Option, + pub chromium_mach_port_rendezvous: Option, } impl MacOsPermissions { @@ -81,6 +82,7 @@ impl MacOsPermissions { && self.automations.is_none() && self.accessibility.is_none() && self.calendar.is_none() + && self.chromium_mach_port_rendezvous.is_none() } } @@ -133,6 +135,7 @@ pub struct MacOsSeatbeltProfileExtensions { pub macos_automation: MacOsAutomationPermission, pub macos_accessibility: bool, pub macos_calendar: bool, + pub macos_chromium_mach_port_rendezvous: bool, } #[derive(Debug, Clone, Default, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, TS)]