David Uhden Collado wrote:
Hello,

Please find attached two related patches that prevent Codex from
silently running restricted commands without sandbox enforcement.

OpenBSD does not currently provide a supported Codex sandbox backend.
pledge/unveil cannot reliably enforce these restrictions across
arbitrary subprocesses created through execve.

The first patch rejects managed sandbox profiles during configuration
and session creation.

The second rejects unsupported restrictions at command execution,
including managed network policies that cannot be enforced by a
proxy alone.

Both are necessary to cover the different execution paths.

Explicit danger-full-access execution remains available, as does
the option of running Codex inside external isolation.

Thanks,
David.
Oops, I forgot to attach one of the patches.
Index: devel/codex/patches/patch-codex-rs_exec-server_src_process_sandbox_rs
===================================================================
RCS file: devel/codex/patches/patch-codex-rs_exec-server_src_process_sandbox_rs
diff -N devel/codex/patches/patch-codex-rs_exec-server_src_process_sandbox_rs
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devel/codex/patches/patch-codex-rs_exec-server_src_process_sandbox_rs	18 Oct 2026 16:10:35 -0000
@@ -0,0 +1,18 @@
+Index: codex-rs/exec-server/src/process_sandbox.rs
+--- codex-rs/exec-server/src/process_sandbox.rs.orig
++++ codex-rs/exec-server/src/process_sandbox.rs
+@@ -95,6 +95,14 @@ pub(crate) async fn prepare_exec_request
+     network_policy_audit_observer: Option<NetworkPolicyAuditObserver>,
+     telemetry: &ProcessTelemetry,
+ ) -> Result<PreparedExecRequest, JSONRPCErrorError> {
++    // A proxy environment cannot enforce egress policy without a command
++    // sandbox. Check before the sandbox=None native-launch shortcut too.
++    #[cfg(target_os = "openbsd")]
++    if params.enforce_managed_network {
++        return Err(invalid_params(
++            "OpenBSD cannot enforce managed command networking: no supported command sandbox is available".to_string(),
++        ));
++    }
+     if let Some(sandbox) = params.sandbox.as_ref()
+         && sandbox.windows_sandbox_selection == WindowsSandboxSelection::Mxc
+     {
Index: devel/codex/patches/patch-codex-rs_sandboxing_src_lib_rs
===================================================================
RCS file: devel/codex/patches/patch-codex-rs_sandboxing_src_lib_rs
diff -N devel/codex/patches/patch-codex-rs_sandboxing_src_lib_rs
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devel/codex/patches/patch-codex-rs_sandboxing_src_lib_rs	18 Oct 2026 16:10:35 -0000
@@ -0,0 +1,14 @@
+Index: codex-rs/sandboxing/src/lib.rs
+--- codex-rs/sandboxing/src/lib.rs.orig
++++ codex-rs/sandboxing/src/lib.rs
+@@ -75,6 +75,10 @@ pub fn system_bwrap_warning(
+ impl From<SandboxTransformError> for CodexErr {
+     fn from(err: SandboxTransformError) -> Self {
+         match err {
++            #[cfg(target_os = "openbsd")]
++            SandboxTransformError::OpenBsdSandboxUnavailable => CodexErr::UnsupportedOperation(
++                "OpenBSD has no supported command sandbox; select explicit danger-full-access or provide external isolation".to_string(),
++            ),
+             error @ SandboxTransformError::InvalidCommandCwd { .. }
+             | error @ SandboxTransformError::InvalidSandboxPolicyCwd { .. } => {
+                 CodexErr::InvalidRequest(error.to_string())
Index: devel/codex/patches/patch-codex-rs_sandboxing_src_manager_rs
===================================================================
RCS file: devel/codex/patches/patch-codex-rs_sandboxing_src_manager_rs
diff -N devel/codex/patches/patch-codex-rs_sandboxing_src_manager_rs
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devel/codex/patches/patch-codex-rs_sandboxing_src_manager_rs	18 Oct 2026 16:10:35 -0000
@@ -0,0 +1,63 @@
+Index: codex-rs/sandboxing/src/manager.rs
+--- codex-rs/sandboxing/src/manager.rs.orig
++++ codex-rs/sandboxing/src/manager.rs
+@@ -189,6 +189,8 @@ impl PendingSandboxedExecRequest {
+ 
+ #[derive(Debug)]
+ pub enum SandboxTransformError {
++    #[cfg(target_os = "openbsd")]
++    OpenBsdSandboxUnavailable,
+     InvalidCommandCwd {
+         cwd: PathUri,
+         source: io::Error,
+@@ -213,6 +215,11 @@ pub enum SandboxTransformError {
+ impl std::fmt::Display for SandboxTransformError {
+     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+         match self {
++            #[cfg(target_os = "openbsd")]
++            Self::OpenBsdSandboxUnavailable => write!(
++                f,
++                "OpenBSD has no supported command sandbox; select explicit danger-full-access or provide external isolation"
++            ),
+             Self::InvalidCommandCwd { cwd, source } => {
+                 write!(
+                     f,
+@@ -256,6 +263,8 @@ impl std::error::Error for SandboxTransf
+             Self::MissingLinuxSandboxExecutable => None,
+             Self::WindowsMxcPreparation(_) => None,
+             Self::EnvironmentNetworkProxy(_) => None,
++            #[cfg(target_os = "openbsd")]
++            Self::OpenBsdSandboxUnavailable => None,
+             #[cfg(target_os = "macos")]
+             Self::SeatbeltPreparation(_) => None,
+             #[cfg(target_os = "linux")]
+@@ -375,6 +384,29 @@ impl SandboxManager {
+             network.and_then(NetworkProxy::managed_mitm_ca_trust_bundle_path);
+         let base_effective_permission_profile =
+             effective_permission_profile(permissions, additional_permissions.as_ref());
++        // OpenBSD has no upstream sandbox backend. Never interpret a missing
++        // backend as permission to run a restricted request without isolation.
++        #[cfg(target_os = "openbsd")]
++        {
++            let (file_system_policy, network_policy) =
++                base_effective_permission_profile.to_runtime_permissions();
++            if matches!(
++                &base_effective_permission_profile,
++                PermissionProfile::Managed { .. }
++            ) || sandbox != SandboxType::None
++                || (matches!(
++                    file_system_policy.kind,
++                    codex_protocol::permissions::FileSystemSandboxKind::Restricted
++                ) && !file_system_policy.has_full_disk_read_access())
++                || should_require_platform_sandbox(
++                    &file_system_policy,
++                    network_policy,
++                    enforce_managed_network,
++                )
++            {
++                return Err(SandboxTransformError::OpenBsdSandboxUnavailable);
++            }
++        }
+         let pending_sandboxed_request = PendingSandboxedExecRequest::new(
+             &command.cwd,
+             sandbox_policy_cwd,

Reply via email to