Extract shared Windows sandbox session runner (#28357)

## Why

This is the first PR in a stack for the Windows fs-helper sandbox fix.
Before changing fs-helper behavior, this pulls the reusable Windows
sandbox session launch pieces out of the debug CLI path so later PRs can
call the same backend selection and stdio forwarding logic.

Keeping this as a pure refactor makes the later security fix easier to
review: `codex sandbox windows` should continue to launch the same
elevated or restricted-token backend, just through shared APIs in
`windows-sandbox-rs` instead of code local to
`cli/src/debug_sandbox.rs`.

## What Changed

- Added `WindowsSandboxSessionRequest` and
`spawn_windows_sandbox_session_for_level()` in `windows-sandbox-rs` to
share the elevated-vs-legacy session launch decision.
- Moved the Windows sandbox stdio forwarding helpers from
`cli/src/debug_sandbox.rs` into
`windows-sandbox-rs/src/stdio_bridge.rs`.
- Updated `codex sandbox windows` to call the shared session launcher
and stdio bridge.
- Added unit coverage for the moved stdio forwarding helpers.

## Verification

- `just bazel-lock-update`
- `just bazel-lock-check`
- `just test -p codex-windows-sandbox stdio_bridge::tests`
- `just fix -p codex-windows-sandbox -p codex-sandboxing -p
codex-exec-server -p codex-arg0 -p codex-core -p codex-file-system`
- The new `stdio_bridge` tests also passed as part of `just test -p
codex-windows-sandbox` on the stack tip. That full local run still fails
in pre-existing legacy session integration tests with
`CreateRestrictedToken failed: 87` on this workstation.
This commit is contained in:
iceweasel-oai authored and GitHub committed 2026-06-15 18:30:48 +00:00
1 parent 0afe559318
commit c3415f76c9
6 files changed
+290 -237

No files matched your search

@@ -10,6 +10,7 @@
mod backends;
use anyhow::Result;
use codex_protocol::config_types::WindowsSandboxLevel;
use codex_protocol::models::PermissionProfile;
use codex_utils_absolute_path::AbsolutePathBuf;
use codex_utils_pty::SpawnedProcess;
@@ -17,6 +18,73 @@ use std::collections::HashMap;
use std::path::Path;
use std::path::PathBuf;
/// Fully resolved Windows sandbox session launch request.
///
/// Callers should parse their own input shape first, then use this request to
/// share the elevated-vs-legacy backend selection and session launch path.
pub struct WindowsSandboxSessionRequest<'a> {
pub permission_profile: &'a PermissionProfile,
pub workspace_roots: &'a [AbsolutePathBuf],
pub codex_home: &'a Path,
pub command: Vec<String>,
pub cwd: &'a Path,
pub env_map: HashMap<String, String>,
pub windows_sandbox_level: WindowsSandboxLevel,
pub timeout_ms: Option<u64>,
pub read_roots_override: Option<&'a [PathBuf]>,
pub read_roots_include_platform_defaults: bool,
pub write_roots_override: Option<&'a [PathBuf]>,
pub deny_read_paths_override: &'a [AbsolutePathBuf],
pub deny_write_paths_override: &'a [AbsolutePathBuf],
pub tty: bool,
pub stdin_open: bool,
pub use_private_desktop: bool,
}
pub async fn spawn_windows_sandbox_session_for_level(
request: WindowsSandboxSessionRequest<'_>,
) -> Result<SpawnedProcess> {
match request.windows_sandbox_level {
WindowsSandboxLevel::Elevated => {
spawn_windows_sandbox_session_elevated_for_permission_profile(
request.permission_profile,
request.workspace_roots,
request.codex_home,
request.command,
request.cwd,
request.env_map,
request.timeout_ms,
request.read_roots_override,
request.read_roots_include_platform_defaults,
request.write_roots_override,
request.deny_read_paths_override,
request.deny_write_paths_override,
request.tty,
request.stdin_open,
request.use_private_desktop,
)
.await
}
WindowsSandboxLevel::RestrictedToken | WindowsSandboxLevel::Disabled => {
spawn_windows_sandbox_session_legacy(
request.permission_profile,
request.workspace_roots,
request.codex_home,
request.command,
request.cwd,
request.env_map,
request.timeout_ms,
request.deny_read_paths_override,
request.deny_write_paths_override,
request.tty,
request.stdin_open,
request.use_private_desktop,
)
.await
}
}
}
#[allow(clippy::too_many_arguments)]
pub async fn spawn_windows_sandbox_session_legacy(
permission_profile: &PermissionProfile,