permissions: remove macOS seatbelt extension profiles (#15918)

## Why

`PermissionProfile` should only describe the per-command permissions we
still want to grant dynamically. Keeping
`MacOsSeatbeltProfileExtensions` in that surface forced extra macOS-only
approval, protocol, schema, and TUI branches for a capability we no
longer want to expose.

## What changed

- Removed the macOS-specific permission-profile types from
`codex-protocol`, the app-server v2 API, and the generated
schema/TypeScript artifacts.
- Deleted the core and sandboxing plumbing that threaded
`MacOsSeatbeltProfileExtensions` through execution requests and seatbelt
construction.
- Simplified macOS seatbelt generation so it always includes the fixed
read-only preferences allowlist instead of carrying a configurable
profile extension.
- Removed the macOS additional-permissions UI/docs/test coverage and
deleted the obsolete macOS permission modules.
- Tightened `request_permissions` intersection handling so explicitly
empty requested read lists are preserved only when that field was
actually granted, avoiding zero-grant responses being stored as active
permissions.
This commit is contained in:
Michael Bolin
2026-03-26 17:12:45 -07:00
committed by GitHub
parent 44d28f500f
commit e6e2999209
50 changed files with 148 additions and 2269 deletions

View File

@@ -160,7 +160,6 @@ async fn guardian_allows_shell_additional_permissions_requests_past_policy_valid
enabled: Some(true),
}),
file_system: None,
macos: None,
},
"justification": params.justification.clone(),
})
@@ -234,7 +233,7 @@ async fn guardian_allows_unified_exec_additional_permissions_requests_past_polic
assert_eq!(
output,
"missing `additional_permissions`; provide at least one of `network`, `file_system`, or `macos` when using `with_additional_permissions`"
"missing `additional_permissions`; provide at least one of `network` or `file_system` when using `with_additional_permissions`"
);
}

View File

@@ -4379,7 +4379,6 @@ fn test_precedence_fixture_with_o3_profile() -> std::io::Result<()> {
shell_environment_policy: ShellEnvironmentPolicy::default(),
windows_sandbox_mode: None,
windows_sandbox_private_desktop: true,
macos_seatbelt_profile_extensions: None,
},
approvals_reviewer: ApprovalsReviewer::User,
enforce_residency: Constrained::allow_any(None),
@@ -4522,7 +4521,6 @@ fn test_precedence_fixture_with_gpt3_profile() -> std::io::Result<()> {
shell_environment_policy: ShellEnvironmentPolicy::default(),
windows_sandbox_mode: None,
windows_sandbox_private_desktop: true,
macos_seatbelt_profile_extensions: None,
},
approvals_reviewer: ApprovalsReviewer::User,
enforce_residency: Constrained::allow_any(None),
@@ -4663,7 +4661,6 @@ fn test_precedence_fixture_with_zdr_profile() -> std::io::Result<()> {
shell_environment_policy: ShellEnvironmentPolicy::default(),
windows_sandbox_mode: None,
windows_sandbox_private_desktop: true,
macos_seatbelt_profile_extensions: None,
},
approvals_reviewer: ApprovalsReviewer::User,
enforce_residency: Constrained::allow_any(None),
@@ -4790,7 +4787,6 @@ fn test_precedence_fixture_with_gpt5_profile() -> std::io::Result<()> {
shell_environment_policy: ShellEnvironmentPolicy::default(),
windows_sandbox_mode: None,
windows_sandbox_private_desktop: true,
macos_seatbelt_profile_extensions: None,
},
approvals_reviewer: ApprovalsReviewer::User,
enforce_residency: Constrained::allow_any(None),

View File

