diff --git a/codex-rs/core/src/exec.rs b/codex-rs/core/src/exec.rs index 309dbbb01b..dcfc7c7514 100644 --- a/codex-rs/core/src/exec.rs +++ b/codex-rs/core/src/exec.rs @@ -40,7 +40,6 @@ use codex_protocol::protocol::ExecOutputStream; use codex_protocol::protocol::SandboxPolicy; use codex_sandboxing::SandboxCommand; use codex_sandboxing::SandboxManager; -use codex_sandboxing::SandboxTransformRequest; use codex_sandboxing::SandboxType; use codex_sandboxing::SandboxablePreference; use codex_utils_absolute_path::AbsolutePathBuf; @@ -284,20 +283,20 @@ pub fn build_exec_request( capture_policy, }; let mut exec_req = manager - .transform(SandboxTransformRequest { + .transform( command, - policy: sandbox_policy, - file_system_policy: file_system_sandbox_policy, - network_policy: network_sandbox_policy, - sandbox: sandbox_type, + sandbox_policy, + file_system_sandbox_policy, + network_sandbox_policy, + sandbox_type, enforce_managed_network, - network: network.as_ref(), - sandbox_policy_cwd: sandbox_cwd, - codex_linux_sandbox_exe: codex_linux_sandbox_exe.as_ref(), + network.as_ref(), + sandbox_cwd, + codex_linux_sandbox_exe.as_ref(), use_legacy_landlock, windows_sandbox_level, windows_sandbox_private_desktop, - }) + ) .map(|request| ExecRequest::from_sandbox_exec_request(request, options)) .map_err(CodexErr::from)?; exec_req.windows_restricted_token_filesystem_overlay = diff --git a/codex-rs/core/src/tools/js_repl/mod.rs b/codex-rs/core/src/tools/js_repl/mod.rs index 0cfbd2a60c..7479fad11d 100644 --- a/codex-rs/core/src/tools/js_repl/mod.rs +++ b/codex-rs/core/src/tools/js_repl/mod.rs @@ -43,7 +43,6 @@ use crate::tools::ToolRouter; use crate::tools::context::SharedTurnDiffTracker; use codex_sandboxing::SandboxCommand; use codex_sandboxing::SandboxManager; -use codex_sandboxing::SandboxTransformRequest; use codex_sandboxing::SandboxablePreference; use codex_tools::ToolSpec; use codex_utils_output_truncation::TruncationPolicy; @@ -1059,23 +1058,20 @@ impl JsReplManager { capture_policy: ExecCapturePolicy::ShellTool, }; let exec_env = sandbox - .transform(SandboxTransformRequest { + .transform( command, - policy: &turn.sandbox_policy, - file_system_policy: &turn.file_system_sandbox_policy, - network_policy: turn.network_sandbox_policy, - sandbox: sandbox_type, - enforce_managed_network: has_managed_network_requirements, - network: None, - sandbox_policy_cwd: &turn.cwd, - 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, - windows_sandbox_private_desktop: turn - .config - .permissions - .windows_sandbox_private_desktop, - }) + &turn.sandbox_policy, + &turn.file_system_sandbox_policy, + turn.network_sandbox_policy, + sandbox_type, + has_managed_network_requirements, + None, + &turn.cwd, + turn.codex_linux_sandbox_exe.as_ref(), + turn.features.use_legacy_landlock(), + turn.windows_sandbox_level, + turn.config.permissions.windows_sandbox_private_desktop, + ) .map(|request| { crate::sandboxing::ExecRequest::from_sandbox_exec_request(request, options) }) diff --git a/codex-rs/core/src/tools/runtimes/shell/unix_escalation.rs b/codex-rs/core/src/tools/runtimes/shell/unix_escalation.rs index b52fd8c863..ccc7599e2b 100644 --- a/codex-rs/core/src/tools/runtimes/shell/unix_escalation.rs +++ b/codex-rs/core/src/tools/runtimes/shell/unix_escalation.rs @@ -34,7 +34,6 @@ use codex_protocol::protocol::ReviewDecision; use codex_protocol::protocol::SandboxPolicy; use codex_sandboxing::SandboxCommand; use codex_sandboxing::SandboxManager; -use codex_sandboxing::SandboxTransformRequest; use codex_sandboxing::SandboxType; use codex_sandboxing::SandboxablePreference; use codex_shell_command::bash::parse_shell_lc_plain_commands; @@ -835,20 +834,20 @@ impl CoreShellCommandExecutor { expiration: ExecExpiration::DefaultTimeout, capture_policy: ExecCapturePolicy::ShellTool, }; - let exec_request = sandbox_manager.transform(SandboxTransformRequest { + let exec_request = sandbox_manager.transform( command, - policy: sandbox_policy, - file_system_policy: file_system_sandbox_policy, - network_policy: network_sandbox_policy, + sandbox_policy, + file_system_sandbox_policy, + network_sandbox_policy, sandbox, - enforce_managed_network: self.network.is_some(), - network: self.network.as_ref(), - sandbox_policy_cwd: &self.sandbox_policy_cwd, - 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, - windows_sandbox_private_desktop: false, - })?; + self.network.is_some(), + self.network.as_ref(), + &self.sandbox_policy_cwd, + self.codex_linux_sandbox_exe.as_ref(), + self.use_legacy_landlock, + self.windows_sandbox_level, + false, + )?; let mut exec_request = crate::sandboxing::ExecRequest::from_sandbox_exec_request(exec_request, options); if let Some(network) = exec_request.network.as_ref() { diff --git a/codex-rs/core/src/tools/runtimes/unified_exec.rs b/codex-rs/core/src/tools/runtimes/unified_exec.rs index 409ec691bf..b913d00c72 100644 --- a/codex-rs/core/src/tools/runtimes/unified_exec.rs +++ b/codex-rs/core/src/tools/runtimes/unified_exec.rs @@ -86,12 +86,12 @@ pub struct UnifiedExecRuntime<'a> { fn build_remote_exec_sandbox_config( attempt: &SandboxAttempt<'_>, additional_permissions: Option, -) -> Option { +) -> SandboxLaunchConfig { if matches!(attempt.sandbox, codex_sandboxing::SandboxType::None) { - return None; + return SandboxLaunchConfig::no_sandbox(attempt.sandbox_cwd.to_path_buf()); } - Some(SandboxLaunchConfig { + SandboxLaunchConfig { sandbox: attempt.sandbox, policy: attempt.policy.clone(), file_system_policy: attempt.file_system_policy.clone(), @@ -102,7 +102,7 @@ fn build_remote_exec_sandbox_config( windows_sandbox_level: attempt.windows_sandbox_level, windows_sandbox_private_desktop: attempt.windows_sandbox_private_desktop, use_legacy_landlock: attempt.use_legacy_landlock, - }) + } } impl<'a> UnifiedExecRuntime<'a> { @@ -248,12 +248,6 @@ impl<'a> ToolRuntime for UnifiedExecRunt .to_string(), )); } - if req.network.is_some() { - return Err(ToolError::Rejected( - "unified_exec managed-network is not supported when exec_server_url is configured" - .to_string(), - )); - } let exec_params = codex_exec_server::ExecParams { process_id: req.process_id.to_string().into(), argv: command, diff --git a/codex-rs/core/src/tools/sandboxing.rs b/codex-rs/core/src/tools/sandboxing.rs index c2671aabf0..05821e07eb 100644 --- a/codex-rs/core/src/tools/sandboxing.rs +++ b/codex-rs/core/src/tools/sandboxing.rs @@ -24,7 +24,6 @@ use codex_protocol::protocol::SandboxPolicy; use codex_sandboxing::SandboxCommand; use codex_sandboxing::SandboxManager; use codex_sandboxing::SandboxTransformError; -use codex_sandboxing::SandboxTransformRequest; use codex_sandboxing::SandboxType; use codex_sandboxing::SandboxablePreference; use futures::Future; @@ -339,20 +338,20 @@ impl<'a> SandboxAttempt<'a> { network: Option<&NetworkProxy>, ) -> Result { self.manager - .transform(SandboxTransformRequest { + .transform( command, - policy: self.policy, - file_system_policy: self.file_system_policy, - network_policy: self.network_policy, - sandbox: self.sandbox, - enforce_managed_network: self.enforce_managed_network, + self.policy, + self.file_system_policy, + self.network_policy, + self.sandbox, + self.enforce_managed_network, network, - sandbox_policy_cwd: self.sandbox_cwd, - codex_linux_sandbox_exe: self.codex_linux_sandbox_exe, - use_legacy_landlock: self.use_legacy_landlock, - windows_sandbox_level: self.windows_sandbox_level, - windows_sandbox_private_desktop: self.windows_sandbox_private_desktop, - }) + self.sandbox_cwd, + self.codex_linux_sandbox_exe, + self.use_legacy_landlock, + self.windows_sandbox_level, + self.windows_sandbox_private_desktop, + ) .map(|request| { crate::sandboxing::ExecRequest::from_sandbox_exec_request(request, options) }) diff --git a/codex-rs/core/src/unified_exec/mod.rs b/codex-rs/core/src/unified_exec/mod.rs index eb25f4ddc8..75c4dcd788 100644 --- a/codex-rs/core/src/unified_exec/mod.rs +++ b/codex-rs/core/src/unified_exec/mod.rs @@ -12,7 +12,7 @@ //! Flow at a glance (open process) //! 1) Build a small request `{ command, cwd }`. //! 2) Orchestrator: approval (bypass/cache/prompt) → select sandbox → run. -//! 3) Runtime: transform `SandboxTransformRequest` -> `ExecRequest` -> spawn PTY. +//! 3) Runtime: transform sandbox config -> `ExecRequest` -> spawn PTY. //! 4) If denial, orchestrator retries with `SandboxType::None`. //! 5) Process handle is returned with streaming output + metadata. //! diff --git a/codex-rs/core/src/unified_exec/process_manager.rs b/codex-rs/core/src/unified_exec/process_manager.rs index 7e22cba13e..f99a39dd12 100644 --- a/codex-rs/core/src/unified_exec/process_manager.rs +++ b/codex-rs/core/src/unified_exec/process_manager.rs @@ -609,7 +609,7 @@ impl UnifiedExecProcessManager { env: env.env.clone(), tty, arg0: env.arg0.clone(), - sandbox: None, + sandbox: codex_sandboxing::SandboxLaunchConfig::no_sandbox(env.cwd.clone()), }) .await .map_err(|err| UnifiedExecError::create_process(err.to_string()))?; diff --git a/codex-rs/exec-server/src/environment.rs b/codex-rs/exec-server/src/environment.rs index b8a3becc7e..1ad729075b 100644 --- a/codex-rs/exec-server/src/environment.rs +++ b/codex-rs/exec-server/src/environment.rs @@ -160,6 +160,7 @@ mod tests { use super::Environment; use super::EnvironmentManager; use crate::ProcessId; + use codex_sandboxing::SandboxLaunchConfig; use pretty_assertions::assert_eq; #[tokio::test] @@ -202,7 +203,9 @@ mod tests { env: Default::default(), tty: false, arg0: None, - sandbox: None, + sandbox: SandboxLaunchConfig::no_sandbox( + std::env::current_dir().expect("read current dir"), + ), }) .await .expect("start process"); diff --git a/codex-rs/exec-server/src/local_process.rs b/codex-rs/exec-server/src/local_process.rs index 96f73b7f7a..bb9693f81e 100644 --- a/codex-rs/exec-server/src/local_process.rs +++ b/codex-rs/exec-server/src/local_process.rs @@ -9,14 +9,9 @@ use std::time::Duration; use async_trait::async_trait; use codex_app_server_protocol::JSONRPCErrorError; -use codex_protocol::config_types::WindowsSandboxLevel; -use codex_protocol::permissions::FileSystemSandboxPolicy; -use codex_protocol::permissions::NetworkSandboxPolicy; -use codex_protocol::protocol::SandboxPolicy; use codex_sandboxing::SandboxCommand; use codex_sandboxing::SandboxExecRequest; use codex_sandboxing::SandboxType; -use codex_sandboxing::landlock::CODEX_LINUX_SANDBOX_ARG0; use codex_utils_pty::ExecCommandSession; use codex_utils_pty::TerminalSize; use tokio::sync::Mutex; @@ -110,14 +105,8 @@ struct ExecServerRuntimeConfig { impl ExecServerRuntimeConfig { fn detect() -> Self { let env_path = std::env::var_os("CODEX_LINUX_SANDBOX_EXE").map(PathBuf::from); - let sibling_path = std::env::current_exe().ok().and_then(|current_exe| { - current_exe - .parent() - .map(|parent| parent.join(CODEX_LINUX_SANDBOX_ARG0)) - .filter(|candidate| candidate.exists()) - }); Self { - codex_linux_sandbox_exe: env_path.or(sibling_path), + codex_linux_sandbox_exe: env_path, } } } @@ -523,29 +512,14 @@ fn prepare_exec_launch( params: &ExecParams, runtime: &ExecServerRuntimeConfig, ) -> Result { - let Some(sandbox) = params.sandbox.as_ref() else { - return Ok(SandboxExecRequest { - command: params.argv.clone(), - cwd: params.cwd.clone(), - env: params.env.clone(), - arg0: params.arg0.clone(), - network: None, - sandbox: SandboxType::None, - windows_sandbox_level: WindowsSandboxLevel::Disabled, - windows_sandbox_private_desktop: false, - sandbox_policy: SandboxPolicy::DangerFullAccess, - file_system_sandbox_policy: FileSystemSandboxPolicy::unrestricted(), - network_sandbox_policy: NetworkSandboxPolicy::Enabled, - }); - }; - let command = build_sandbox_command( ¶ms.argv, params.cwd.as_path(), ¶ms.env, - sandbox.additional_permissions.clone(), + params.sandbox.additional_permissions.clone(), )?; - sandbox + params + .sandbox .transform( command, // TODO: Thread managed-network proxy state across exec-server so diff --git a/codex-rs/exec-server/src/protocol.rs b/codex-rs/exec-server/src/protocol.rs index 5b03fa3ac5..dd11028935 100644 --- a/codex-rs/exec-server/src/protocol.rs +++ b/codex-rs/exec-server/src/protocol.rs @@ -62,7 +62,7 @@ pub struct ExecParams { pub env: HashMap, pub tty: bool, pub arg0: Option, - pub sandbox: Option, + pub sandbox: SandboxLaunchConfig, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] diff --git a/codex-rs/exec-server/src/remote_process.rs b/codex-rs/exec-server/src/remote_process.rs index d50f91a8e0..36813d56c4 100644 --- a/codex-rs/exec-server/src/remote_process.rs +++ b/codex-rs/exec-server/src/remote_process.rs @@ -1,7 +1,6 @@ use std::sync::Arc; use async_trait::async_trait; -use codex_sandboxing::SandboxType; use tokio::sync::watch; use tracing::trace; @@ -35,10 +34,7 @@ impl RemoteProcess { impl ExecBackend for RemoteProcess { async fn start(&self, params: ExecParams) -> Result { let process_id = params.process_id.clone(); - let sandbox_type = params - .sandbox - .as_ref() - .map_or(SandboxType::None, |sandbox| sandbox.sandbox); + let sandbox_type = params.sandbox.sandbox; let session = self.client.register_session(&process_id).await?; match self.client.exec(params).await { Ok(_) => {} diff --git a/codex-rs/exec-server/src/server/handler/tests.rs b/codex-rs/exec-server/src/server/handler/tests.rs index 7b2321b56d..42e4866cba 100644 --- a/codex-rs/exec-server/src/server/handler/tests.rs +++ b/codex-rs/exec-server/src/server/handler/tests.rs @@ -12,6 +12,7 @@ use crate::protocol::InitializeResponse; use crate::protocol::TerminateParams; use crate::protocol::TerminateResponse; use crate::rpc::RpcNotificationSender; +use codex_sandboxing::SandboxLaunchConfig; fn exec_params(process_id: &str) -> ExecParams { let mut env = HashMap::new(); @@ -29,7 +30,7 @@ fn exec_params(process_id: &str) -> ExecParams { env, tty: false, arg0: None, - sandbox: None, + sandbox: SandboxLaunchConfig::no_sandbox(std::env::current_dir().expect("cwd")), } } diff --git a/codex-rs/exec-server/tests/exec_process.rs b/codex-rs/exec-server/tests/exec_process.rs index a28e44f32b..e35f149c28 100644 --- a/codex-rs/exec-server/tests/exec_process.rs +++ b/codex-rs/exec-server/tests/exec_process.rs @@ -61,7 +61,9 @@ async fn assert_exec_process_starts_and_exits(use_remote: bool) -> Result<()> { env: Default::default(), tty: false, arg0: None, - sandbox: None, + sandbox: SandboxLaunchConfig::no_sandbox( + std::env::current_dir().expect("read current dir"), + ), }) .await?; assert_eq!(session.process.process_id().as_str(), "proc-1"); @@ -138,7 +140,9 @@ async fn assert_exec_process_streams_output(use_remote: bool) -> Result<()> { env: Default::default(), tty: false, arg0: None, - sandbox: None, + sandbox: SandboxLaunchConfig::no_sandbox( + std::env::current_dir().expect("read current dir"), + ), }) .await?; assert_eq!(session.process.process_id().as_str(), process_id); @@ -168,7 +172,7 @@ async fn assert_exec_process_write_then_read(use_remote: bool) -> Result<()> { env: Default::default(), tty: true, arg0: None, - sandbox: None, + sandbox: SandboxLaunchConfig::no_sandbox(std::env::current_dir().expect("read current dir")), }) .await?; assert_eq!(session.process.process_id().as_str(), process_id); @@ -205,7 +209,9 @@ async fn assert_exec_process_preserves_queued_events_before_subscribe( env: Default::default(), tty: false, arg0: None, - sandbox: None, + sandbox: SandboxLaunchConfig::no_sandbox( + std::env::current_dir().expect("read current dir"), + ), }) .await?; @@ -306,7 +312,9 @@ async fn remote_exec_process_reports_transport_disconnect() -> Result<()> { env: Default::default(), tty: false, arg0: None, - sandbox: None, + sandbox: SandboxLaunchConfig::no_sandbox( + std::env::current_dir().expect("read current dir"), + ), }) .await?; diff --git a/codex-rs/sandboxing/src/lib.rs b/codex-rs/sandboxing/src/lib.rs index 499fa0aa17..a211709285 100644 --- a/codex-rs/sandboxing/src/lib.rs +++ b/codex-rs/sandboxing/src/lib.rs @@ -15,7 +15,6 @@ pub use manager::SandboxExecRequest; pub use manager::SandboxLaunchConfig; pub use manager::SandboxManager; pub use manager::SandboxTransformError; -pub use manager::SandboxTransformRequest; pub use manager::SandboxType; pub use manager::SandboxablePreference; pub use manager::get_platform_sandbox; diff --git a/codex-rs/sandboxing/src/manager.rs b/codex-rs/sandboxing/src/manager.rs index b698ebc94c..9e27ef4c41 100644 --- a/codex-rs/sandboxing/src/manager.rs +++ b/codex-rs/sandboxing/src/manager.rs @@ -65,26 +65,41 @@ pub struct SandboxLaunchConfig { } impl SandboxLaunchConfig { + pub fn no_sandbox(sandbox_policy_cwd: PathBuf) -> Self { + Self { + sandbox: SandboxType::None, + policy: SandboxPolicy::DangerFullAccess, + file_system_policy: FileSystemSandboxPolicy::unrestricted(), + network_policy: NetworkSandboxPolicy::Enabled, + sandbox_policy_cwd, + additional_permissions: None, + enforce_managed_network: false, + windows_sandbox_level: WindowsSandboxLevel::Disabled, + windows_sandbox_private_desktop: false, + use_legacy_landlock: false, + } + } + pub fn transform( &self, command: SandboxCommand, network: Option<&NetworkProxy>, codex_linux_sandbox_exe: Option<&PathBuf>, ) -> Result { - SandboxManager::new().transform(SandboxTransformRequest { + SandboxManager::new().transform( command, - policy: &self.policy, - file_system_policy: &self.file_system_policy, - network_policy: self.network_policy, - sandbox: self.sandbox, - enforce_managed_network: self.enforce_managed_network, + &self.policy, + &self.file_system_policy, + self.network_policy, + self.sandbox, + self.enforce_managed_network, network, - sandbox_policy_cwd: self.sandbox_policy_cwd.as_path(), + self.sandbox_policy_cwd.as_path(), codex_linux_sandbox_exe, - use_legacy_landlock: self.use_legacy_landlock, - windows_sandbox_level: self.windows_sandbox_level, - windows_sandbox_private_desktop: self.windows_sandbox_private_desktop, - }) + self.use_legacy_landlock, + self.windows_sandbox_level, + self.windows_sandbox_private_desktop, + ) } } @@ -128,26 +143,6 @@ pub struct SandboxExecRequest { pub arg0: Option, } -/// Bundled arguments for sandbox transformation. -/// -/// This keeps call sites self-documenting when several fields are optional. -pub struct SandboxTransformRequest<'a> { - pub command: SandboxCommand, - pub policy: &'a SandboxPolicy, - pub file_system_policy: &'a FileSystemSandboxPolicy, - pub network_policy: NetworkSandboxPolicy, - pub sandbox: SandboxType, - pub enforce_managed_network: bool, - // TODO(viyatb): Evaluate switching this to Option> - // to make shared ownership explicit across runtime/sandbox plumbing. - pub network: Option<&'a NetworkProxy>, - pub sandbox_policy_cwd: &'a Path, - pub codex_linux_sandbox_exe: Option<&'a PathBuf>, - pub use_legacy_landlock: bool, - pub windows_sandbox_level: WindowsSandboxLevel, - pub windows_sandbox_private_desktop: bool, -} - #[derive(Debug)] pub enum SandboxTransformError { MissingLinuxSandboxExecutable, @@ -208,22 +203,19 @@ impl SandboxManager { pub fn transform( &self, - request: SandboxTransformRequest<'_>, + mut command: SandboxCommand, + policy: &SandboxPolicy, + file_system_policy: &FileSystemSandboxPolicy, + network_policy: NetworkSandboxPolicy, + sandbox: SandboxType, + enforce_managed_network: bool, + network: Option<&NetworkProxy>, + sandbox_policy_cwd: &Path, + codex_linux_sandbox_exe: Option<&PathBuf>, + use_legacy_landlock: bool, + windows_sandbox_level: WindowsSandboxLevel, + windows_sandbox_private_desktop: bool, ) -> Result { - let SandboxTransformRequest { - mut command, - policy, - file_system_policy, - network_policy, - sandbox, - enforce_managed_network, - network, - sandbox_policy_cwd, - codex_linux_sandbox_exe, - use_legacy_landlock, - windows_sandbox_level, - windows_sandbox_private_desktop, - } = request; let additional_permissions = command.additional_permissions.take(); let EffectiveSandboxPermissions { sandbox_policy: effective_policy, diff --git a/codex-rs/sandboxing/src/manager_tests.rs b/codex-rs/sandboxing/src/manager_tests.rs index 6fc34c9637..c3a4b32e78 100644 --- a/codex-rs/sandboxing/src/manager_tests.rs +++ b/codex-rs/sandboxing/src/manager_tests.rs @@ -1,6 +1,5 @@ use super::SandboxCommand; use super::SandboxManager; -use super::SandboxTransformRequest; use super::SandboxType; use super::SandboxablePreference; use super::get_platform_sandbox; @@ -76,28 +75,28 @@ fn transform_preserves_unrestricted_file_system_policy_for_restricted_network() let manager = SandboxManager::new(); let cwd = std::env::current_dir().expect("current dir"); let exec_request = manager - .transform(SandboxTransformRequest { - command: SandboxCommand { + .transform( + SandboxCommand { program: "true".into(), args: Vec::new(), cwd: cwd.clone(), env: HashMap::new(), additional_permissions: None, }, - policy: &SandboxPolicy::ExternalSandbox { + &SandboxPolicy::ExternalSandbox { network_access: NetworkAccess::Restricted, }, - file_system_policy: &FileSystemSandboxPolicy::unrestricted(), - network_policy: NetworkSandboxPolicy::Restricted, - sandbox: SandboxType::None, - enforce_managed_network: false, - network: None, - sandbox_policy_cwd: cwd.as_path(), - codex_linux_sandbox_exe: None, - use_legacy_landlock: false, - windows_sandbox_level: WindowsSandboxLevel::Disabled, - windows_sandbox_private_desktop: false, - }) + &FileSystemSandboxPolicy::unrestricted(), + NetworkSandboxPolicy::Restricted, + SandboxType::None, + false, + None, + cwd.as_path(), + None, + false, + WindowsSandboxLevel::Disabled, + false, + ) .expect("transform"); assert_eq!( @@ -120,8 +119,8 @@ fn transform_additional_permissions_enable_network_for_external_sandbox() { ) .expect("absolute temp dir"); let exec_request = manager - .transform(SandboxTransformRequest { - command: SandboxCommand { + .transform( + SandboxCommand { program: "true".into(), args: Vec::new(), cwd: cwd.clone(), @@ -136,20 +135,20 @@ fn transform_additional_permissions_enable_network_for_external_sandbox() { }), }), }, - policy: &SandboxPolicy::ExternalSandbox { + &SandboxPolicy::ExternalSandbox { network_access: NetworkAccess::Restricted, }, - file_system_policy: &FileSystemSandboxPolicy::unrestricted(), - network_policy: NetworkSandboxPolicy::Restricted, - sandbox: SandboxType::None, - enforce_managed_network: false, - network: None, - sandbox_policy_cwd: cwd.as_path(), - codex_linux_sandbox_exe: None, - use_legacy_landlock: false, - windows_sandbox_level: WindowsSandboxLevel::Disabled, - windows_sandbox_private_desktop: false, - }) + &FileSystemSandboxPolicy::unrestricted(), + NetworkSandboxPolicy::Restricted, + SandboxType::None, + false, + None, + cwd.as_path(), + None, + false, + WindowsSandboxLevel::Disabled, + false, + ) .expect("transform"); assert_eq!( @@ -176,8 +175,8 @@ fn transform_additional_permissions_preserves_denied_entries() { let allowed_path = workspace_root.join("allowed").expect("allowed path"); let denied_path = workspace_root.join("denied").expect("denied path"); let exec_request = manager - .transform(SandboxTransformRequest { - command: SandboxCommand { + .transform( + SandboxCommand { program: "true".into(), args: Vec::new(), cwd: cwd.clone(), @@ -190,11 +189,11 @@ fn transform_additional_permissions_preserves_denied_entries() { ..Default::default() }), }, - policy: &SandboxPolicy::ReadOnly { + &SandboxPolicy::ReadOnly { access: ReadOnlyAccess::FullAccess, network_access: false, }, - file_system_policy: &FileSystemSandboxPolicy::restricted(vec![ + &FileSystemSandboxPolicy::restricted(vec![ FileSystemSandboxEntry { path: FileSystemPath::Special { value: FileSystemSpecialPath::Root, @@ -208,16 +207,16 @@ fn transform_additional_permissions_preserves_denied_entries() { access: FileSystemAccessMode::None, }, ]), - network_policy: NetworkSandboxPolicy::Restricted, - sandbox: SandboxType::None, - enforce_managed_network: false, - network: None, - sandbox_policy_cwd: cwd.as_path(), - codex_linux_sandbox_exe: None, - use_legacy_landlock: false, - windows_sandbox_level: WindowsSandboxLevel::Disabled, - windows_sandbox_private_desktop: false, - }) + NetworkSandboxPolicy::Restricted, + SandboxType::None, + false, + None, + cwd.as_path(), + None, + false, + WindowsSandboxLevel::Disabled, + false, + ) .expect("transform"); assert_eq!( @@ -252,26 +251,26 @@ fn transform_linux_seccomp_request( let manager = SandboxManager::new(); let cwd = std::env::current_dir().expect("current dir"); manager - .transform(SandboxTransformRequest { - command: SandboxCommand { + .transform( + SandboxCommand { program: "true".into(), args: Vec::new(), cwd: cwd.clone(), env: HashMap::new(), additional_permissions: None, }, - policy: &SandboxPolicy::DangerFullAccess, - file_system_policy: &FileSystemSandboxPolicy::unrestricted(), - network_policy: NetworkSandboxPolicy::Enabled, - sandbox: SandboxType::LinuxSeccomp, - enforce_managed_network: false, - network: None, - sandbox_policy_cwd: cwd.as_path(), - codex_linux_sandbox_exe: Some(codex_linux_sandbox_exe), - use_legacy_landlock: false, - windows_sandbox_level: WindowsSandboxLevel::Disabled, - windows_sandbox_private_desktop: false, - }) + &SandboxPolicy::DangerFullAccess, + &FileSystemSandboxPolicy::unrestricted(), + NetworkSandboxPolicy::Enabled, + SandboxType::LinuxSeccomp, + false, + None, + cwd.as_path(), + Some(codex_linux_sandbox_exe), + false, + WindowsSandboxLevel::Disabled, + false, + ) .expect("transform") } diff --git a/codex-rs/sandboxing/src/seatbelt_tests.rs b/codex-rs/sandboxing/src/seatbelt_tests.rs index a2f7bdd4da..7a2a6d8b56 100644 --- a/codex-rs/sandboxing/src/seatbelt_tests.rs +++ b/codex-rs/sandboxing/src/seatbelt_tests.rs @@ -27,11 +27,9 @@ use tempfile::TempDir; fn assert_seatbelt_denied(stderr: &[u8], path: &Path) { let stderr = String::from_utf8_lossy(stderr); - let path_display = path.display().to_string(); - let denied_path = stderr.contains(&path_display); - let denied_operation = stderr.contains("Operation not permitted"); assert!( - (denied_path && denied_operation) + (stderr.contains(&path.display().to_string()) + && stderr.contains("Operation not permitted")) || stderr.contains("sandbox-exec: sandbox_apply: Operation not permitted"), "unexpected stderr: {stderr}" );