feat: Add additional macOS Sandbox Permissions for Launch Services, Contacts, Reminders (#14155)

Add additional macOS Sandbox Permissions levers for the following:

- Launch Services
- Contacts
- Reminders
This commit is contained in:
Leo Shimonaka
2026-03-10 16:34:47 -07:00
committed by Michael Bolin
Unverified
parent 8ac27b2a16
commit 889b4796fc
25 changed files with 779 additions and 25 deletions
@@ -39,15 +39,27 @@
"calendar": {
"type": "boolean"
},
"contacts": {
"$ref": "#/definitions/MacOsContactsPermission"
},
"launchServices": {
"type": "boolean"
},
"preferences": {
"$ref": "#/definitions/MacOsPreferencesPermission"
},
"reminders": {
"type": "boolean"
}
},
"required": [
"accessibility",
"automations",
"calendar",
"preferences"
"contacts",
"launchServices",
"preferences",
"reminders"
],
"type": "object"
},
@@ -324,6 +336,14 @@
}
]
},
"MacOsContactsPermission": {
"enum": [
"none",
"read_only",
"read_write"
],
"type": "string"
},
"MacOsPreferencesPermission": {
"enum": [
"none",
@@ -4044,6 +4044,14 @@
}
]
},
"MacOsContactsPermission": {
"enum": [
"none",
"read_only",
"read_write"
],
"type": "string"
},
"MacOsPreferencesPermission": {
"enum": [
"none",
@@ -4070,6 +4078,18 @@
"default": false,
"type": "boolean"
},
"macos_contacts": {
"allOf": [
{
"$ref": "#/definitions/MacOsContactsPermission"
}
],
"default": "none"
},
"macos_launch_services": {
"default": false,
"type": "boolean"
},
"macos_preferences": {
"allOf": [
{
@@ -4077,6 +4097,10 @@
}
],
"default": "read_only"
},
"macos_reminders": {
"default": false,
"type": "boolean"
}
},
"type": "object"
@@ -39,15 +39,27 @@
"calendar": {
"type": "boolean"
},
"contacts": {
"$ref": "#/definitions/MacOsContactsPermission"
},
"launchServices": {
"type": "boolean"
},
"preferences": {
"$ref": "#/definitions/MacOsPreferencesPermission"
},
"reminders": {
"type": "boolean"
}
},
"required": [
"accessibility",
"automations",
"calendar",
"preferences"
"contacts",
"launchServices",
"preferences",
"reminders"
],
"type": "object"
},
@@ -124,6 +136,14 @@
}
]
},
"MacOsContactsPermission": {
"enum": [
"none",
"read_only",
"read_write"
],
"type": "string"
},
"MacOsPreferencesPermission": {
"enum": [
"none",
@@ -63,6 +63,22 @@
"null"
]
},
"contacts": {
"anyOf": [
{
"$ref": "#/definitions/MacOsContactsPermission"
},
{
"type": "null"
}
]
},
"launchServices": {
"type": [
"boolean",
"null"
]
},
"preferences": {
"anyOf": [
{
@@ -72,6 +88,12 @@
"type": "null"
}
]
},
"reminders": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
@@ -138,6 +160,14 @@
}
]
},
"MacOsContactsPermission": {
"enum": [
"none",
"read_only",
"read_write"
],
"type": "string"
},
"MacOsPreferencesPermission": {
"enum": [
"none",
@@ -39,15 +39,27 @@
"calendar": {
"type": "boolean"
},
"contacts": {
"$ref": "#/definitions/MacOsContactsPermission"
},
"launchServices": {
"type": "boolean"
},
"preferences": {
"$ref": "#/definitions/MacOsPreferencesPermission"
},
"reminders": {
"type": "boolean"
}
},
"required": [
"accessibility",
"automations",
"calendar",
"preferences"
"contacts",
"launchServices",
"preferences",
"reminders"
],
"type": "object"
},
@@ -653,6 +665,14 @@
}
]
},
"MacOsContactsPermission": {
"enum": [
"none",
"read_only",
"read_write"
],
"type": "string"
},
"MacOsPreferencesPermission": {
"enum": [
"none",
@@ -35,15 +35,27 @@
"calendar": {
"type": "boolean"
},
"contacts": {
"$ref": "#/definitions/MacOsContactsPermission"
},
"launchServices": {
"type": "boolean"
},
"preferences": {
"$ref": "#/definitions/MacOsPreferencesPermission"
},
"reminders": {
"type": "boolean"
}
},
"required": [
"accessibility",
"automations",
"calendar",
"preferences"
"contacts",
"launchServices",
"preferences",
"reminders"
],
"type": "object"
},
@@ -5303,6 +5315,22 @@
"null"
]
},
"contacts": {
"anyOf": [
{
"$ref": "#/definitions/MacOsContactsPermission"
},
{
"type": "null"
}
]
},
"launchServices": {
"type": [
"boolean",
"null"
]
},
"preferences": {
"anyOf": [
{
@@ -5312,6 +5340,12 @@
"type": "null"
}
]
},
"reminders": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
@@ -5573,6 +5607,14 @@
}
]
},
"MacOsContactsPermission": {
"enum": [
"none",
"read_only",
"read_write"
],
"type": "string"
},
"MacOsPreferencesPermission": {
"enum": [
"none",
@@ -5599,6 +5641,18 @@
"default": false,
"type": "boolean"
},
"macos_contacts": {
"allOf": [
{
"$ref": "#/definitions/MacOsContactsPermission"
}
],
"default": "none"
},
"macos_launch_services": {
"default": false,
"type": "boolean"
},
"macos_preferences": {
"allOf": [
{
@@ -5606,6 +5660,10 @@
}
],
"default": "read_only"
},
"macos_reminders": {
"default": false,
"type": "boolean"
}
},
"type": "object"
@@ -8070,6 +8070,14 @@
}
]
},
"MacOsContactsPermission": {
"enum": [
"none",
"read_only",
"read_write"
],
"type": "string"
},
"MacOsPreferencesPermission": {
"enum": [
"none",
@@ -8096,6 +8104,18 @@
"default": false,
"type": "boolean"
},
"macos_contacts": {
"allOf": [
{
"$ref": "#/definitions/MacOsContactsPermission"
}
],
"default": "none"
},
"macos_launch_services": {
"default": false,
"type": "boolean"
},
"macos_preferences": {
"allOf": [
{
@@ -8103,6 +8123,10 @@
}
],
"default": "read_only"
},
"macos_reminders": {
"default": false,
"type": "boolean"
}
},
"type": "object"
@@ -0,0 +1,5 @@
// GENERATED CODE! DO NOT MODIFY BY HAND!
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type MacOsContactsPermission = "none" | "read_only" | "read_write";
@@ -2,6 +2,7 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { MacOsAutomationPermission } from "./MacOsAutomationPermission";
import type { MacOsContactsPermission } from "./MacOsContactsPermission";
import type { MacOsPreferencesPermission } from "./MacOsPreferencesPermission";
export type MacOsSeatbeltProfileExtensions = { macos_preferences: MacOsPreferencesPermission, macos_automation: MacOsAutomationPermission, macos_accessibility: boolean, macos_calendar: boolean, };
export type MacOsSeatbeltProfileExtensions = { macos_preferences: MacOsPreferencesPermission, macos_automation: MacOsAutomationPermission, macos_launch_services: boolean, macos_accessibility: boolean, macos_calendar: boolean, macos_reminders: boolean, macos_contacts: MacOsContactsPermission, };
@@ -112,6 +112,7 @@ export type { LocalShellAction } from "./LocalShellAction";
export type { LocalShellExecAction } from "./LocalShellExecAction";
export type { LocalShellStatus } from "./LocalShellStatus";
export type { MacOsAutomationPermission } from "./MacOsAutomationPermission";
export type { MacOsContactsPermission } from "./MacOsContactsPermission";
export type { MacOsPreferencesPermission } from "./MacOsPreferencesPermission";
export type { MacOsSeatbeltProfileExtensions } from "./MacOsSeatbeltProfileExtensions";
export type { McpAuthStatus } from "./McpAuthStatus";
@@ -2,6 +2,7 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { MacOsAutomationPermission } from "../MacOsAutomationPermission";
import type { MacOsContactsPermission } from "../MacOsContactsPermission";
import type { MacOsPreferencesPermission } from "../MacOsPreferencesPermission";
export type AdditionalMacOsPermissions = { preferences: MacOsPreferencesPermission, automations: MacOsAutomationPermission, accessibility: boolean, calendar: boolean, };
export type AdditionalMacOsPermissions = { preferences: MacOsPreferencesPermission, automations: MacOsAutomationPermission, launchServices: boolean, accessibility: boolean, calendar: boolean, reminders: boolean, contacts: MacOsContactsPermission, };
@@ -2,6 +2,7 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { MacOsAutomationPermission } from "../MacOsAutomationPermission";
import type { MacOsContactsPermission } from "../MacOsContactsPermission";
import type { MacOsPreferencesPermission } from "../MacOsPreferencesPermission";
export type GrantedMacOsPermissions = { preferences?: MacOsPreferencesPermission, automations?: MacOsAutomationPermission, accessibility?: boolean, calendar?: boolean, };
export type GrantedMacOsPermissions = { preferences?: MacOsPreferencesPermission, automations?: MacOsAutomationPermission, launchServices?: boolean, accessibility?: boolean, calendar?: boolean, reminders?: boolean, contacts?: MacOsContactsPermission, };
+141 -5
View File
@@ -31,6 +31,7 @@ use codex_protocol::mcp::ResourceTemplate as McpResourceTemplate;
use codex_protocol::mcp::Tool as McpTool;
use codex_protocol::models::FileSystemPermissions as CoreFileSystemPermissions;
use codex_protocol::models::MacOsAutomationPermission as CoreMacOsAutomationPermission;
use codex_protocol::models::MacOsContactsPermission as CoreMacOsContactsPermission;
use codex_protocol::models::MacOsPreferencesPermission as CoreMacOsPreferencesPermission;
use codex_protocol::models::MacOsSeatbeltProfileExtensions as CoreMacOsSeatbeltProfileExtensions;
use codex_protocol::models::MessagePhase;
@@ -973,8 +974,11 @@ impl From<AdditionalFileSystemPermissions> for CoreFileSystemPermissions {
pub struct AdditionalMacOsPermissions {
pub preferences: CoreMacOsPreferencesPermission,
pub automations: CoreMacOsAutomationPermission,
pub launch_services: bool,
pub accessibility: bool,
pub calendar: bool,
pub reminders: bool,
pub contacts: CoreMacOsContactsPermission,
}
impl From<CoreMacOsSeatbeltProfileExtensions> for AdditionalMacOsPermissions {
@@ -982,8 +986,11 @@ impl From<CoreMacOsSeatbeltProfileExtensions> for AdditionalMacOsPermissions {
Self {
preferences: value.macos_preferences,
automations: value.macos_automation,
launch_services: value.macos_launch_services,
accessibility: value.macos_accessibility,
calendar: value.macos_calendar,
reminders: value.macos_reminders,
contacts: value.macos_contacts,
}
}
}
@@ -993,8 +1000,11 @@ impl From<AdditionalMacOsPermissions> for CoreMacOsSeatbeltProfileExtensions {
Self {
macos_preferences: value.preferences,
macos_automation: value.automations,
macos_launch_services: value.launch_services,
macos_accessibility: value.accessibility,
macos_calendar: value.calendar,
macos_reminders: value.reminders,
macos_contacts: value.contacts,
}
}
}
@@ -1063,10 +1073,19 @@ pub struct GrantedMacOsPermissions {
pub automations: Option<CoreMacOsAutomationPermission>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
pub launch_services: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
pub accessibility: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
pub calendar: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
pub reminders: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
pub contacts: Option<CoreMacOsContactsPermission>,
}
impl From<GrantedMacOsPermissions> for CoreMacOsSeatbeltProfileExtensions {
@@ -1078,8 +1097,11 @@ impl From<GrantedMacOsPermissions> for CoreMacOsSeatbeltProfileExtensions {
macos_automation: value
.automations
.unwrap_or(CoreMacOsAutomationPermission::None),
macos_launch_services: value.launch_services.unwrap_or(false),
macos_accessibility: value.accessibility.unwrap_or(false),
macos_calendar: value.calendar.unwrap_or(false),
macos_reminders: value.reminders.unwrap_or(false),
macos_contacts: value.contacts.unwrap_or(CoreMacOsContactsPermission::None),
}
}
}
@@ -1104,8 +1126,11 @@ impl From<GrantedPermissionProfile> for CorePermissionProfile {
let macos = value.macos.and_then(|macos| {
if macos.preferences.is_none()
&& macos.automations.is_none()
&& macos.launch_services.is_none()
&& macos.accessibility.is_none()
&& macos.calendar.is_none()
&& macos.reminders.is_none()
&& macos.contacts.is_none()
{
None
} else {
@@ -5494,8 +5519,11 @@ mod tests {
"automations": {
"bundle_ids": ["com.apple.Notes"]
},
"launchServices": false,
"accessibility": false,
"calendar": false
"calendar": false,
"reminders": false,
"contacts": "read_only"
}
},
"skillMetadata": null,
@@ -5509,10 +5537,52 @@ mod tests {
params
.additional_permissions
.and_then(|permissions| permissions.macos)
.map(|macos| macos.automations),
Some(CoreMacOsAutomationPermission::BundleIds(vec![
"com.apple.Notes".to_string(),
]))
.map(|macos| (macos.automations, macos.launch_services, macos.contacts)),
Some((
CoreMacOsAutomationPermission::BundleIds(vec!["com.apple.Notes".to_string(),]),
false,
CoreMacOsContactsPermission::ReadOnly,
))
);
}
#[test]
fn command_execution_request_approval_accepts_macos_reminders_permission() {
let params = serde_json::from_value::<CommandExecutionRequestApprovalParams>(json!({
"threadId": "thr_123",
"turnId": "turn_123",
"itemId": "call_123",
"command": "cat file",
"cwd": "/tmp",
"commandActions": null,
"reason": null,
"networkApprovalContext": null,
"additionalPermissions": {
"network": null,
"fileSystem": null,
"macos": {
"preferences": "read_only",
"automations": "none",
"launchServices": false,
"accessibility": false,
"calendar": false,
"reminders": true,
"contacts": "none"
}
},
"skillMetadata": null,
"proposedExecpolicyAmendment": null,
"proposedNetworkPolicyAmendments": null,
"availableDecisions": null
}))
.expect("reminders permission should deserialize");
assert_eq!(
params
.additional_permissions
.and_then(|permissions| permissions.macos)
.map(|macos| macos.reminders),
Some(true)
);
}
@@ -5560,8 +5630,11 @@ mod tests {
Some(CoreMacOsSeatbeltProfileExtensions {
macos_preferences: CoreMacOsPreferencesPermission::ReadOnly,
macos_automation: CoreMacOsAutomationPermission::None,
macos_launch_services: false,
macos_accessibility: false,
macos_calendar: false,
macos_reminders: false,
macos_contacts: CoreMacOsContactsPermission::None,
}),
),
(
@@ -5581,8 +5654,29 @@ mod tests {
macos_automation: CoreMacOsAutomationPermission::BundleIds(vec![
"com.apple.Notes".to_string(),
]),
macos_launch_services: false,
macos_accessibility: false,
macos_calendar: false,
macos_reminders: false,
macos_contacts: CoreMacOsContactsPermission::None,
}),
),
(
json!({
"launchServices": true,
}),
Some(GrantedMacOsPermissions {
launch_services: Some(true),
..Default::default()
}),
Some(CoreMacOsSeatbeltProfileExtensions {
macos_preferences: CoreMacOsPreferencesPermission::None,
macos_automation: CoreMacOsAutomationPermission::None,
macos_launch_services: true,
macos_accessibility: false,
macos_calendar: false,
macos_reminders: false,
macos_contacts: CoreMacOsContactsPermission::None,
}),
),
(
@@ -5596,8 +5690,11 @@ mod tests {
Some(CoreMacOsSeatbeltProfileExtensions {
macos_preferences: CoreMacOsPreferencesPermission::None,
macos_automation: CoreMacOsAutomationPermission::None,
macos_launch_services: false,
macos_accessibility: true,
macos_calendar: false,
macos_reminders: false,
macos_contacts: CoreMacOsContactsPermission::None,
}),
),
(
@@ -5611,8 +5708,47 @@ mod tests {
Some(CoreMacOsSeatbeltProfileExtensions {
macos_preferences: CoreMacOsPreferencesPermission::None,
macos_automation: CoreMacOsAutomationPermission::None,
macos_launch_services: false,
macos_accessibility: false,
macos_calendar: true,
macos_reminders: false,
macos_contacts: CoreMacOsContactsPermission::None,
}),
),
(
json!({
"reminders": true,
}),
Some(GrantedMacOsPermissions {
reminders: Some(true),
..Default::default()
}),
Some(CoreMacOsSeatbeltProfileExtensions {
macos_preferences: CoreMacOsPreferencesPermission::None,
macos_automation: CoreMacOsAutomationPermission::None,
macos_launch_services: false,
macos_accessibility: false,
macos_calendar: false,
macos_reminders: true,
macos_contacts: CoreMacOsContactsPermission::None,
}),
),
(
json!({
"contacts": "read_only",
}),
Some(GrantedMacOsPermissions {
contacts: Some(CoreMacOsContactsPermission::ReadOnly),
..Default::default()
}),
Some(CoreMacOsSeatbeltProfileExtensions {
macos_preferences: CoreMacOsPreferencesPermission::None,
macos_automation: CoreMacOsAutomationPermission::None,
macos_launch_services: false,
macos_accessibility: false,
macos_calendar: false,
macos_reminders: false,
macos_contacts: CoreMacOsContactsPermission::ReadOnly,
}),
),
];