mirror of
https://github.com/openai/codex.git
synced 2026-09-16 12:13:30 +00:00
feat: add opt-in chromium seatbelt extension
This commit is contained in:
@@ -52,6 +52,12 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"chromiumMachPortRendezvous": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"preferences": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
||||
@@ -3689,6 +3689,12 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"chromium_mach_port_rendezvous": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"preferences": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
||||
@@ -52,6 +52,12 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"chromiumMachPortRendezvous": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"preferences": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
||||
@@ -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": [
|
||||
{
|
||||
|
||||
@@ -7252,6 +7252,12 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"chromium_mach_port_rendezvous": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"preferences": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
||||
@@ -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, };
|
||||
|
||||
@@ -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, };
|
||||
|
||||
@@ -840,6 +840,7 @@ pub struct AdditionalMacOsPermissions {
|
||||
pub automations: Option<CoreMacOsAutomationValue>,
|
||||
pub accessibility: Option<bool>,
|
||||
pub calendar: Option<bool>,
|
||||
pub chromium_mach_port_rendezvous: Option<bool>,
|
||||
}
|
||||
|
||||
impl From<CoreMacOsPermissions> for AdditionalMacOsPermissions {
|
||||
@@ -849,6 +850,7 @@ impl From<CoreMacOsPermissions> for AdditionalMacOsPermissions {
|
||||
automations: value.automations,
|
||||
accessibility: value.accessibility,
|
||||
calendar: value.calendar,
|
||||
chromium_mach_port_rendezvous: value.chromium_mach_port_rendezvous,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
@@ -73,6 +73,7 @@ pub struct MacOsPermissions {
|
||||
pub automations: Option<MacOsAutomationValue>,
|
||||
pub accessibility: Option<bool>,
|
||||
pub calendar: Option<bool>,
|
||||
pub chromium_mach_port_rendezvous: Option<bool>,
|
||||
}
|
||||
|
||||
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)]
|
||||
|
||||
Reference in New Issue
Block a user