windows-sandbox: drive write roots from resolved permissions (#22923)

## Why

This is the third PR in the Windows sandbox `SandboxPolicy` ->
`PermissionProfile` migration stack.

#22896 introduced `ResolvedWindowsSandboxPermissions`, and #22918 moved
elevated runner IPC to carry `PermissionProfile`. This PR starts moving
the remaining setup/spawn helpers away from asking legacy enum questions
like “is this `WorkspaceWrite`?” and toward resolved runtime permission
questions like “does this profile require write capability roots?”

## What changed

- Added resolved-permissions helpers for network identity and
write-capability detection.
- Moved setup write-root gathering to operate on
`ResolvedWindowsSandboxPermissions`, with the legacy `SandboxPolicy`
wrapper left in place for existing call sites.
- Updated identity setup, elevated capture setup, and world-writable
audit denies to use resolved write roots.
- Updated spawn preparation to carry resolved permissions in
`SpawnContext` and use them for network blocking, setup write roots,
elevated capability SID selection, and legacy capability roots.
- Removed a now-unused legacy write-root helper.

## Verification

- `cargo test -p codex-windows-sandbox`
- `just fix -p codex-windows-sandbox`
- Existing stack checks are green on #22896 and #22918; CI has started
for this PR.
















---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/22923).
* #23715
* #23714
* #23167
* __->__ #22923
This commit is contained in:
Michael Bolin authored and GitHub committed 2026-05-20 14:30:42 -07:00
1 parent f48be015d6
commit e1ec0eee5f
10 files changed
+361 -134

No files matched your search

@@ -10,6 +10,7 @@ use crate::process::StdinMode;
use crate::process::read_handle_loop;
use crate::process::spawn_process_with_pipes;
use crate::spawn_prep::LegacyAclSids;
use crate::spawn_prep::SpawnPrepOptions;
use crate::spawn_prep::allow_null_device_for_workspace_write;
use crate::spawn_prep::apply_legacy_session_acl_rules;
use crate::spawn_prep::legacy_session_capability_roots;
@@ -283,12 +284,15 @@ pub(crate) async fn spawn_windows_sandbox_session_legacy(
) -> Result<SpawnedProcess> {
let common = prepare_legacy_spawn_context(
policy_json_or_preset,
sandbox_policy_cwd,
codex_home,
cwd,
&mut env_map,
&command,
/*inherit_path*/ false,
/*add_git_safe_directory*/ false,
SpawnPrepOptions {
inherit_path: false,
add_git_safe_directory: false,
},
)?;
if !common.policy.has_full_disk_read_access() {
anyhow::bail!("Restricted read-only access requires the elevated Windows sandbox backend");
@@ -311,7 +315,7 @@ pub(crate) async fn spawn_windows_sandbox_session_legacy(
);
let security =
prepare_legacy_session_security(&common.policy, codex_home, cwd, capability_roots)?;
allow_null_device_for_workspace_write(common.is_workspace_write);
allow_null_device_for_workspace_write(common.uses_write_capabilities);
apply_legacy_session_acl_rules(
&common.policy,