Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
475 changes: 475 additions & 0 deletions artifacts/github/bundles/openai-codex-pr-27007.json

Large diffs are not rendered by default.

125 changes: 125 additions & 0 deletions artifacts/github/bundles/openai-codex-pr-27035.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
{
"analysis_mode": "pr_first",
"commits": [
{
"author": "viyatb-oai",
"committed_at": "2026-06-08T18:15:31Z",
"message": "fix(cli): enforce configured sandbox network proxy",
"sha": "d783face3686a981e14453bc228913eac1d74059",
"url": "https://github.com/openai/codex/commit/d783face3686a981e14453bc228913eac1d74059"
},
{
"author": "viyatb-oai",
"committed_at": "2026-06-08T18:25:45Z",
"message": "fix(ci): provide bwrap to CLI integration tests",
"sha": "2a15fb7d4eadc623a70b44db8aec1c9243418279",
"url": "https://github.com/openai/codex/commit/2a15fb7d4eadc623a70b44db8aec1c9243418279"
},
{
"author": "viyatb-oai",
"committed_at": "2026-06-08T19:13:44Z",
"message": "test(cli): skip proxy sandbox test without bwrap",
"sha": "965e080940e4aeea1d3549c1c4f651bd16af1819",
"url": "https://github.com/openai/codex/commit/965e080940e4aeea1d3549c1c4f651bd16af1819"
},
{
"author": "viyatb-oai",
"committed_at": "2026-06-08T20:38:17Z",
"message": "fix(cli): preserve proxy routing with legacy landlock",
"sha": "3928dc19b1a780206384dd5e0a1427c25188c6f0",
"url": "https://github.com/openai/codex/commit/3928dc19b1a780206384dd5e0a1427c25188c6f0"
},
{
"author": "viyatb-oai",
"committed_at": "2026-06-08T20:46:07Z",
"message": "test(cli): use curl for direct network probe",
"sha": "6d445696505735e1cc41ef38ee20979282ed4d1f",
"url": "https://github.com/openai/codex/commit/6d445696505735e1cc41ef38ee20979282ed4d1f"
}
],
"default_branch": "main",
"docs_refs": [],
"examples_refs": [],
"extracted_flags": [
"CLI",
"MACOS_WEBRTC_RUSTC_LINK_FLAGS",
"BWRAP_UNAVAILABLE_ERR",
"CODEX_HOME",
"--permissions-profile",
"--noproxy",
"--silent",
"--show-error",
"--connect-timeout",
"--max-time",
"--permission-profile",
"--use-legacy-landlock",
"--command-cwd",
"--allow-network-for-proxy"
],
"files": [
{
"additions": 3,
"deletions": 0,
"patch_excerpt": "@@ -3,6 +3,9 @@ load(\"//:defs.bzl\", \"MACOS_WEBRTC_RUSTC_LINK_FLAGS\", \"codex_rust_crate\", \"multip\n codex_rust_crate(\n name = \"cli\",\n crate_name = \"codex_cli\",\n+ extra_binaries = [\n+ \"//codex-rs/bwrap:bwrap\",\n+ ],\n rustc_flags_extra = MACOS_WEBRTC_RUSTC_LINK_FLAGS,\n )",
"path": "codex-rs/cli/BUILD.bazel",
"status": "modified"
},
{
"additions": 5,
"deletions": 2,
"patch_excerpt": "@@ -258,6 +258,9 @@ async fn run_command_under_sandbox(\n let network = network_proxy\n .as_ref()\n .map(codex_core::config::StartedNetworkProxy::proxy);\n+ // Proxy containment depends on whether a proxy is active, not whether its\n+ // policy came from managed requirements.\n+ let enforce_managed_network = network.is_some();\n let managed_mitm_ca_trust_bundle_path = match network.as_ref() {\n Some(network) => network.managed_mitm_ca_trust_bundle_path(),\n None => None,\n@@ -278,7 +281,7 @@ async fn run_command_under_sandbox(\n file_system_sandbox_policy: &file_system_sandbox_policy,\n network_sandbox_policy,\n sandbox_policy_cwd: sandbox_policy_cwd.as_path(),\n- enforce_managed_network: false,\n+ enforce_managed_network,\n network: network.as_ref(),\n ...",
"path": "codex-rs/cli/src/debug_sandbox.rs",
"status": "modified"
},
{
"additions": 70,
"deletions": 0,
"patch_excerpt": "@@ -0,0 +1,70 @@\n+#![cfg(target_os = \"linux\")]\n+\n+use std::net::TcpListener;\n+\n+use anyhow::Result;\n+use tempfile::TempDir;\n+\n+const BWRAP_UNAVAILABLE_ERR: &str = \"bubblewrap is unavailable\";\n+\n+#[test]\n+fn sandbox_with_network_proxy_blocks_direct_loopback_access() -> Result<()> {\n+ let codex_home = TempDir::new()?;\n+ let listener = TcpListener::bind(\"127.0.0.2:0\")?;\n+ let port = listener.local_addr()?.port();\n+ std::fs::write(\n+ codex_home.path().join(\"config.toml\"),\n+ r#\"\n+default_permissions = \"network-test\"\n+\n+[features]\n+network_proxy = true\n+use_legacy_landlock = true\n+\n+[permissions.network-test]\n+extends = \":workspace\"\n+\n+[permissions.network-test.network]\n+enabled = true\n+mode = \"full\"\n+\"#,\n+ )?;\n+\n+ let url = format!(\"http://127.0.0.2:{port}/\");\n+ let output = std::process::Command::new(codex_utils_cargo_bin::cargo_bin(\"codex\")?)\n+ .env...",
"path": "codex-rs/cli/tests/sandbox_network_proxy.rs",
"status": "added"
},
{
"additions": 4,
"deletions": 2,
"patch_excerpt": "@@ -47,7 +47,8 @@ pub fn create_linux_sandbox_command_args_for_permission_profile(\n \"--permission-profile\".to_string(),\n permission_profile_json,\n ];\n- if use_legacy_landlock {\n+ // Proxy-only networking requires bubblewrap's isolated network namespace.\n+ if use_legacy_landlock && !allow_network_for_proxy {\n linux_cmd.push(\"--use-legacy-landlock\".to_string());\n }\n if allow_network_for_proxy {\n@@ -83,7 +84,8 @@ fn create_linux_sandbox_command_args(\n \"--command-cwd\".to_string(),\n command_cwd,\n ];\n- if use_legacy_landlock {\n+ // Proxy-only networking requires bubblewrap's isolated network namespace.\n+ if use_legacy_landlock && !allow_network_for_proxy {\n linux_cmd.push(\"--use-legacy-landlock\".to_string());\n }\n if allow_network_for_proxy {",
"path": "codex-rs/sandboxing/src/landlock.rs",
"status": "modified"
},
{
"additions": 5,
"deletions": 2,
"patch_excerpt": "@@ -33,14 +33,16 @@ fn legacy_landlock_flag_is_included_when_requested() {\n }\n \n #[test]\n-fn proxy_flag_is_included_when_requested() {\n+fn proxy_flag_takes_precedence_over_legacy_landlock() {\n let command = vec![\"/bin/true\".to_string()];\n let command_cwd = Path::new(\"/tmp/link\");\n let cwd = Path::new(\"/tmp\");\n+ let permission_profile = PermissionProfile::read_only();\n \n- let args = create_linux_sandbox_command_args(\n+ let args = create_linux_sandbox_command_args_for_permission_profile(\n command,\n command_cwd,\n+ &permission_profile,\n cwd,\n /*use_legacy_landlock*/ true,\n /*allow_network_for_proxy*/ true,\n@@ -49,6 +51,7 @@ fn proxy_flag_is_included_when_requested() {\n args.contains(&\"--allow-network-for-proxy\".to_string()),\n true\n );\n+ assert_eq!(args.contains(&\"--use-legacy-landlock\".to_string()), fa...",
"path": "codex-rs/sandboxing/src/landlock_tests.rs",
"status": "modified"
},
{
"additions": 2,
"deletions": 2,
"patch_excerpt": "@@ -338,8 +338,8 @@ fn ensure_linux_bubblewrap_is_supported(\n allow_network_for_proxy: bool,\n is_wsl1: bool,\n ) -> Result<(), SandboxTransformError> {\n- let requires_bubblewrap = !use_legacy_landlock\n- && (!file_system_sandbox_policy.has_full_disk_write_access() || allow_network_for_proxy);\n+ let requires_bubblewrap = allow_network_for_proxy\n+ || (!use_legacy_landlock && !file_system_sandbox_policy.has_full_disk_write_access());\n if is_wsl1 && requires_bubblewrap {\n return Err(SandboxTransformError::Wsl1UnsupportedForBubblewrap);\n }",
"path": "codex-rs/sandboxing/src/manager.rs",
"status": "modified"
},
{
"additions": 9,
"deletions": 0,
"patch_excerpt": "@@ -342,6 +342,15 @@ fn wsl1_rejects_linux_bubblewrap_path() {\n ),\n Err(super::SandboxTransformError::Wsl1UnsupportedForBubblewrap)\n ));\n+ assert!(matches!(\n+ super::ensure_linux_bubblewrap_is_supported(\n+ &FileSystemSandboxPolicy::unrestricted(),\n+ /*use_legacy_landlock*/ true,\n+ /*allow_network_for_proxy*/ true,\n+ /*is_wsl1*/ true,\n+ ),\n+ Err(super::SandboxTransformError::Wsl1UnsupportedForBubblewrap)\n+ ));\n }\n \n #[cfg(target_os = \"linux\")]",
"path": "codex-rs/sandboxing/src/manager_tests.rs",
"status": "modified"
}
],
"linked_issues": [],
"notes": [
"Built from GitHub pull-request, commits, files, and repo endpoints."
],
"primary_pr": {
"body": "## Why\n\n`codex sandbox` can start a network proxy from a configured permission profile. Previously, sandbox-level containment was tied to managed network requirements rather than whether a proxy was actually active. This meant config-driven proxy policies were not consistently enforced as the sandbox's only network path.\n\n## What changed\n\n- Enable proxy-only network containment whenever `codex sandbox` starts a network proxy.\n- Apply the same active-proxy check to the macOS and Linux sandbox paths.\n- Add a Linux regression test that verifies a sandboxed command cannot establish a direct connection while the configured proxy is active.\n\n## Test plan\n\n- `just test -p codex-cli debug_sandbox::tests`\n- `sandbox_with_network_proxy_blocks_direct_loopback_access` runs on Linux to cover the config-driven proxy path end to end.\n",
"labels": [],
"merged_at": "2026-06-08T21:03:37Z",
"number": 27035,
"state": "merged",
"title": "Enforce configured network proxy in codex sandbox",
"url": "https://github.com/openai/codex/pull/27035"
},
"repo": "openai/codex",
"schema": "github_change_bundle/v1"
}
65 changes: 65 additions & 0 deletions artifacts/github/bundles/openai-codex-pr-27068.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"analysis_mode": "pr_first",
"commits": [
{
"author": "canvrno-oai",
"committed_at": "2026-06-08T21:36:22Z",
"message": "Fix debug config sandbox mode rendering",
"sha": "c84c6bbd105eeef517ee1411a75fc7f06f2a9515",
"url": "https://github.com/openai/codex/commit/c84c6bbd105eeef517ee1411a75fc7f06f2a9515"
},
{
"author": "canvrno-oai",
"committed_at": "2026-06-08T21:57:15Z",
"message": "Merge branch 'main' into codex/debug-config-effective-sandbox-modes",
"sha": "aef829d185388be2dfa51b4d66be78836176ab92",
"url": "https://github.com/openai/codex/commit/aef829d185388be2dfa51b4d66be78836176ab92"
},
{
"author": "canvrno-oai",
"committed_at": "2026-06-08T22:24:03Z",
"message": "Add debug config sandbox mode snapshot",
"sha": "65c5b125134e8afa0c7dd86014d95c490e791671",
"url": "https://github.com/openai/codex/commit/65c5b125134e8afa0c7dd86014d95c490e791671"
}
],
"default_branch": "main",
"docs_refs": [],
"examples_refs": [],
"extracted_flags": [
"TOML",
"CONFIG_TOML_FILE",
"MDM"
],
"files": [
{
"additions": 143,
"deletions": 11,
"patch_excerpt": "@@ -1,5 +1,6 @@\n use crate::history_cell::PlainHistoryCell;\n use crate::legacy_core::config::Config;\n+use crate::legacy_core::config::Permissions;\n use crate::session_state::SessionNetworkProxyRuntime;\n use codex_app_server_protocol::ConfigLayerSource;\n use codex_config::CONFIG_TOML_FILE;\n@@ -15,6 +16,8 @@ use codex_config::ResidencyRequirement;\n use codex_config::SandboxModeRequirement;\n use codex_config::WebSearchModeRequirement;\n use codex_config::format_config_layer_source;\n+use codex_protocol::models::PermissionProfile;\n+use codex_protocol::permissions::NetworkSandboxPolicy;\n use ratatui::style::Stylize;\n use ratatui::text::Line;\n use toml::Value as TomlValue;\n@@ -23,7 +26,9 @@ pub(crate) fn new_debug_config_output(\n config: &Config,\n session_network_proxy: Option<&SessionNetworkProxyRuntime>,\n ) -> PlainHistoryCell {\n- let mut lines = render_debug_config_lines(&config.co...",
"path": "codex-rs/tui/src/debug_config.rs",
"status": "modified"
},
{
"additions": 12,
"deletions": 0,
"patch_excerpt": "@@ -0,0 +1,12 @@\n+---\n+source: tui/src/debug_config.rs\n+expression: rendered.as_str()\n+---\n+/debug-config\n+\n+Config layer stack (lowest precedence first):\n+ <none>\n+\n+Requirements:\n+ - allowed_sandbox_modes: read-only, workspace-write (source: /etc/codex/requirements.toml)\n+ - permissions.filesystem.deny_read: /home/alice/.gitconfig (source: /etc/codex/requirements.toml)",
"path": "codex-rs/tui/src/snapshots/codex_tui__debug_config__tests__debug_config_effective_sandbox_modes_with_deny_read.snap",
"status": "added"
}
],
"linked_issues": [],
"notes": [
"Built from GitHub pull-request, commits, files, and repo endpoints."
],
"primary_pr": {
"body": "## Summary\n- Render `/debug-config`'s `allowed_sandbox_modes` from the finalized permission constraints instead of the raw requirements list.\n- Add regression coverage for configured full-access and external sandbox modes being omitted when effective permissions reject them.\n\n## Details\n`allowed_sandbox_modes` comes from managed requirements, but the final permissions can be further constrained by derived validation rules. For example, `permissions.filesystem.deny_read` requires sandbox enforcement, so modes that disable or externalize Codex's sandbox are not actually usable even if they were present in the raw requirements TOML.\n\nThe debug renderer now enumerates the configured sandbox-mode labels and keeps only those accepted by `Config.permissions`. That makes `/debug-config` reflect the same effective permission-profile constraint path used by runtime config validation, while preserving the existing source/provenance display.\n\n## Validation\n- Added a regression test for effective sandbox-mode filtering in `/debug-config`.\n",
"labels": [],
"merged_at": "2026-06-09T00:03:53Z",
"number": 27068,
"state": "merged",
"title": "Show effective sandbox modes in /debug-config",
"url": "https://github.com/openai/codex/pull/27068"
},
"repo": "openai/codex",
"schema": "github_change_bundle/v1"
}
Loading