@@ -78,7 +78,6 @@ use codex_protocol::config_types::WebSearchConfig;
use codex_protocol::config_types::WebSearchMode;
use codex_protocol::config_types::WebSearchToolConfig;
use codex_protocol::config_types::WindowsSandboxLevel;
use codex_protocol::models::MacOsSeatbeltProfileExtensions;
use codex_protocol::openai_models::ModelsResponse;
use codex_protocol::openai_models::ReasoningEffort;
use codex_protocol::permissions::FileSystemSandboxPolicy;
@@ -206,9 +205,6 @@ pub struct Permissions {
pub windows_sandbox_mode: Option<WindowsSandboxModeToml>,
/// Whether the final Windows sandboxed child should run on a private desktop.
pub windows_sandbox_private_desktop: bool,
/// Optional macOS seatbelt extension profile used to extend default
/// seatbelt permissions when running under seatbelt.
pub macos_seatbelt_profile_extensions: Option<MacOsSeatbeltProfileExtensions>,
}
/// Application configuration loaded from disk and merged with overrides.
@@ -2556,7 +2552,6 @@ impl Config {
shell_environment_policy,
windows_sandbox_mode,
windows_sandbox_private_desktop,
macos_seatbelt_profile_extensions: None,
},
approvals_reviewer,
enforce_residency: enforce_residency.value,

View File

