Route Windows sandbox proxy traffic by restricting SID (#34613)

## Why

Elevated Windows sandboxes need stable managed-proxy ports while preserving the network policy and environment attribution of each sandboxed process.

## What changed

- Keep shared HTTP and SOCKS5 loopback ingress listeners alive across managed-proxy instances.
- Add a per-route restricting SID to elevated sandbox tokens and dispatch incoming connections to the matching proxy policy after attributing the client process.
- Reject connections without exactly one registered route, remove routes when their proxy handle is dropped, and keep unsandboxed Windows launches off the managed ingress.
- Provision the elevated sandbox with the configured proxy ports and local-binding setting, honoring the selected profile and CLI overrides.

## Testing

- Add Windows unit tests for TCP ownership attribution, route selection, restricting-token propagation, and setup settings.
- Add an end-to-end Windows test covering stable ports, isolated environment policies, HTTP and SOCKS5 routing, and route teardown.

GitOrigin-RevId: 783fac6e0f904dc9bb1955b75d4a5895e8bb9690
This commit is contained in:
iceweasel-oai authored and copyberry committed 2026-07-21 21:06:04 +00:00
1 parent dfd2d8133c
commit 999a715089
40 files changed
+2792 -191

No files matched your search

+47 -14
View File
@@ -1445,6 +1445,14 @@ async fn cli_main(
.await?;
}
Some(Subcommand::Sandbox(mut sandbox_cli)) => {
let config_profile = sandbox_cli
.config_profile
.as_ref()
.or(interactive.config_profile_v2.as_ref());
prepend_config_flags(
&mut sandbox_cli.config_overrides,
root_config_overrides.clone(),
);
#[cfg(target_os = "windows")]
if let Some(setup_cli) = sandbox_setup::parse_setup_command(&sandbox_cli.command)? {
reject_remote_mode_for_subcommand(
@@ -1452,7 +1460,11 @@ async fn cli_main(
root_remote_auth_token_env.as_deref(),
"sandbox setup",
)?;
sandbox_setup::run(setup_cli).await?;
let cli_overrides = sandbox_cli
.config_overrides
.parse_overrides()
.map_err(anyhow::Error::msg)?;
sandbox_setup::run(setup_cli, config_profile.cloned(), cli_overrides).await?;
return Ok(());
}
reject_remote_mode_for_subcommand(
@@ -1460,15 +1472,7 @@ async fn cli_main(
root_remote_auth_token_env.as_deref(),
"sandbox",
)?;
let config_profile = sandbox_cli
.config_profile
.as_ref()
.or(interactive.config_profile_v2.as_ref());
let loader_overrides = loader_overrides_for_profile(config_profile)?;
prepend_config_flags(
&mut sandbox_cli.config_overrides,
root_config_overrides.clone(),
);
#[cfg(target_os = "macos")]
codex_cli::run_command_under_seatbelt(
sandbox_cli,
@@ -1879,16 +1883,29 @@ fn loader_overrides_for_profile(
match profile_v2 {
Some(profile_v2) => {
let codex_home = find_codex_home()?;
Ok(LoaderOverrides {
user_config_path: Some(resolve_profile_v2_config_path(&codex_home, profile_v2)),
user_config_profile: Some(profile_v2.clone()),
..Default::default()
})
Ok(loader_overrides_for_profile_at_codex_home(
Some(profile_v2),
&codex_home,
))
}
None => Ok(LoaderOverrides::default()),
}
}
fn loader_overrides_for_profile_at_codex_home(
profile_v2: Option<&ProfileV2Name>,
codex_home: &std::path::Path,
) -> LoaderOverrides {
match profile_v2 {
Some(profile_v2) => LoaderOverrides {
user_config_path: Some(resolve_profile_v2_config_path(codex_home, profile_v2)),
user_config_profile: Some(profile_v2.clone()),
..Default::default()
},
None => LoaderOverrides::default(),
}
}
fn maybe_print_under_development_feature_warning(codex_home: &std::path::Path, feature: &str) {
let Some(spec) = FEATURES.iter().find(|spec| spec.key == feature) else {
return;
@@ -2706,6 +2723,22 @@ mod tests {
Ok(profile_v2_for_subcommand(&cli.interactive, subcommand)?.map(ToString::to_string))
}
#[test]
fn profile_loader_overrides_use_explicit_codex_home() -> anyhow::Result<()> {
let codex_home = tempfile::tempdir()?;
let profile: ProfileV2Name = "work".parse()?;
let overrides =
loader_overrides_for_profile_at_codex_home(Some(&profile), codex_home.path());
assert_eq!(
overrides.user_config_path,
Some(resolve_profile_v2_config_path(codex_home.path(), &profile))
);
assert_eq!(overrides.user_config_profile, Some(profile));
Ok(())
}
#[test]
fn profile_v2_is_rejected_for_config_management_subcommands() {
assert!(profile_v2_for_args(&["codex", "--profile", "work", "features", "list"]).is_err());