mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
cli: add macOS seatbelt debug flags for Mach services and Apple events
This commit is contained in:
@@ -49,6 +49,9 @@ pub async fn run_command_under_seatbelt(
|
||||
config_profile: _,
|
||||
cwd,
|
||||
include_managed_config,
|
||||
allow_mach_services,
|
||||
allow_appleevent_bundle_ids,
|
||||
allow_lsopen,
|
||||
allow_unix_sockets,
|
||||
log_denials,
|
||||
config_overrides,
|
||||
@@ -58,8 +61,8 @@ pub async fn run_command_under_seatbelt(
|
||||
&permissions_profile,
|
||||
include_managed_config,
|
||||
);
|
||||
run_command_under_sandbox(
|
||||
DebugSandboxConfigOptions {
|
||||
run_command_under_sandbox(RunCommandUnderSandboxParams {
|
||||
config_options: DebugSandboxConfigOptions {
|
||||
permissions_profile,
|
||||
cwd,
|
||||
managed_requirements_mode,
|
||||
@@ -68,10 +71,13 @@ pub async fn run_command_under_seatbelt(
|
||||
command,
|
||||
config_overrides,
|
||||
codex_linux_sandbox_exe,
|
||||
SandboxType::Seatbelt,
|
||||
sandbox_type: SandboxType::Seatbelt,
|
||||
log_denials,
|
||||
&allow_unix_sockets,
|
||||
)
|
||||
allow_mach_services: &allow_mach_services,
|
||||
allow_appleevent_bundle_ids: &allow_appleevent_bundle_ids,
|
||||
allow_lsopen,
|
||||
allow_unix_sockets: &allow_unix_sockets,
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -101,8 +107,8 @@ pub async fn run_command_under_landlock(
|
||||
&permissions_profile,
|
||||
include_managed_config,
|
||||
);
|
||||
run_command_under_sandbox(
|
||||
DebugSandboxConfigOptions {
|
||||
run_command_under_sandbox(RunCommandUnderSandboxParams {
|
||||
config_options: DebugSandboxConfigOptions {
|
||||
permissions_profile,
|
||||
cwd,
|
||||
managed_requirements_mode,
|
||||
@@ -111,10 +117,13 @@ pub async fn run_command_under_landlock(
|
||||
command,
|
||||
config_overrides,
|
||||
codex_linux_sandbox_exe,
|
||||
SandboxType::Landlock,
|
||||
/*log_denials*/ false,
|
||||
&[],
|
||||
)
|
||||
sandbox_type: SandboxType::Landlock,
|
||||
log_denials: false,
|
||||
allow_mach_services: &[],
|
||||
allow_appleevent_bundle_ids: &[],
|
||||
allow_lsopen: false,
|
||||
allow_unix_sockets: &[],
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -135,8 +144,8 @@ pub async fn run_command_under_windows_sandbox(
|
||||
&permissions_profile,
|
||||
include_managed_config,
|
||||
);
|
||||
run_command_under_sandbox(
|
||||
DebugSandboxConfigOptions {
|
||||
run_command_under_sandbox(RunCommandUnderSandboxParams {
|
||||
config_options: DebugSandboxConfigOptions {
|
||||
permissions_profile,
|
||||
cwd,
|
||||
managed_requirements_mode,
|
||||
@@ -145,10 +154,13 @@ pub async fn run_command_under_windows_sandbox(
|
||||
command,
|
||||
config_overrides,
|
||||
codex_linux_sandbox_exe,
|
||||
SandboxType::Windows,
|
||||
/*log_denials*/ false,
|
||||
&[],
|
||||
)
|
||||
sandbox_type: SandboxType::Windows,
|
||||
log_denials: false,
|
||||
allow_mach_services: &[],
|
||||
allow_appleevent_bundle_ids: &[],
|
||||
allow_lsopen: false,
|
||||
allow_unix_sockets: &[],
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -186,16 +198,43 @@ impl ManagedRequirementsMode {
|
||||
}
|
||||
}
|
||||
|
||||
async fn run_command_under_sandbox(
|
||||
struct RunCommandUnderSandboxParams<'a> {
|
||||
config_options: DebugSandboxConfigOptions,
|
||||
command: Vec<String>,
|
||||
config_overrides: CliConfigOverrides,
|
||||
codex_linux_sandbox_exe: Option<PathBuf>,
|
||||
sandbox_type: SandboxType,
|
||||
log_denials: bool,
|
||||
#[cfg_attr(not(target_os = "macos"), allow(unused_variables))]
|
||||
allow_unix_sockets: &[AbsolutePathBuf],
|
||||
) -> anyhow::Result<()> {
|
||||
#[cfg_attr(not(target_os = "macos"), allow(dead_code))]
|
||||
allow_mach_services: &'a [String],
|
||||
#[cfg_attr(not(target_os = "macos"), allow(dead_code))]
|
||||
allow_appleevent_bundle_ids: &'a [String],
|
||||
#[cfg_attr(not(target_os = "macos"), allow(dead_code))]
|
||||
allow_lsopen: bool,
|
||||
#[cfg_attr(not(target_os = "macos"), allow(dead_code))]
|
||||
allow_unix_sockets: &'a [AbsolutePathBuf],
|
||||
}
|
||||
|
||||
async fn run_command_under_sandbox(params: RunCommandUnderSandboxParams<'_>) -> anyhow::Result<()> {
|
||||
let RunCommandUnderSandboxParams {
|
||||
config_options,
|
||||
command,
|
||||
config_overrides,
|
||||
codex_linux_sandbox_exe,
|
||||
sandbox_type,
|
||||
log_denials,
|
||||
allow_mach_services,
|
||||
allow_appleevent_bundle_ids,
|
||||
allow_lsopen,
|
||||
allow_unix_sockets,
|
||||
} = params;
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
let _ = (
|
||||
allow_mach_services,
|
||||
allow_appleevent_bundle_ids,
|
||||
allow_lsopen,
|
||||
allow_unix_sockets,
|
||||
);
|
||||
let config = load_debug_sandbox_config(
|
||||
config_overrides
|
||||
.parse_overrides()
|
||||
@@ -280,6 +319,9 @@ async fn run_command_under_sandbox(
|
||||
sandbox_policy_cwd: sandbox_policy_cwd.as_path(),
|
||||
enforce_managed_network: false,
|
||||
network: network.as_ref(),
|
||||
extra_mach_services: allow_mach_services,
|
||||
extra_appleevent_bundle_ids: allow_appleevent_bundle_ids,
|
||||
allow_lsopen,
|
||||
extra_allow_unix_sockets: allow_unix_sockets,
|
||||
});
|
||||
spawn_debug_sandbox_child(
|
||||
|
||||
@@ -50,6 +50,18 @@ pub struct SeatbeltCommand {
|
||||
)]
|
||||
pub include_managed_config: bool,
|
||||
|
||||
/// Allow the sandboxed command to look up this Mach service name. Repeat to allow multiple services.
|
||||
#[arg(long = "allow-mach-service", value_name = "SERVICE", value_parser = parse_non_empty_string)]
|
||||
pub allow_mach_services: Vec<String>,
|
||||
|
||||
/// Allow the sandboxed command to send AppleEvents to this destination bundle ID. Repeat to allow multiple destinations.
|
||||
#[arg(long = "allow-appleevent-destination", value_name = "BUNDLE_ID", value_parser = parse_non_empty_string)]
|
||||
pub allow_appleevent_bundle_ids: Vec<String>,
|
||||
|
||||
/// Allow the sandboxed command to use LaunchServices open APIs.
|
||||
#[arg(long = "allow-lsopen", default_value_t = false)]
|
||||
pub allow_lsopen: bool,
|
||||
|
||||
/// Allow the sandboxed command to bind/connect AF_UNIX sockets rooted at this path. Relative paths are resolved against the current directory. Repeat to allow multiple paths.
|
||||
#[arg(long = "allow-unix-socket", value_parser = parse_allow_unix_socket_path)]
|
||||
pub allow_unix_sockets: Vec<AbsolutePathBuf>,
|
||||
@@ -71,6 +83,15 @@ fn parse_allow_unix_socket_path(raw: &str) -> Result<AbsolutePathBuf, String> {
|
||||
.map_err(|err| format!("invalid path {raw}: {err}"))
|
||||
}
|
||||
|
||||
fn parse_non_empty_string(raw: &str) -> Result<String, String> {
|
||||
let trimmed = raw.trim();
|
||||
if trimmed.is_empty() {
|
||||
Err("value must not be empty".to_string())
|
||||
} else {
|
||||
Ok(trimmed.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct LandlockCommand {
|
||||
/// Named permissions profile to apply from the active configuration stack.
|
||||
@@ -140,3 +161,45 @@ pub struct WindowsCommand {
|
||||
#[arg(trailing_var_arg = true)]
|
||||
pub command: Vec<String>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::SeatbeltCommand;
|
||||
use clap::Parser;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn seatbelt_command_parses_additional_allowlist_flags() {
|
||||
let command = SeatbeltCommand::try_parse_from([
|
||||
"seatbelt",
|
||||
"--allow-mach-service",
|
||||
"com.apple.foo",
|
||||
"--allow-mach-service",
|
||||
"com.apple.bar",
|
||||
"--allow-appleevent-destination",
|
||||
"com.apple.finder",
|
||||
"--allow-lsopen",
|
||||
"--allow-unix-socket",
|
||||
"/tmp/codex.sock",
|
||||
"--",
|
||||
"/bin/echo",
|
||||
"hi",
|
||||
])
|
||||
.expect("parse");
|
||||
|
||||
assert_eq!(
|
||||
command.allow_mach_services,
|
||||
vec!["com.apple.foo".to_string(), "com.apple.bar".to_string()]
|
||||
);
|
||||
assert_eq!(
|
||||
command.allow_appleevent_bundle_ids,
|
||||
vec!["com.apple.finder".to_string()]
|
||||
);
|
||||
assert!(command.allow_lsopen);
|
||||
assert_eq!(command.allow_unix_sockets.len(), 1);
|
||||
assert_eq!(
|
||||
command.command,
|
||||
vec!["/bin/echo".to_string(), "hi".to_string()]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user