feat: add opt-in chromium seatbelt extension

This commit is contained in:
viyatb-oai
2026-03-05 13:09:47 -08:00
parent 4907096d13
commit caacc39d9d
15 changed files with 85 additions and 3 deletions

View File

@@ -52,6 +52,12 @@
"null"
]
},
"chromiumMachPortRendezvous": {
"type": [
"boolean",
"null"
]
},
"preferences": {
"anyOf": [
{

View File

@@ -3689,6 +3689,12 @@
"null"
]
},
"chromium_mach_port_rendezvous": {
"type": [
"boolean",
"null"
]
},
"preferences": {
"anyOf": [
{

View File

@@ -52,6 +52,12 @@
"null"
]
},
"chromiumMachPortRendezvous": {
"type": [
"boolean",
"null"
]
},
"preferences": {
"anyOf": [
{

View File

@@ -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": [
{

View File

@@ -7252,6 +7252,12 @@
"null"
]
},
"chromium_mach_port_rendezvous": {
"type": [
"boolean",
"null"
]
},
"preferences": {
"anyOf": [
{

View File

@@ -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, };

View File

@@ -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, };

View File

@@ -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,
}
}
}

View File

@@ -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.

View File

@@ -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

View File

@@ -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]

View File

@@ -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());

View File

@@ -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()
})

View File

@@ -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,
}
)
);

View File

@@ -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)]