Harden managed proxy setup for sandboxed executions (#34641)

## What changed

- Make the generated Linux proxy socket directory readable inside restricted
  `bubblewrap` sandboxes so the proxy bridge can connect.
- Route `WS_PROXY` and `WSS_PROXY` through the Linux managed proxy bridge.
- Remove inherited proxy attribution tokens from unscoped executions while
  continuing to replace them with the current token for scoped executions.

## Testing

- Exercise `WSS_PROXY` routing with a minimal filesystem policy.
- Cover attribution-token removal and replacement during environment setup.

GitOrigin-RevId: 2f14ddb26baab0147a786bc354d93eb5aad059f3
This commit is contained in:
viyatb-oai authored and copyberry committed 2026-07-22 00:31:30 +00:00
1 parent bdd3118c71
commit c5eb33aed1
5 files changed
+80 -13

No files matched your search

@@ -4,6 +4,13 @@
use codex_core::exec_env::create_env;
use codex_protocol::config_types::ShellEnvironmentPolicy;
use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::FileSystemAccessMode;
use codex_protocol::permissions::FileSystemPath;
use codex_protocol::permissions::FileSystemSandboxEntry;
use codex_protocol::permissions::FileSystemSandboxPolicy;
use codex_protocol::permissions::FileSystemSpecialPath;
use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_utils_absolute_path::AbsolutePathBuf;
use pretty_assertions::assert_eq;
use std::collections::HashMap;
use std::io::Read;
@@ -28,6 +35,8 @@ const MANAGED_PROXY_PERMISSION_ERR_SNIPPETS: &[&str] = &[
const PROXY_ENV_KEYS: &[&str] = &[
"HTTP_PROXY",
"HTTPS_PROXY",
"WS_PROXY",
"WSS_PROXY",
"ALL_PROXY",
"FTP_PROXY",
"YARN_HTTP_PROXY",
@@ -209,14 +218,40 @@ async fn managed_proxy_mode_routes_through_bridge_and_blocks_direct_egress() {
"HTTP_PROXY".to_string(),
format!("http://127.0.0.1:{proxy_port}"),
);
env.insert(
"WSS_PROXY".to_string(),
format!("http://127.0.0.1:{proxy_port}"),
);
let sandbox_helper_dir = std::path::Path::new(env!("CARGO_BIN_EXE_codex-linux-sandbox"))
.parent()
.expect("sandbox helper should have a parent");
let file_system_sandbox_policy =
FileSystemSandboxPolicy::restricted(vec![FileSystemSandboxEntry {
path: FileSystemPath::Special {
value: FileSystemSpecialPath::Minimal,
},
access: FileSystemAccessMode::Read,
missing_path_behavior: None,
}])
.with_additional_readable_roots(
std::env::current_dir()
.expect("current directory should exist")
.as_path(),
&[AbsolutePathBuf::try_from(sandbox_helper_dir).expect("absolute helper dir")],
);
let permission_profile = PermissionProfile::from_runtime_permissions(
&file_system_sandbox_policy,
NetworkSandboxPolicy::Restricted,
);
let routed_output = run_linux_sandbox_direct(
&[
"bash",
"-c",
"proxy=\"${HTTP_PROXY#*://}\"; host=\"${proxy%%:*}\"; port=\"${proxy##*:}\"; exec 3<>/dev/tcp/${host}/${port}; printf 'GET http://example.com/ HTTP/1.1\\r\\nHost: example.com\\r\\n\\r\\n' >&3; IFS= read -r line <&3; printf '%s\\n' \"$line\"",
"proxy=\"${WSS_PROXY#*://}\"; host=\"${proxy%%:*}\"; port=\"${proxy##*:}\"; exec 3<>/dev/tcp/${host}/${port}; printf 'GET http://example.com/ HTTP/1.1\\r\\nHost: example.com\\r\\n\\r\\n' >&3; IFS= read -r line <&3; printf '%s\\n' \"$line\"",
],
&PermissionProfile::Disabled,
&permission_profile,
/*allow_network_for_proxy*/ true,
env.clone(),
NETWORK_TIMEOUT_MS,