windows-sandbox: remove SandboxPolicy runner plumbing (#23813)

## Why

The Windows sandbox runner still carried the old `SandboxPolicy`
compatibility path even though core now computes `PermissionProfile`.
That meant Windows command-runner execution could only see the legacy
projection, so profile-only filesystem rules such as deny globs were not
part of the runner input.

## What Changed

- Removed the Windows-local `SandboxPolicy` parser/export and deleted
`windows-sandbox-rs/src/policy.rs`.
- Changed restricted-token capture/session setup, elevated setup,
world-writable audit, read-root grant, and command-runner session APIs
to accept `PermissionProfile` plus the profile cwd.
- Bumped the elevated command-runner IPC protocol to version 2 because
`SpawnRequest` now carries `permission_profile` /
`permission_profile_cwd` instead of the legacy `policy_json_or_preset` /
`sandbox_policy_cwd` fields.
- Updated core exec, unified exec, debug-sandbox, TUI setup/grant flows,
and app-server setup to pass the actual effective `PermissionProfile`.
- Left regression coverage asserting the old IPC policy fields are
absent and the runner serializes tagged `PermissionProfile` JSON.

## Verification

- `cargo test -p codex-windows-sandbox`
- `cargo test -p codex-core windows_sandbox`
- `cargo test -p codex-app-server
request_processors::windows_sandbox_processor`
- `just fix -p codex-windows-sandbox -p codex-core -p codex-app-server
-p codex-cli -p codex-tui`
- `just fix -p codex-cli -p codex-tui`
- `just fix -p codex-windows-sandbox -p codex-tui`
- `rg "\\bSandboxPolicy\\b" codex-rs/windows-sandbox-rs` returned no
matches.

Note: `cargo test -p codex-cli` was attempted but did not reach crate
tests because local disk filled while compiling dependencies (`No space
left on device`). The targeted clippy pass compiled the affected CLI/TUI
surfaces afterward.




---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/23813).
* #24108
* __->__ #23813
This commit is contained in:
Michael Bolin authored and GitHub committed 2026-05-26 14:56:27 -07:00
1 parent 414561294c
commit 0a6bc4e687
22 files changed
+537 -788

No files matched your search

