mirror of
https://github.com/openai/codex.git
synced 2026-05-05 03:47:01 +00:00
Support Unix socket allowlists in macOS sandbox (#17654)
## Changes Allows sandboxes to restrict overall network access while granting access to specific unix sockets on mac. ## Details - `codex sandbox macos`: adds a repeatable `--allow-unix-socket` option. - `codex-sandboxing`: threads explicit Unix socket roots into the macOS Seatbelt profile generation. - Preserves restricted network behavior when only Unix socket IPC is requested, and preserves full network behavior when full network is already enabled. ## Verification - `cargo test -p codex-cli -p codex-sandboxing` - `cargo build -p codex-cli --bin codex` - verified that `codex sandbox macos --allow-unix-socket /tmp/test.sock -- test-client` grants access as expected
This commit is contained in:
@@ -18,7 +18,10 @@ use codex_protocol::config_types::SandboxMode;
|
||||
use codex_protocol::permissions::NetworkSandboxPolicy;
|
||||
use codex_sandboxing::landlock::create_linux_sandbox_command_args_for_policies;
|
||||
#[cfg(target_os = "macos")]
|
||||
use codex_sandboxing::seatbelt::create_seatbelt_command_args_for_policies;
|
||||
use codex_sandboxing::seatbelt::CreateSeatbeltCommandArgsParams;
|
||||
#[cfg(target_os = "macos")]
|
||||
use codex_sandboxing::seatbelt::create_seatbelt_command_args;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use codex_utils_cli::CliConfigOverrides;
|
||||
use tokio::process::Child;
|
||||
use tokio::process::Command as TokioCommand;
|
||||
@@ -39,6 +42,7 @@ pub async fn run_command_under_seatbelt(
|
||||
) -> anyhow::Result<()> {
|
||||
let SeatbeltCommand {
|
||||
full_auto,
|
||||
allow_unix_sockets,
|
||||
log_denials,
|
||||
config_overrides,
|
||||
command,
|
||||
@@ -50,6 +54,7 @@ pub async fn run_command_under_seatbelt(
|
||||
codex_linux_sandbox_exe,
|
||||
SandboxType::Seatbelt,
|
||||
log_denials,
|
||||
&allow_unix_sockets,
|
||||
)
|
||||
.await
|
||||
}
|
||||
@@ -78,6 +83,7 @@ pub async fn run_command_under_landlock(
|
||||
codex_linux_sandbox_exe,
|
||||
SandboxType::Landlock,
|
||||
/*log_denials*/ false,
|
||||
&[],
|
||||
)
|
||||
.await
|
||||
}
|
||||
@@ -98,6 +104,7 @@ pub async fn run_command_under_windows(
|
||||
codex_linux_sandbox_exe,
|
||||
SandboxType::Windows,
|
||||
/*log_denials*/ false,
|
||||
&[],
|
||||
)
|
||||
.await
|
||||
}
|
||||
@@ -116,6 +123,8 @@ async fn run_command_under_sandbox(
|
||||
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<()> {
|
||||
let config = load_debug_sandbox_config(
|
||||
config_overrides
|
||||
@@ -252,14 +261,15 @@ async fn run_command_under_sandbox(
|
||||
let mut child = match sandbox_type {
|
||||
#[cfg(target_os = "macos")]
|
||||
SandboxType::Seatbelt => {
|
||||
let args = create_seatbelt_command_args_for_policies(
|
||||
let args = create_seatbelt_command_args(CreateSeatbeltCommandArgsParams {
|
||||
command,
|
||||
&config.permissions.file_system_sandbox_policy,
|
||||
config.permissions.network_sandbox_policy,
|
||||
sandbox_policy_cwd.as_path(),
|
||||
/*enforce_managed_network*/ false,
|
||||
network.as_ref(),
|
||||
);
|
||||
file_system_sandbox_policy: &config.permissions.file_system_sandbox_policy,
|
||||
network_sandbox_policy: config.permissions.network_sandbox_policy,
|
||||
sandbox_policy_cwd: sandbox_policy_cwd.as_path(),
|
||||
enforce_managed_network: false,
|
||||
network: network.as_ref(),
|
||||
extra_allow_unix_sockets: allow_unix_sockets,
|
||||
});
|
||||
let network_policy = config.permissions.network_sandbox_policy;
|
||||
spawn_debug_sandbox_child(
|
||||
PathBuf::from("/usr/bin/sandbox-exec"),
|
||||
|
||||
@@ -3,6 +3,7 @@ mod exit_status;
|
||||
pub(crate) mod login;
|
||||
|
||||
use clap::Parser;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use codex_utils_cli::CliConfigOverrides;
|
||||
|
||||
pub use debug_sandbox::run_command_under_landlock;
|
||||
@@ -22,6 +23,10 @@ pub struct SeatbeltCommand {
|
||||
#[arg(long = "full-auto", default_value_t = false)]
|
||||
pub full_auto: 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>,
|
||||
|
||||
/// While the command runs, capture macOS sandbox denials via `log stream` and print them after exit
|
||||
#[arg(long = "log-denials", default_value_t = false)]
|
||||
pub log_denials: bool,
|
||||
@@ -34,6 +39,11 @@ pub struct SeatbeltCommand {
|
||||
pub command: Vec<String>,
|
||||
}
|
||||
|
||||
fn parse_allow_unix_socket_path(raw: &str) -> Result<AbsolutePathBuf, String> {
|
||||
AbsolutePathBuf::relative_to_current_dir(raw)
|
||||
.map_err(|err| format!("invalid path {raw}: {err}"))
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct LandlockCommand {
|
||||
/// Convenience alias for low-friction sandboxed automatic execution (network-disabled sandbox that can write to cwd and TMPDIR)
|
||||
|
||||
Reference in New Issue
Block a user