@@ -292,8 +292,6 @@ pub fn build_exec_request(
enforce_managed_network,
network: network.as_ref(),
sandbox_policy_cwd: sandbox_cwd,
#[cfg(target_os = "macos")]
macos_seatbelt_profile_extensions: None,
codex_linux_sandbox_exe: codex_linux_sandbox_exe.as_ref(),
use_legacy_landlock,
windows_sandbox_level,

View File

@@ -828,6 +828,33 @@ fn unmatched_on_request_uses_split_filesystem_policy_for_escalation_prompts() {
);
}
#[tokio::test]
async fn exec_approval_requirement_prompts_for_inline_additional_permissions_under_on_request() {
assert_exec_approval_requirement_for_command(
ExecApprovalRequirementScenario {
policy_src: None,
command: vec![
"zsh".to_string(),
"-lc".to_string(),
"touch requested-dir/requested-but-unused.txt".to_string(),
],
approval_policy: AskForApproval::OnRequest,
sandbox_policy: SandboxPolicy::new_read_only_policy(),
file_system_sandbox_policy: read_only_file_system_sandbox_policy(),
sandbox_permissions: SandboxPermissions::WithAdditionalPermissions,
prefix_rule: None,
},
ExecApprovalRequirement::NeedsApproval {
reason: None,
proposed_execpolicy_amendment: Some(ExecPolicyAmendment::new(vec![
"touch".to_string(),
"requested-dir/requested-but-unused.txt".to_string(),
])),
},
)
.await;
}
#[tokio::test]
async fn exec_approval_requirement_rejects_unmatched_sandbox_escalation_when_granular_sandbox_is_disabled()
{

View File

@@ -9,7 +9,7 @@ use codex_network_proxy::NetworkProxy;
use codex_protocol::permissions::FileSystemSandboxPolicy;
use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_sandboxing::seatbelt::MACOS_PATH_TO_SEATBELT_EXECUTABLE;
use codex_sandboxing::seatbelt::create_seatbelt_command_args_for_policies_with_extensions;
use codex_sandboxing::seatbelt::create_seatbelt_command_args_for_policies;
use std::collections::HashMap;
use std::path::Path;
use std::path::PathBuf;
@@ -24,14 +24,13 @@ pub async fn spawn_command_under_seatbelt(
network: Option<&NetworkProxy>,
mut env: HashMap<String, String>,
) -> std::io::Result<Child> {
let args = create_seatbelt_command_args_for_policies_with_extensions(
let args = create_seatbelt_command_args_for_policies(
command,
&FileSystemSandboxPolicy::from_legacy_sandbox_policy(sandbox_policy, sandbox_policy_cwd),
NetworkSandboxPolicy::from(sandbox_policy),
sandbox_policy_cwd,
/*enforce_managed_network*/ false,
network,
/*extensions*/ None,
);
let arg0 = None;
env.insert(CODEX_SANDBOX_ENV_VAR.to_string(), "seatbelt".to_string());

View File

@@ -127,18 +127,14 @@ pub(crate) fn normalize_and_validate_additional_permissions(
}
let Some(additional_permissions) = additional_permissions else {
return Err(
"missing `additional_permissions`; provide at least one of `network`, `file_system`, or `macos` when using `with_additional_permissions`"
"missing `additional_permissions`; provide at least one of `network` or `file_system` when using `with_additional_permissions`"
.to_string(),
);
};
#[cfg(not(target_os = "macos"))]
if additional_permissions.macos.is_some() {
return Err("`additional_permissions.macos` is only supported on macOS".to_string());
}
let normalized = normalize_additional_permissions(additional_permissions)?;
if normalized.is_empty() {
return Err(
"`additional_permissions` must include at least one requested permission in `network`, `file_system`, or `macos`"
"`additional_permissions` must include at least one requested permission in `network` or `file_system`"
.to_string(),
);
}

View File

@@ -1068,8 +1068,6 @@ impl JsReplManager {
enforce_managed_network: has_managed_network_requirements,
network: None,
sandbox_policy_cwd: &turn.cwd,
#[cfg(target_os = "macos")]
macos_seatbelt_profile_extensions: None,
codex_linux_sandbox_exe: turn.codex_linux_sandbox_exe.as_ref(),
use_legacy_landlock: turn.features.use_legacy_landlock(),
windows_sandbox_level: turn.windows_sandbox_level,

View File

@@ -23,7 +23,6 @@ use codex_execpolicy::Policy;
use codex_execpolicy::RuleMatch;
use codex_features::Feature;
use codex_protocol::config_types::WindowsSandboxLevel;
use codex_protocol::models::MacOsSeatbeltProfileExtensions;
use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::FileSystemSandboxPolicy;
use codex_protocol::permissions::NetworkSandboxPolicy;
@@ -154,12 +153,6 @@ pub(super) async fn try_run_zsh_fork(
windows_sandbox_level,
arg0,
sandbox_policy_cwd: ctx.turn.cwd.to_path_buf(),
macos_seatbelt_profile_extensions: ctx
.turn
.config
.permissions
.macos_seatbelt_profile_extensions
.clone(),
codex_linux_sandbox_exe: ctx.turn.codex_linux_sandbox_exe.clone(),
use_legacy_landlock: ctx.turn.features.use_legacy_landlock(),
};
@@ -258,12 +251,6 @@ pub(crate) async fn prepare_unified_exec_zsh_fork(
windows_sandbox_level: exec_request.windows_sandbox_level,
arg0: exec_request.arg0.clone(),
sandbox_policy_cwd: ctx.turn.cwd.to_path_buf(),
macos_seatbelt_profile_extensions: ctx
.turn
.config
.permissions
.macos_seatbelt_profile_extensions
.clone(),
codex_linux_sandbox_exe: ctx.turn.codex_linux_sandbox_exe.clone(),
use_legacy_landlock: ctx.turn.features.use_legacy_landlock(),
};
@@ -359,7 +346,6 @@ impl CoreShellActionProvider {
file_system_sandbox_policy: &FileSystemSandboxPolicy,
network_sandbox_policy: NetworkSandboxPolicy,
additional_permissions: Option<&PermissionProfile>,
macos_seatbelt_profile_extensions: Option<&MacOsSeatbeltProfileExtensions>,
) -> EscalationExecution {
match sandbox_permissions {
SandboxPermissions::UseDefault => EscalationExecution::TurnDefault,
@@ -373,8 +359,6 @@ impl CoreShellActionProvider {
sandbox_policy: sandbox_policy.clone(),
file_system_sandbox_policy: file_system_sandbox_policy.clone(),
network_sandbox_policy,
macos_seatbelt_profile_extensions: macos_seatbelt_profile_extensions
.cloned(),
},
))
})
@@ -560,11 +544,6 @@ impl EscalationPolicy for CoreShellActionProvider {
&self.file_system_sandbox_policy,
self.network_sandbox_policy,
self.prompt_permissions.as_ref(),
self.turn
.config
.permissions
.macos_seatbelt_profile_extensions
.as_ref(),
),
};
self.process_decision(
@@ -687,8 +666,6 @@ struct CoreShellCommandExecutor {
windows_sandbox_level: WindowsSandboxLevel,
arg0: Option<String>,
sandbox_policy_cwd: PathBuf,
#[cfg_attr(not(target_os = "macos"), allow(dead_code))]
macos_seatbelt_profile_extensions: Option<MacOsSeatbeltProfileExtensions>,
codex_linux_sandbox_exe: Option<PathBuf>,
use_legacy_landlock: bool,
}
@@ -701,8 +678,6 @@ struct PrepareSandboxedExecParams<'a> {
file_system_sandbox_policy: &'a FileSystemSandboxPolicy,
network_sandbox_policy: NetworkSandboxPolicy,
additional_permissions: Option<PermissionProfile>,
#[cfg(target_os = "macos")]
macos_seatbelt_profile_extensions: Option<&'a MacOsSeatbeltProfileExtensions>,
}
#[async_trait::async_trait]
@@ -787,17 +762,12 @@ impl ShellCommandExecutor for CoreShellCommandExecutor {
file_system_sandbox_policy: &self.file_system_sandbox_policy,
network_sandbox_policy: self.network_sandbox_policy,
additional_permissions: None,
#[cfg(target_os = "macos")]
macos_seatbelt_profile_extensions: self
.macos_seatbelt_profile_extensions
.as_ref(),
})?
}
EscalationExecution::Permissions(EscalationPermissions::PermissionProfile(
permission_profile,
)) => {
// Merge additive permissions into the existing turn/request sandbox policy.
// On macOS, additional profile extensions are unioned with the turn defaults.
self.prepare_sandboxed_exec(PrepareSandboxedExecParams {
command,
workdir,
@@ -806,10 +776,6 @@ impl ShellCommandExecutor for CoreShellCommandExecutor {
file_system_sandbox_policy: &self.file_system_sandbox_policy,
network_sandbox_policy: self.network_sandbox_policy,
additional_permissions: Some(permission_profile),
#[cfg(target_os = "macos")]
macos_seatbelt_profile_extensions: self
.macos_seatbelt_profile_extensions
.as_ref(),
})?
}
EscalationExecution::Permissions(EscalationPermissions::Permissions(permissions)) => {
@@ -822,10 +788,6 @@ impl ShellCommandExecutor for CoreShellCommandExecutor {
file_system_sandbox_policy: &permissions.file_system_sandbox_policy,
network_sandbox_policy: permissions.network_sandbox_policy,
additional_permissions: None,
#[cfg(target_os = "macos")]
macos_seatbelt_profile_extensions: permissions
.macos_seatbelt_profile_extensions
.as_ref(),
})?
}
};
@@ -848,8 +810,6 @@ impl CoreShellCommandExecutor {
file_system_sandbox_policy,
network_sandbox_policy,
additional_permissions,
#[cfg(target_os = "macos")]
macos_seatbelt_profile_extensions,
} = params;
let (program, args) = command
.split_first()
@@ -882,8 +842,6 @@ impl CoreShellCommandExecutor {
enforce_managed_network: self.network.is_some(),
network: self.network.as_ref(),
sandbox_policy_cwd: &self.sandbox_policy_cwd,
#[cfg(target_os = "macos")]
macos_seatbelt_profile_extensions,
codex_linux_sandbox_exe: self.codex_linux_sandbox_exe.as_ref(),
use_legacy_landlock: self.use_legacy_landlock,
windows_sandbox_level: self.windows_sandbox_level,

View File

@@ -1,6 +1,4 @@
use super::CoreShellActionProvider;
#[cfg(target_os = "macos")]
use super::CoreShellCommandExecutor;
use super::InterceptedExecPolicyContext;
use super::ParsedShellCommand;
use super::commands_for_intercepted_exec_policy;
@@ -8,12 +6,6 @@ use super::evaluate_intercepted_exec_policy;
use super::extract_shell_script;
use super::join_program_and_argv;
use super::map_exec_result;
#[cfg(target_os = "macos")]
use crate::config::Constrained;
#[cfg(target_os = "macos")]
use crate::config::Permissions;
#[cfg(target_os = "macos")]
use crate::config::types::ShellEnvironmentPolicy;
use crate::protocol::AskForApproval;
use crate::protocol::GranularApprovalConfig;
use crate::protocol::ReadOnlyAccess;
@@ -23,11 +15,7 @@ use codex_execpolicy::Decision;
use codex_execpolicy::Evaluation;
use codex_execpolicy::PolicyParser;
use codex_execpolicy::RuleMatch;
#[cfg(target_os = "macos")]
use codex_protocol::config_types::WindowsSandboxLevel;
use codex_protocol::models::FileSystemPermissions;
use codex_protocol::models::MacOsPreferencesPermission;
use codex_protocol::models::MacOsSeatbeltProfileExtensions;
use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::FileSystemAccessMode;
use codex_protocol::permissions::FileSystemPath;
@@ -36,18 +24,12 @@ use codex_protocol::permissions::FileSystemSandboxPolicy;
use codex_protocol::permissions::FileSystemSpecialPath;
use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_sandboxing::SandboxType;
#[cfg(target_os = "macos")]
use codex_sandboxing::seatbelt::MACOS_PATH_TO_SEATBELT_EXECUTABLE;
use codex_shell_escalation::EscalationExecution;
use codex_shell_escalation::EscalationPermissions;
use codex_shell_escalation::ExecResult;
use codex_shell_escalation::Permissions as EscalatedPermissions;
#[cfg(target_os = "macos")]
use codex_shell_escalation::ShellCommandExecutor;
use codex_utils_absolute_path::AbsolutePathBuf;
use pretty_assertions::assert_eq;
#[cfg(target_os = "macos")]
use std::collections::HashMap;
use std::path::PathBuf;
use std::time::Duration;
@@ -76,11 +58,6 @@ fn read_only_file_system_sandbox_policy() -> FileSystemSandboxPolicy {
}])
}
#[cfg(target_os = "macos")]
fn unrestricted_file_system_sandbox_policy() -> FileSystemSandboxPolicy {
FileSystemSandboxPolicy::unrestricted()
}
#[test]
fn execve_prompt_rejection_keeps_prefix_rules_on_rules_flag() {
assert_eq!(
@@ -294,10 +271,6 @@ fn shell_request_escalation_execution_is_explicit() {
},
]);
let network_sandbox_policy = NetworkSandboxPolicy::Restricted;
let macos_seatbelt_profile_extensions = MacOsSeatbeltProfileExtensions {
macos_preferences: MacOsPreferencesPermission::ReadWrite,
..Default::default()
};
assert_eq!(
CoreShellActionProvider::shell_request_escalation_execution(
@@ -306,7 +279,6 @@ fn shell_request_escalation_execution_is_explicit() {
&file_system_sandbox_policy,
network_sandbox_policy,
None,
Some(&macos_seatbelt_profile_extensions),
),
EscalationExecution::TurnDefault,
);
@@ -317,7 +289,6 @@ fn shell_request_escalation_execution_is_explicit() {
&file_system_sandbox_policy,
network_sandbox_policy,
None,
Some(&macos_seatbelt_profile_extensions),
),
EscalationExecution::Unsandboxed,
);
@@ -328,14 +299,12 @@ fn shell_request_escalation_execution_is_explicit() {
&file_system_sandbox_policy,
network_sandbox_policy,
Some(&requested_permissions),
Some(&macos_seatbelt_profile_extensions),
),
EscalationExecution::Permissions(EscalationPermissions::Permissions(
EscalatedPermissions {
sandbox_policy,
file_system_sandbox_policy,
network_sandbox_policy,
macos_seatbelt_profile_extensions: Some(macos_seatbelt_profile_extensions),
},
)),
);
@@ -558,191 +527,3 @@ host_executable(name = "git", paths = ["{allowed_git_literal}"])
evaluation.decision
));
}
#[cfg(target_os = "macos")]
#[tokio::test]
async fn prepare_escalated_exec_turn_default_preserves_macos_seatbelt_extensions() {
let cwd = AbsolutePathBuf::from_absolute_path(std::env::temp_dir()).unwrap();
let executor = CoreShellCommandExecutor {
command: vec!["echo".to_string(), "ok".to_string()],
cwd: cwd.to_path_buf(),
env: HashMap::new(),
network: None,
sandbox: SandboxType::None,
sandbox_policy: SandboxPolicy::new_read_only_policy(),
file_system_sandbox_policy: read_only_file_system_sandbox_policy(),
network_sandbox_policy: NetworkSandboxPolicy::Restricted,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
arg0: None,
sandbox_policy_cwd: cwd.to_path_buf(),
macos_seatbelt_profile_extensions: Some(MacOsSeatbeltProfileExtensions {
macos_preferences: MacOsPreferencesPermission::ReadWrite,
..Default::default()
}),
codex_linux_sandbox_exe: None,
use_legacy_landlock: false,
};
let prepared = executor
.prepare_escalated_exec(
&AbsolutePathBuf::from_absolute_path("/bin/echo").unwrap(),
&["echo".to_string(), "ok".to_string()],
&cwd,
HashMap::new(),
EscalationExecution::TurnDefault,
)
.await
.unwrap();
assert_eq!(
prepared.command.first().map(String::as_str),
Some(MACOS_PATH_TO_SEATBELT_EXECUTABLE)
);
assert_eq!(prepared.command.get(1).map(String::as_str), Some("-p"));
assert!(
prepared
.command
.get(2)
.is_some_and(|policy| policy.contains("(allow user-preference-write)")),
"expected seatbelt policy to include macOS extension profile: {:?}",
prepared.command
);
}
#[cfg(target_os = "macos")]
#[tokio::test]
async fn prepare_escalated_exec_permissions_preserve_macos_seatbelt_extensions() {
let cwd = AbsolutePathBuf::from_absolute_path(std::env::temp_dir()).unwrap();
let executor = CoreShellCommandExecutor {
command: vec!["echo".to_string(), "ok".to_string()],
cwd: cwd.to_path_buf(),
env: HashMap::new(),
network: None,
sandbox: SandboxType::None,
sandbox_policy: SandboxPolicy::DangerFullAccess,
file_system_sandbox_policy: unrestricted_file_system_sandbox_policy(),
network_sandbox_policy: NetworkSandboxPolicy::Enabled,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
arg0: None,
sandbox_policy_cwd: cwd.to_path_buf(),
macos_seatbelt_profile_extensions: None,
codex_linux_sandbox_exe: None,
use_legacy_landlock: false,
};
let permissions = Permissions {
approval_policy: Constrained::allow_any(AskForApproval::Never),
sandbox_policy: Constrained::allow_any(SandboxPolicy::new_read_only_policy()),
file_system_sandbox_policy: read_only_file_system_sandbox_policy(),
network_sandbox_policy: codex_protocol::permissions::NetworkSandboxPolicy::Restricted,
network: None,
allow_login_shell: true,
shell_environment_policy: ShellEnvironmentPolicy::default(),
windows_sandbox_mode: None,
windows_sandbox_private_desktop: false,
macos_seatbelt_profile_extensions: Some(MacOsSeatbeltProfileExtensions {
macos_preferences: MacOsPreferencesPermission::ReadWrite,
..Default::default()
}),
};
let prepared = executor
.prepare_escalated_exec(
&AbsolutePathBuf::from_absolute_path("/bin/echo").unwrap(),
&["echo".to_string(), "ok".to_string()],
&cwd,
HashMap::new(),
EscalationExecution::Permissions(EscalationPermissions::Permissions(
EscalatedPermissions {
sandbox_policy: permissions.sandbox_policy.get().clone(),
file_system_sandbox_policy: permissions.file_system_sandbox_policy.clone(),
network_sandbox_policy: permissions.network_sandbox_policy,
macos_seatbelt_profile_extensions: permissions
.macos_seatbelt_profile_extensions
.clone(),
},
)),
)
.await
.unwrap();
assert_eq!(
prepared.command.first().map(String::as_str),
Some(MACOS_PATH_TO_SEATBELT_EXECUTABLE)
);
assert_eq!(prepared.command.get(1).map(String::as_str), Some("-p"));
assert!(
prepared
.command
.get(2)
.is_some_and(|policy| policy.contains("(allow user-preference-write)")),
"expected seatbelt policy to include macOS extension profile: {:?}",
prepared.command
);
}
#[cfg(target_os = "macos")]
#[tokio::test]
async fn prepare_escalated_exec_permission_profile_unions_turn_and_requested_macos_extensions() {
let cwd = AbsolutePathBuf::from_absolute_path(std::env::temp_dir()).unwrap();
let sandbox_policy = SandboxPolicy::new_read_only_policy();
let executor = CoreShellCommandExecutor {
command: vec!["echo".to_string(), "ok".to_string()],
cwd: cwd.to_path_buf(),
env: HashMap::new(),
network: None,
sandbox: SandboxType::None,
sandbox_policy: sandbox_policy.clone(),
file_system_sandbox_policy: read_only_file_system_sandbox_policy(),
network_sandbox_policy: NetworkSandboxPolicy::from(&sandbox_policy),
windows_sandbox_level: WindowsSandboxLevel::Disabled,
arg0: None,
sandbox_policy_cwd: cwd.to_path_buf(),
macos_seatbelt_profile_extensions: Some(MacOsSeatbeltProfileExtensions {
macos_preferences: MacOsPreferencesPermission::ReadOnly,
..Default::default()
}),
codex_linux_sandbox_exe: None,
use_legacy_landlock: false,
};
let prepared = executor
.prepare_escalated_exec(
&AbsolutePathBuf::from_absolute_path("/bin/echo").unwrap(),
&["echo".to_string(), "ok".to_string()],
&cwd,
HashMap::new(),
EscalationExecution::Permissions(EscalationPermissions::PermissionProfile(
PermissionProfile {
macos: Some(MacOsSeatbeltProfileExtensions {
macos_calendar: true,
macos_reminders: false,
..Default::default()
}),
..Default::default()
},
)),
)
.await
.unwrap();
let policy = prepared
.command
.get(2)
.expect("seatbelt policy should be present");
assert_eq!(
prepared.command.first().map(String::as_str),
Some(MACOS_PATH_TO_SEATBELT_EXECUTABLE)
);
assert_eq!(prepared.command.get(1).map(String::as_str), Some("-p"));
assert!(
policy.contains("(allow user-preference-read)"),
"expected turn macOS seatbelt extensions to be preserved: {:?}",
prepared.command
);
assert!(
policy.contains("(allow mach-lookup (global-name \"com.apple.CalendarAgent\"))"),
"expected requested macOS seatbelt extensions to be included: {:?}",
prepared.command
);
}

View File

@@ -348,8 +348,6 @@ impl<'a> SandboxAttempt<'a> {
enforce_managed_network: self.enforce_managed_network,
network,
sandbox_policy_cwd: self.sandbox_cwd,
#[cfg(target_os = "macos")]
macos_seatbelt_profile_extensions: None,
codex_linux_sandbox_exe: self.codex_linux_sandbox_exe,
use_legacy_landlock: self.use_legacy_landlock,
windows_sandbox_level: self.windows_sandbox_level,