mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
e476fc16ce810495cbfabe4f815d20947da0ba79
33 Commits
-
Prepare managed network sandbox context (#29456)
## Why Managed network configures commands to use local HTTP and SOCKS proxies. For commands delegated to the exec server, the proxy environment and the sandbox policy were prepared separately. On macOS, that meant a command could receive `HTTPS_PROXY=http://127.0.0.1:43123` while Seatbelt still denied access to port `43123`. ## What changed `NetworkProxy` now prepares the command environment and sandbox context together from the same runtime snapshot: ```text Prepared managed network ├── command environment: HTTPS_PROXY=http://127.0.0.1:43123 └── sandbox context: allow outbound to 127.0.0.1:43123 ``` That context travels with remote exec requests. The exec server preserves the managed proxy and CA environment, and macOS Seatbelt allows only the prepared loopback proxy ports without enabling broad network access or local binding. The protocol field is optional and the existing enforcement flag remains in place, preserving compatibility with callers that do not send the new context.
jif ·
2026-06-23 20:07:09 +01:00 -
Honor startup custom CA bundles with managed MITM (#29014)
## Why When Codex starts with a custom CA override such as `SSL_CERT_FILE=/path/to/corp-ca.pem codex`, `rustls-native-certs` treats that override as a replacement for the platform trust store. The managed proxy then rewrites child CA variables to its generated bundle, so the custom root or the ordinary platform roots can be lost. The proxy's upstream TLS connector must trust the same roots or private and corporate upstream certificates still fail after interception. ## What - load platform-native roots without consulting inherited CA override variables - append certificates from the existing curated startup CA file variables and `SSL_CERT_DIR` - share those platform and startup roots with the MITM upstream rustls connector - exclude the Codex managed MITM CA from upstream trust - normalize OpenSSL `TRUSTED CERTIFICATE` blocks while dropping trailing trust metadata - skip an inherited current Codex-managed bundle so nested launches do not duplicate it - append the Codex managed MITM CA to the child-facing bundle - copy certificate material only, so a private key or unrelated text colocated in a startup file is never exposed through the public bundle This is intentionally limited to CA paths present when Codex starts. It does not parse inline shell assignments or add per-command bundle materialization. This changes only `codex-network-proxy` and dependency metadata; it does not touch `codex-core` or sandbox orchestration. ## Validation - `just test -p codex-network-proxy` - includes an end-to-end upstream TLS test using a server trusted only by the startup custom CA - `just fix -p codex-network-proxy` - `just bazel-lock-check`
Winston Howes ·
2026-06-22 14:16:48 -07:00 -
Scope network approvals by environment (#28899)
Stacked on #28766. ## Why Network approvals are environment-scoped: allowing a host in one execution environment should not allow the same host in another environment. #28766 adds the inert IDs and constructor plumbing. This PR applies the behavior on top. ## What changed - Route managed network traffic through per-environment HTTP and SOCKS proxy listeners. - Stamp HTTP, HTTPS CONNECT, SOCKS TCP, and SOCKS UDP policy requests with the source environment at the proxy boundary. - Carry the selected execution environment through shell, unified exec, zsh-fork, and sandbox transform paths. - Include the environment in pending, approved-for-session, and denied-for-session network approval cache keys. - Include the environment in approval IDs and approval prompts. - Preserve legacy fallback for unattributed requests, but deny when active-call attribution is ambiguous. - Fail closed if an environment-specific proxy endpoint cannot be prepared. ## Validation - just fmt - CI will run tests and clippy
jif ·
2026-06-19 13:49:45 +02:00 -
Wire managed MITM CA trust into child env (#22668)
## Stack 1. Parent PR: #18240 uses named MITM permissions config. 2. This PR wires managed MITM CA trust into spawned child processes. ## Why When Codex terminates HTTPS for limited mode or MITM hooks, child HTTPS clients need to trust Codex's managed MITM CA. Exporting proxy URLs alone is not enough, but blindly replacing user CA settings would be wrong: it can break custom enterprise/test roots, leak unreadable CA files into generated bundles, or make the child env disagree with its sandbox policy. ## Summary 1. Build immutable managed CA bundles under `$CODEX_HOME/proxy` that include native roots, the managed MITM CA, and only inherited or command-scoped CA bundles the child is allowed to read. 2. Export curated CA env vars alongside managed proxy env vars while preserving user CA override semantics, including nested Codex `SSL_CERT_FILE` precedence. 3. Thread generated CA bundle paths into child sandbox readable roots, including debug sandbox execution, so the exported env vars work inside sandboxed commands. 4. Remove only Codex-generated MITM CA bundle env when a child intentionally drops managed proxying for escalation or no-proxy retry. 5. Document the managed CA bundle behavior and cover env injection, per-child bundle generation, sandbox readable roots, and no-proxy cleanup in tests. ## Validation 1. Ran `just test -p codex-network-proxy`. 2. Ran `just test -p codex-protocol`. 3. Ran `just fix -p codex-network-proxy -p codex-protocol`. 4. Tried focused `codex-core` validation, but the crate currently fails to compile in `core/tests/suite/guardian_review.rs` because an existing `Op::UserInput` initializer is missing `additional_context`. --------- Co-authored-by: Eva Wong <evawong@openai.com>
Winston Howes ·
2026-06-01 23:23:59 +00:00 -
[codex] Enable Node env proxy for managed network proxy (#23905)
## Summary - set `NODE_USE_ENV_PROXY=1` when Codex applies managed network proxy environment overrides - keep the Node opt-in in the proxy environment key set used by shell/runtime env handling - cover the new env var in the focused network proxy env test ## Why Codex already sets HTTP proxy environment variables for child processes when the managed network proxy is active. Node's built-in network behavior needs the `NODE_USE_ENV_PROXY` opt-in to honor those env vars, so Node-based skill scripts can otherwise skip the managed proxy path and fail under restricted network access. ## Validation - `just fmt` in `codex-rs` - `cargo test -p codex-network-proxy` in `codex-rs`
rreichel3-oai ·
2026-05-22 01:27:25 -04:00 -
fix(network-proxy): normalize network proxy host matching (#19995)
## Why The proxy matches allow and deny rules against normalized host strings. Scoped IPv6 literals can arrive in equivalent forms, such as `fd00::1%eth0`, `[fd00::1%eth0]`, or `[fd00::1%25eth0]`. Policy should canonicalize those spellings without erasing scope granularity: an unscoped rule like `fd00::1` should still cover scoped requests for that address, while a scoped rule like `fd00::1%eth0` should remain exact to that scope. ## What changed - preserve IPv6 scope IDs during host normalization and canonicalize `%25scope` to `%scope` - match policy against the exact normalized host plus the unscoped IP base for scoped literals - keep local-address explicit allow checks aligned with the same scoped/unscoped semantics - add focused coverage for scoped IPv6 normalization, scoped allow rules, and scoped deny rules in `network-proxy` ## Security impact A request cannot bypass a broad deny rule by adding an IPv6 scope suffix. At the same time, scoped policy remains precise: `deny=fd00::1%eth0` affects that scoped spelling without collapsing `fd00::1%eth1` onto the same key, and `allow=fe80::1%eth0` does not implicitly allow other scopes. ## Verification - `just fmt` - `cargo test -p codex-network-proxy` - `just fix -p codex-network-proxy` - `git diff --check` --------- Co-authored-by: Codex <noreply@openai.com> Co-authored-by: evawong-oai <evawong@openai.com>
viyatb-oai ·
2026-04-28 15:50:00 -07:00 -
fix(network-proxy): tighten network proxy bypass defaults (#20002)
## Why Managed sessions use `NO_PROXY` to keep a small set of destinations on the direct path by default. The old default also bypassed all IPv4 link-local addresses in `169.254.0.0/16`, which includes metadata endpoints such as `169.254.169.254`. Because `NO_PROXY` is evaluated by the client before the request reaches the managed proxy, requests to that range could skip proxy-side allowlist and local-binding checks entirely. On hosts where a link-local metadata service is reachable, that creates a path to sensitive environment metadata or credentials outside the intended enforcement point. ## What changed - remove the default IPv4 link-local `169.254.0.0/16` bypass from the managed proxy environment - keep the existing loopback and private-network defaults unchanged - update the regression assertion to lock in the narrower default ## Security impact Link-local requests now stay on the managed-proxy path by default, so the proxy can apply configured policy before they reach metadata-style endpoints or other link-local services. ## Verification - `cargo test -p codex-network-proxy` Co-authored-by: Codex <noreply@openai.com>
viyatb-oai ·
2026-04-28 10:51:43 -07:00 -
fix: fix stale proxy env restoration after shell snapshots (#17271)
## Summary This fixes a stale-environment path in shell snapshot restoration. A sandboxed command can source a shell snapshot that was captured while an older proxy process was running. If that proxy has died and come back on a different port, the snapshot can otherwise put old proxy values back into the command environment, which is how tools like `pip` end up talking to a dead proxy. The wrapper now captures the live process environment before sourcing the snapshot and then restores or clears every proxy env var from the proxy crate's canonical list. That makes proxy state after shell snapshot restoration match the current command environment, rather than whatever proxy values happened to be present in the snapshot. On macOS, the Codex-generated `GIT_SSH_COMMAND` is refreshed when the SOCKS listener changes, while custom SSH wrappers are still left alone. --------- Co-authored-by: Codex <noreply@openai.com>
viyatb-oai ·
2026-04-20 16:39:17 -07:00 -
fix: unblock private DNS in macOS sandbox (#17370)
## Summary - keep hostname targets proxied by default by removing hostname suffixes from the managed `NO_PROXY` value while preserving private/link-local CIDRs - make the macOS `allow_local_binding` sandbox rules match the local socket shape used by DNS tools by allowing wildcard local binds - allow raw DNS egress to remote port 53 only when `allow_local_binding` is enabled, without opening blanket outbound network access ## Root cause Raw DNS tools do not honor `HTTP_PROXY` or `ALL_PROXY`, so the proxy-only Seatbelt policy blocked their resolver traffic before it could reach host DNS. In the affected managed config, `allow_local_binding = true`, but the existing rule only allowed `localhost:*` binds; `dig`/BIND can bind sockets in a way that needs wildcard local binding. Separately, hostname suffixes in `NO_PROXY` could force internal hostnames to resolve locally instead of through the proxy path. --------- Co-authored-by: Codex <noreply@openai.com>
viyatb-oai ·
2026-04-10 20:34:04 -07:00 -
fix: refresh network proxy settings when sandbox mode changes (#17040)
## Summary Fix network proxy sessions so changing sandbox mode recomputes the effective managed network policy and applies it to the already-running per-session proxy. ## Root Cause `danger_full_access_denylist_only` injects `"*"` only while building the proxy spec for Full Access. Sessions built that spec once at startup, so a later permission switch to Full Access left the live proxy in its original restricted policy. Switching back needed the same recompute path to remove the synthetic wildcard again. ## What Changed - Preserve the original managed network proxy config/requirements so the effective spec can be recomputed for a new sandbox policy. - Refresh the current session proxy when sandbox settings change, then reapply exec-policy network overlays. - Add an in-place proxy state update path while rejecting listener/port/SOCKS changes that cannot be hot-reloaded. - Keep runtime proxy settings cheap to snapshot and update. - Add regression coverage for workspace-write -> Full Access -> workspace-write.
viyatb-oai ·
2026-04-08 03:07:55 +00:00 -
fix: clean up remaining Windows argument-comment-lint violations (#16071)
## Why The initial `argument-comment-lint` rollout left Windows on default-target coverage because there were still Windows-only callsites failing under `--all-targets`. This follow-up cleans up those remaining Windows-specific violations so the Windows CI lane can enforce the same stricter coverage, leaving Linux as the remaining platform-specific follow-up. ## What changed - switched the Windows `rust-ci` argument-comment-lint step back to the default wrapper invocation so it runs full-target coverage again - added the required `/*param_name*/` annotations at Windows-gated literal callsites in: - `codex-rs/windows-sandbox-rs/src/lib.rs` - `codex-rs/windows-sandbox-rs/src/elevated_impl.rs` - `codex-rs/tui_app_server/src/multi_agents.rs` - `codex-rs/network-proxy/src/proxy.rs` ## Validation - Windows `argument comment lint` CI on this PR
Michael Bolin ·
2026-03-27 20:48:21 -07:00 -
chore: clean up argument-comment lint and roll out all-target CI on macOS (#16054)
## Why `argument-comment-lint` was green in CI even though the repo still had many uncommented literal arguments. The main gap was target coverage: the repo wrapper did not force Cargo to inspect test-only call sites, so examples like the `latest_session_lookup_params(true, ...)` tests in `codex-rs/tui_app_server/src/lib.rs` never entered the blocking CI path. This change cleans up the existing backlog, makes the default repo lint path cover all Cargo targets, and starts rolling that stricter CI enforcement out on the platform where it is currently validated. ## What changed - mechanically fixed existing `argument-comment-lint` violations across the `codex-rs` workspace, including tests, examples, and benches - updated `tools/argument-comment-lint/run-prebuilt-linter.sh` and `tools/argument-comment-lint/run.sh` so non-`--fix` runs default to `--all-targets` unless the caller explicitly narrows the target set - fixed both wrappers so forwarded cargo arguments after `--` are preserved with a single separator - documented the new default behavior in `tools/argument-comment-lint/README.md` - updated `rust-ci` so the macOS lint lane keeps the plain wrapper invocation and therefore enforces `--all-targets`, while Linux and Windows temporarily pass `-- --lib --bins` That temporary CI split keeps the stricter all-targets check where it is already cleaned up, while leaving room to finish the remaining Linux- and Windows-specific target-gated cleanup before enabling `--all-targets` on those runners. The Linux and Windows failures on the intermediate revision were caused by the wrapper forwarding bug, not by additional lint findings in those lanes. ## Validation - `bash -n tools/argument-comment-lint/run.sh` - `bash -n tools/argument-comment-lint/run-prebuilt-linter.sh` - shell-level wrapper forwarding check for `-- --lib --bins` - shell-level wrapper forwarding check for `-- --tests` - `just argument-comment-lint` - `cargo test` in `tools/argument-comment-lint` - `cargo test -p codex-terminal-detection` ## Follow-up - Clean up remaining Linux-only target-gated callsites, then switch the Linux lint lane back to the plain wrapper invocation. - Clean up remaining Windows-only target-gated callsites, then switch the Windows lint lane back to the plain wrapper invocation.
Michael Bolin ·
2026-03-27 19:00:44 -07:00 -
chore: refactor network permissions to use explicit domain and unix socket rule maps (#15120)
## Summary This PR replaces the legacy network allow/deny list model with explicit rule maps for domains and unix sockets across managed requirements, permissions profiles, the network proxy config, and the app server protocol. Concretely, it: - introduces typed domain (`allow` / `deny`) and unix socket permission (`allow` / `none`) entries instead of separate `allowed_domains`, `denied_domains`, and `allow_unix_sockets` lists - updates config loading, managed requirements merging, and exec-policy overlays to read and upsert rule entries consistently - exposes the new shape through protocol/schema outputs, debug surfaces, and app-server config APIs - rejects the legacy list-based keys and updates docs/tests to reflect the new config format ## Why The previous representation split related network policy across multiple parallel lists, which made merging and overriding rules harder to reason about. Moving to explicit keyed permission maps gives us a single source of truth per host/socket entry, makes allow/deny precedence clearer, and gives protocol consumers access to the full rule state instead of derived projections only. ## Backward Compatibility ### Backward compatible - Managed requirements still accept the legacy `experimental_network.allowed_domains`, `experimental_network.denied_domains`, and `experimental_network.allow_unix_sockets` fields. They are normalized into the new canonical `domains` and `unix_sockets` maps internally. - App-server v2 still deserializes legacy `allowedDomains`, `deniedDomains`, and `allowUnixSockets` payloads, so older clients can continue reading managed network requirements. - App-server v2 responses still populate `allowedDomains`, `deniedDomains`, and `allowUnixSockets` as legacy compatibility views derived from the canonical maps. - `managed_allowed_domains_only` keeps the same behavior after normalization. Legacy managed allowlists still participate in the same enforcement path as canonical `domains` entries. ### Not backward compatible - Permissions profiles under `[permissions.<profile>.network]` no longer accept the legacy list-based keys. Those configs must use the canonical `[domains]` and `[unix_sockets]` tables instead of `allowed_domains`, `denied_domains`, or `allow_unix_sockets`. - Managed `experimental_network` config cannot mix canonical and legacy forms in the same block. For example, `domains` cannot be combined with `allowed_domains` or `denied_domains`, and `unix_sockets` cannot be combined with `allow_unix_sockets`. - The canonical format can express explicit `"none"` entries for unix sockets, but those entries do not round-trip through the legacy compatibility fields because the legacy fields only represent allow/deny lists. ## Testing `/target/debug/codex sandbox macos --log-denials /bin/zsh -c 'curl https://www.example.com' ` gives 200 with config ``` [permissions.workspace.network.domains] "www.example.com" = "allow" ``` and fails when set to deny: `curl: (56) CONNECT tunnel failed, response 403`. Also tested backward compatibility path by verifying that adding the following to `/etc/codex/requirements.toml` works: ``` [experimental_network] allowed_domains = ["www.example.com"] ```
Celia Chen ·
2026-03-27 06:17:59 +00:00 -
feat(windows-sandbox): add network proxy support (#12220)
## Summary This PR makes Windows sandbox proxying enforceable by routing proxy-only runs through the existing `offline` sandbox user and reserving direct network access for the existing `online` sandbox user. In brief: - if a Windows sandbox run should be proxy-enforced, we run it as the `offline` user - the `offline` user gets firewall rules that block direct outbound traffic and only permit the configured localhost proxy path - if a Windows sandbox run should have true direct network access, we run it as the `online` user - no new sandbox identity is introduced This brings Windows in line with the intended model: proxy use is not just env-based, it is backed by OS-level egress controls. Windows already has two sandbox identities: - `offline`: intended to have no direct network egress - `online`: intended to have full network access This PR makes proxy-enforced runs use that model directly. ### Proxy-enforced runs When proxy enforcement is active: - the run is assigned to the `offline` identity - setup extracts the loopback proxy ports from the sandbox env - Windows setup programs firewall rules for the `offline` user that: - block all non-loopback outbound traffic - block loopback UDP - block loopback TCP except for the configured proxy ports - optionally allow broader localhost access when `allow_local_binding=1` So the sandboxed process can only talk to the local proxy. It cannot open direct outbound sockets or do local UDP-based DNS on its own.The proxy then performs the real outbound network access outside that restricted sandbox identity. ### Direct-network runs When proxy enforcement is not active and full network access is allowed: - the run is assigned to the `online` identity - no proxy-only firewall restrictions are applied - the process gets normal direct network access ### Unelevated vs elevated The restricted-token / unelevated path cannot enforce per-identity firewall policy by itself. So for Windows proxy-enforced runs, we transparently use the logon-user sandbox path under the hood, even if the caller started from the unelevated mode. That keeps enforcement real instead of best-effort. --------- Co-authored-by: Codex <noreply@openai.com>
viyatb-oai ·
2026-03-26 17:27:38 -07:00 -
fix(network-proxy): serve HTTP proxy listener as HTTP/1 (#14395)
## Summary - switch the local HTTP proxy listener from Rama's auto server to explicit HTTP/1 so CONNECT clients skip the version-sniffing pre-read path - move rustls crypto-provider bootstrap into the HTTP proxy runner so direct callers do not need hidden global init - add a regression test that exercises a plain HTTP/1 CONNECT request against a live loopback listener
viyatb-oai ·
2026-03-11 14:35:44 -07:00 -
Add guardian approval MVP (#13692)
## Summary - add the guardian reviewer flow for `on-request` approvals in command, patch, sandbox-retry, and managed-network approval paths - keep guardian behind `features.guardian_approval` instead of exposing a public `approval_policy = guardian` mode - route ordinary `OnRequest` approvals to the guardian subagent when the feature is enabled, without changing the public approval-mode surface ## Public model - public approval modes stay unchanged - guardian is enabled via `features.guardian_approval` - when that feature is on, `approval_policy = on-request` keeps the same approval boundaries but sends those approval requests to the guardian reviewer instead of the user - `/experimental` only persists the feature flag; it does not rewrite `approval_policy` - CLI and app-server no longer expose a separate `guardian` approval mode in this PR ## Guardian reviewer - the reviewer runs as a normal subagent and reuses the existing subagent/thread machinery - it is locked to a read-only sandbox and `approval_policy = never` - it does not inherit user/project exec-policy rules - it prefers `gpt-5.4` when the current provider exposes it, otherwise falls back to the parent turn's active model - it fail-closes on timeout, startup failure, malformed output, or any other review error - it currently auto-approves only when `risk_score < 80` ## Review context and policy - guardian mirrors `OnRequest` approval semantics rather than introducing a separate approval policy - explicit `require_escalated` requests follow the same approval surface as `OnRequest`; the difference is only who reviews them - managed-network allowlist misses that enter the approval flow are also reviewed by guardian - the review prompt includes bounded recent transcript history plus recent tool call/result evidence - transcript entries and planned-action strings are truncated with explicit `<guardian_truncated ... />` markers so large payloads stay bounded - apply-patch reviews include the full patch content (without duplicating the structured `changes` payload) - the guardian request layout is snapshot-tested using the same model-visible Responses request formatter used elsewhere in core ## Guardian network behavior - the guardian subagent inherits the parent session's managed-network allowlist when one exists, so it can use the same approved network surface while reviewing - exact session-scoped network approvals are copied into the guardian session with protocol/port scope preserved - those copied approvals are now seeded before the guardian's first turn is submitted, so inherited approvals are available during any immediate review-time checks ## Out of scope / follow-ups - the sandbox-permission validation split was pulled into a separate PR and is not part of this diff - a future follow-up can enable `serde_json` preserve-order in `codex-core` and then simplify the guardian action rendering further --------- Co-authored-by: Codex <noreply@openai.com>
Charley Cunningham ·
2026-03-07 05:40:10 -08:00 -
refactor: remove proxy admin endpoint (#13687)
## Summary - delete the network proxy admin server and its runtime listener/task plumbing - remove the admin endpoint config, runtime, requirement, protocol, schema, and debug-surface fields - update proxy docs to reflect the remaining HTTP and SOCKS listeners only
viyatb-oai ·
2026-03-05 22:03:16 -08:00 -
feat(core): persist network approvals in execpolicy (#12357)
## Summary Persist network approval allow/deny decisions as `network_rule(...)` entries in execpolicy (not proxy config) It adds `network_rule` parsing + append support in `codex-execpolicy`, including `decision="prompt"` (parse-only; not compiled into proxy allow/deny lists) - compile execpolicy network rules into proxy allow/deny lists and update the live proxy state on approval - preserve requirements execpolicy `network_rule(...)` entries when merging with file-based execpolicy - reject broad wildcard hosts (for example `*`) for persisted `network_rule(...)`
viyatb-oai ·
2026-02-23 21:37:46 -08:00 -
fix(network-proxy): add unix socket allow-all and update seatbelt rules (#11368)
## Summary Adds support for a Unix socket escape hatch so we can bypass socket allowlisting when explicitly enabled. ## Description * added a new flag, `network.dangerously_allow_all_unix_sockets` as an explicit escape hatch * In codex-network-proxy, enabling that flag now allows any absolute Unix socket path from x-unix-socket instead of requiring each path to be explicitly allowlisted. Relative paths are still rejected. * updated the macOS seatbelt path in core so it enforces the same Unix socket behavior: * allowlisted sockets generate explicit network* subpath rules * allow-all generates a broad network* (subpath "/") rule --------- Co-authored-by: Codex <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
viyatb-oai ·
2026-02-20 10:56:57 -08:00 -
Refactor network approvals to host/protocol/port scope (#12140)
## Summary Simplify network approvals by removing per-attempt proxy correlation and moving to session-level approval dedupe keyed by (host, protocol, port). Instead of encoding attempt IDs into proxy credentials/URLs, we now treat approvals as a destination policy decision. - Concurrent calls to the same destination share one approval prompt. - Different destinations (or same host on different ports) get separate prompts. - Allow once approves the current queued request group only. - Allow for session caches that (host, protocol, port) and auto-allows future matching requests. - Never policy continues to deny without prompting. Example: - 3 calls: - a.com (line 443) - b.com (line 443) - a.com (line 443) => 2 prompts total (a, b), second a waits on the first decision. - a.com:80 is treated separately from a.com line 443 ## Testing - `just fmt` (in `codex-rs`) - `cargo test -p codex-core tools::network_approval::tests` - `cargo test -p codex-core` (unit tests pass; existing integration-suite failures remain in this environment)
viyatb-oai ·
2026-02-20 10:39:55 -08:00 -
feat(network-proxy): add websocket proxy env support (#11784)
## Summary - add managed proxy env wiring for websocket-specific variables (`WS_PROXY`/`WSS_PROXY`, including lowercase) - keep websocket proxy vars aligned with the existing managed HTTP proxy endpoint - add CONNECT regression tests to cover allowlist and denylist decisions (websocket tunnel path) - document websocket proxy usage and CONNECT policy behavior in the network proxy README ## Testing - just fmt - cargo test -p codex-network-proxy - cargo clippy -p codex-network-proxy Co-authored-by: Codex <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
viyatb-oai ·
2026-02-17 13:49:43 -08:00 -
feat(core): add structured network approval plumbing and policy decision model (#11672)
### Description #### Summary Introduces the core plumbing required for structured network approvals #### What changed - Added structured network policy decision modeling in core. - Added approval payload/context types needed for network approval semantics. - Wired shell/unified-exec runtime plumbing to consume structured decisions. - Updated related core error/event surfaces for structured handling. - Updated protocol plumbing used by core approval flow. - Included small CLI debug sandbox compatibility updates needed by this layer. #### Why establishes the minimal backend foundation for network approvals without yet changing high-level orchestration or TUI behavior. #### Notes - Behavior remains constrained by existing requirements/config gating. - Follow-up PRs in the stack handle orchestration, UX, and app-server integration. --------- Co-authored-by: Codex <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
viyatb-oai ·
2026-02-14 04:18:12 +00:00 -
feat(network-proxy): structured policy signaling and attempt correlation to core (#11662)
## Summary When network requests were blocked, downstream code often had to infer ask vs deny from free-form response text. That was brittle and led to incorrect approval behavior. This PR fixes the proxy side so blocked decisions are structured and request metadata survives reliably. ## Description - Blocked proxy responses now carry consistent structured policy decision data. - Request attempt metadata is preserved across proxy env paths (including ALL_PROXY flows). - Header stripping was tightened so we still remove unsafe forwarding headers, but keep metadata needed for policy handling. - Block messages were clarified (for example, allowlist miss vs explicit deny). - Added unified violation log entries so policy failures can be inspected in one place. - Added/updated tests for these behaviors. --------- Co-authored-by: Codex <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
viyatb-oai ·
2026-02-13 09:01:11 +00:00 -
Enable SOCKS defaults for common local network proxy use cases (#11362)
## Summary - enable local-use defaults in network proxy settings: SOCKS5 on, SOCKS5 UDP on, upstream proxying on, and local binding on - add a regression test that asserts the full `NetworkProxySettings::default()` baseline - Fixed managed listener reservation behavior. Before: we always reserved a loopback SOCKS listener, even when enable_socks5 = false. Now: SOCKS listener is only reserved when SOCKS is enabled. - Fixed /debug-config env output for SOCKS-disabled sessions. ALL_PROXY now shows the HTTP proxy URL when SOCKS is disabled (instead of incorrectly showing socks5h://...). ## Validation - just fmt - cargo test -p codex-network-proxy - cargo clippy -p codex-network-proxy --all-targets
viyatb-oai ·
2026-02-10 15:13:52 -08:00 -
feat: retain NetworkProxy, when appropriate (#11207)
As of this PR, `SessionServices` retains a `Option<StartedNetworkProxy>`, if appropriate. Now the `network` field on `Config` is `Option<NetworkProxySpec>` instead of `Option<NetworkProxy>`. Over in `Session::new()`, we invoke `NetworkProxySpec::start_proxy()` to create the `StartedNetworkProxy`, which is a new struct that retains the `NetworkProxy` as well as the `NetworkProxyHandle`. (Note that `Drop` is implemented for `NetworkProxyHandle` to ensure the proxies are shutdown when it is dropped.) The `NetworkProxy` from the `StartedNetworkProxy` is threaded through to the appropriate places. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/11207). * #11285 * __->__ #11207
Michael Bolin ·
2026-02-10 02:09:23 -08:00 -
chore: put crypto provider logic in a shared crate (#11294)
Ensures a process-wide rustls crypto provider is installed. Both the `codex-network-proxy` and `codex-api` crates need this.
Michael Bolin ·
2026-02-10 01:04:31 -08:00 -
feat(sandbox): enforce proxy-aware network routing in sandbox (#11113)
## Summary - expand proxy env injection to cover common tool env vars (`HTTP_PROXY`/`HTTPS_PROXY`/`ALL_PROXY`/`NO_PROXY` families + tool-specific variants) - harden macOS Seatbelt network policy generation to route through inferred loopback proxy endpoints and fail closed when proxy env is malformed - thread proxy-aware Linux sandbox flags and add minimal bwrap netns isolation hook for restricted non-proxy runs - add/refresh tests for proxy env wiring, Seatbelt policy generation, and Linux sandbox argument wiring
viyatb-oai ·
2026-02-10 07:44:21 +00:00 -
feat: reserve loopback ephemeral listeners for managed proxy (#11269)
Codex may run many per-thread proxy instances, so hardcoded proxy ports are brittle and conflict-prone. The previous "ephemeral" approach still had a race: `build()` read `local_addr()` from temporary listeners and dropped them before `run()` rebound the ports. That left a [TOCTOU](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use) window where the OS (or another process) could reuse the same port, causing intermittent `EADDRINUSE` and partial proxy startup. Change the managed proxy path to reserve real listener sockets up front and keep them alive until startup: - add `ReservedListeners` on `NetworkProxy` to hold HTTP/SOCKS/admin std listeners allocated during `build()` - in managed mode, bind `127.0.0.1:0` for each listener and carry those bound sockets into `run()` instead of rebinding by address later - add `run_*_with_std_listener` entry points for HTTP, SOCKS5, and admin servers so `run()` can start services from already-reserved sockets - keep static/configured ports only when `managed_by_codex(false)`, including explicit `socks_addr` override support - remove fallback synthetic port allocation and add tests for managed ephemeral loopback binding and unmanaged configured-port behavior This makes managed startup deterministic, avoids port collisions, and preserves the intended distinction between Codex-managed ephemeral ports and externally managed fixed ports.
Michael Bolin ·
2026-02-10 06:11:02 +00:00 -
feat: include NetworkConfig through ExecParams (#11105)
This PR adds the following field to `Config`: ```rust pub network: Option<NetworkProxy>, ``` Though for the moment, it will always be initialized as `None` (this will be addressed in a subsequent PR). This PR does the work to thread `network` through to `execute_exec_env()`, `process_exec_tool_call()`, and `UnifiedExecRuntime.run()` to ensure it is available whenever we span a process.
Michael Bolin ·
2026-02-09 03:32:17 +00:00 -
Michael Bolin ·
2026-02-08 17:03:24 -08:00 -
refactor(network-proxy): flatten network config under [network] (#10965)
Summary: - Rename config table from network_proxy to network. - Flatten allowed_domains, denied_domains, allow_unix_sockets, and allow_local_binding onto NetworkProxySettings. - Update runtime, state constraints, tests, and README to the new config shape.
viyatb-oai ·
2026-02-07 05:22:44 +00:00 -
feat(network-proxy): add a SOCKS5 proxy with policy enforcement (#9803)
### Summary - Adds an optional SOCKS5 listener via `rama-socks5` - SOCKS5 is disabled by default and gated by config - Reuses existing policy enforcement and blocked-request recording - Blocks SOCKS5 in limited mode to prevent method-policy bypass - Applies bind clamping to the SOCKS5 listener ### Config New/used fields under `network_proxy`: - `enable_socks5` - `socks_url` - `enable_socks5_udp` ### Scope - Changes limited to `codex-rs/network-proxy` (+ `codex-rs/Cargo.lock`) ### Testing ```bash cd codex-rs just fmt cargo test -p codex-network-proxy --offline
viyatb-oai ·
2026-01-27 10:09:39 -08:00 -
feat: introducing a network sandbox proxy (#8442)
This add a new crate, `codex-network-proxy`, a local network proxy service used by Codex to enforce fine-grained network policy (domain allow/deny) and to surface blocked network events for interactive approvals. - New crate: `codex-rs/network-proxy/` (`codex-network-proxy` binary + library) - Core capabilities: - HTTP proxy support (including CONNECT tunneling) - SOCKS5 proxy support (in the later PR) - policy evaluation (allowed/denied domain lists; denylist wins; wildcard support) - small admin API for polling/reload/mode changes - optional MITM support for HTTPS CONNECT to enforce “limited mode” method restrictions (later PR) Will follow up integration with codex in subsequent PRs. ## Testing - `cd codex-rs && cargo build -p codex-network-proxy` - `cd codex-rs && cargo run -p codex-network-proxy -- proxy`
viyatb-oai ·
2026-01-23 17:47:09 -08:00