@@ -8,7 +8,6 @@ use crate::ipc_framed::FramedMessage;
use crate::ipc_framed::IPC_PROTOCOL_VERSION;
use crate::ipc_framed::Message;
use crate::ipc_framed::SpawnRequest;
use crate::policy::parse_policy;
use crate::resolved_permissions::ResolvedWindowsSandboxPermissions;
use crate::runner_client::spawn_runner_transport;
use crate::spawn_prep::prepare_elevated_spawn_context_for_permissions;
@@ -145,44 +144,3 @@ pub(crate) async fn spawn_windows_sandbox_session_elevated_for_permission_profil
stdin_open,
))
}
#[allow(clippy::too_many_arguments)]
pub(crate) async fn spawn_windows_sandbox_session_elevated(
policy_json_or_preset: &str,
sandbox_policy_cwd: &Path,
codex_home: &Path,
command: Vec<String>,
cwd: &Path,
env_map: HashMap<String, String>,
timeout_ms: Option<u64>,
read_roots_override: Option<&[PathBuf]>,
read_roots_include_platform_defaults: bool,
write_roots_override: Option<&[PathBuf]>,
deny_read_paths_override: &[AbsolutePathBuf],
deny_write_paths_override: &[AbsolutePathBuf],
tty: bool,
stdin_open: bool,
use_private_desktop: bool,
) -> Result<SpawnedProcess> {
let policy = parse_policy(policy_json_or_preset)?;
let permission_profile =
PermissionProfile::from_legacy_sandbox_policy_for_cwd(&policy, sandbox_policy_cwd);
spawn_windows_sandbox_session_elevated_for_permission_profile(
&permission_profile,
sandbox_policy_cwd,
codex_home,
command,
cwd,
env_map,
timeout_ms,
read_roots_override,
read_roots_include_platform_defaults,
write_roots_override,
deny_read_paths_override,
deny_write_paths_override,
tty,
stdin_open,
use_private_desktop,
)
.await
}
@@ -17,6 +17,7 @@ use crate::spawn_prep::legacy_session_capability_roots;
use crate::spawn_prep::prepare_legacy_session_security;
use crate::spawn_prep::prepare_legacy_spawn_context;
use anyhow::Result;
use codex_protocol::models::PermissionProfile;
use codex_utils_absolute_path::AbsolutePathBuf;
use codex_utils_pty::ProcessDriver;
use codex_utils_pty::SpawnedProcess;
@@ -269,8 +270,8 @@ fn resize_conpty_handle(hpc: &Arc<StdMutex<Option<HANDLE>>>, size: TerminalSize)
#[allow(clippy::too_many_arguments)]
pub(crate) async fn spawn_windows_sandbox_session_legacy(
policy_json_or_preset: &str,
sandbox_policy_cwd: &Path,
permission_profile: &PermissionProfile,
permission_profile_cwd: &Path,
codex_home: &Path,
command: Vec<String>,
cwd: &Path,
@@ -283,8 +284,8 @@ pub(crate) async fn spawn_windows_sandbox_session_legacy(
use_private_desktop: bool,
) -> Result<SpawnedProcess> {
let common = prepare_legacy_spawn_context(
policy_json_or_preset,
sandbox_policy_cwd,
permission_profile,
permission_profile_cwd,
codex_home,
cwd,
&mut env_map,
@@ -294,7 +295,7 @@ pub(crate) async fn spawn_windows_sandbox_session_legacy(
add_git_safe_directory: false,
},
)?;
if !common.policy.has_full_disk_read_access() {
if !common.permissions.has_full_disk_read_access() {
anyhow::bail!("Restricted read-only access requires the elevated Windows sandbox backend");
}
// WRITE_RESTRICTED tokens consult restricting SIDs only for writes, so this
@@ -307,14 +308,17 @@ pub(crate) async fn spawn_windows_sandbox_session_legacy(
.map(AbsolutePathBuf::to_path_buf)
.collect::<Vec<_>>();
let capability_roots = legacy_session_capability_roots(
&common.policy,
sandbox_policy_cwd,
&common.permissions,
&common.current_dir,
&env_map,
codex_home,
);
let security =
prepare_legacy_session_security(&common.policy, codex_home, cwd, capability_roots)?;
let security = prepare_legacy_session_security(
common.uses_write_capabilities,
codex_home,
cwd,
capability_roots,
)?;
allow_null_device_for_workspace_write(common.uses_write_capabilities);
apply_legacy_session_acl_rules(
@@ -19,8 +19,8 @@ use std::path::PathBuf;
#[allow(clippy::too_many_arguments)]
pub async fn spawn_windows_sandbox_session_legacy(
policy_json_or_preset: &str,
sandbox_policy_cwd: &Path,
permission_profile: &PermissionProfile,
permission_profile_cwd: &Path,
codex_home: &Path,
command: Vec<String>,
cwd: &Path,
@@ -33,8 +33,8 @@ pub async fn spawn_windows_sandbox_session_legacy(
use_private_desktop: bool,
) -> Result<SpawnedProcess> {
backends::legacy::spawn_windows_sandbox_session_legacy(
policy_json_or_preset,
sandbox_policy_cwd,
permission_profile,
permission_profile_cwd,
codex_home,
command,
cwd,
@@ -87,44 +87,6 @@ pub async fn spawn_windows_sandbox_session_elevated_for_permission_profile(
.await
}
#[allow(clippy::too_many_arguments)]
pub async fn spawn_windows_sandbox_session_elevated(
policy_json_or_preset: &str,
sandbox_policy_cwd: &Path,
codex_home: &Path,
command: Vec<String>,
cwd: &Path,
env_map: HashMap<String, String>,
timeout_ms: Option<u64>,
read_roots_override: Option<&[PathBuf]>,
read_roots_include_platform_defaults: bool,
write_roots_override: Option<&[PathBuf]>,
deny_read_paths_override: &[AbsolutePathBuf],
deny_write_paths_override: &[AbsolutePathBuf],
tty: bool,
stdin_open: bool,
use_private_desktop: bool,
) -> Result<SpawnedProcess> {
backends::elevated::spawn_windows_sandbox_session_elevated(
policy_json_or_preset,
sandbox_policy_cwd,
codex_home,
command,
cwd,
env_map,
timeout_ms,
read_roots_override,
read_roots_include_platform_defaults,
write_roots_override,
deny_read_paths_override,
deny_write_paths_override,
tty,
stdin_open,
use_private_desktop,
)
.await
}
#[cfg(test)]
pub(crate) use backends::windows_common::finish_driver_spawn;
#[cfg(test)]
@@ -5,6 +5,7 @@ use crate::ipc_framed::Message;
use crate::ipc_framed::decode_bytes;
use crate::ipc_framed::read_frame;
use crate::run_windows_sandbox_capture;
use codex_protocol::models::PermissionProfile;
use codex_utils_absolute_path::AbsolutePathBuf;
use codex_utils_pty::ProcessDriver;
use pretty_assertions::assert_eq;
@@ -149,8 +150,9 @@ fn legacy_non_tty_cmd_emits_output() {
let cwd = sandbox_cwd();
let codex_home = sandbox_home("legacy-non-tty-cmd");
println!("cmd codex_home={}", codex_home.path().display());
let permission_profile = PermissionProfile::workspace_write();
let spawned = spawn_windows_sandbox_session_legacy(
"workspace-write",
&permission_profile,
cwd.as_path(),
codex_home.path(),
vec![
@@ -189,8 +191,9 @@ fn legacy_non_tty_cmd_rejects_deny_read_overrides() {
let secret_path =
AbsolutePathBuf::from_absolute_path(cwd.join("legacy-non-tty-deny-read-secret.env"))
.expect("absolute deny-read fixture path");
let permission_profile = PermissionProfile::workspace_write();
let err = spawn_windows_sandbox_session_legacy(
"workspace-write",
&permission_profile,
cwd.as_path(),
codex_home.path(),
vec![
@@ -228,8 +231,9 @@ fn legacy_non_tty_powershell_emits_output() {
let cwd = sandbox_cwd();
let codex_home = sandbox_home("legacy-non-tty-pwsh");
println!("pwsh codex_home={}", codex_home.path().display());
let permission_profile = PermissionProfile::workspace_write();
let spawned = spawn_windows_sandbox_session_legacy(
"workspace-write",
&permission_profile,
cwd.as_path(),
codex_home.path(),
vec![
@@ -413,8 +417,9 @@ fn legacy_capture_powershell_emits_output() {
let cwd = sandbox_cwd();
let codex_home = sandbox_home("legacy-capture-pwsh");
println!("capture pwsh codex_home={}", codex_home.path().display());
let permission_profile = PermissionProfile::workspace_write();
let result = run_windows_sandbox_capture(
"workspace-write",
&permission_profile,
cwd.as_path(),
codex_home.path(),
vec![
@@ -452,8 +457,9 @@ fn legacy_tty_powershell_emits_output_and_accepts_input() {
let cwd = sandbox_cwd();
let codex_home = sandbox_home("legacy-tty-pwsh");
println!("tty pwsh codex_home={}", codex_home.path().display());
let permission_profile = PermissionProfile::workspace_write();
let spawned = spawn_windows_sandbox_session_legacy(
"workspace-write",
&permission_profile,
cwd.as_path(),
codex_home.path(),
vec![
@@ -505,8 +511,9 @@ fn legacy_tty_cmd_emits_output_and_accepts_input() {
let cwd = sandbox_cwd();
let codex_home = sandbox_home("legacy-tty-cmd");
println!("tty cmd codex_home={}", codex_home.path().display());
let permission_profile = PermissionProfile::workspace_write();
let spawned = spawn_windows_sandbox_session_legacy(
"workspace-write",
&permission_profile,
cwd.as_path(),
codex_home.path(),
vec![
@@ -558,8 +565,9 @@ fn legacy_tty_cmd_default_desktop_emits_output_and_accepts_input() {
"tty cmd default desktop codex_home={}",
codex_home.path().display()
);
let permission_profile = PermissionProfile::workspace_write();
let spawned = spawn_windows_sandbox_session_legacy(
"workspace-write",
&permission_profile,
cwd.as_path(),
codex_home.path(),
vec![