Commit Graph
396 Commits
Author SHA1 Message Date
jif 595534314f Use descriptor-safe helpers for executable test fixtures (#50018)
## Why

Concurrent Linux test spawns can inherit writable descriptors for executable fixtures, preventing those fixtures from being executed even after the writing test closes its descriptor.

## What changed

Replace direct executable fixture writes and copies across the Rust tests with `codex_utils_cargo_bin::write_executable` and `copy_executable`. These existing helpers complete writes and copies in separate processes on Linux.

Remove the empty temporary inode before creating fake bubblewrap executables, and stage tampered bubblewrap bytes in a separate data file before copying them into the executable fixture. Add the required test dependencies.

GitOrigin-RevId: c875c83088731a4933ef1574e8d79d8cecc12f54
2026-10-01 15:57:03 +00:00
Nick Steele ecc78e4cf5 Add renewable EMA HTTP authentication and credential versioning (#49987)
## What changed

- Add `EmaAuthenticatedHttpClient` to cache and renew resource bearers, serialize concurrent renewals, and include authentication time in the request deadline. Confine bearers to the configured MCP endpoint and reject redirects.
- Return authentication-required errors for `401` responses without replaying MCP operations. Preserve a newer cached bearer when a delayed response rejects an older one.
- Add revocable request authority that cancels pending requests and ends response streams.
- Pin enterprise credentials to a persistent version advanced on save or deletion. Use short credential locks and invalidate rejected grants only when their record and version are still current, preserving newer logins.
- Hide keyring account identifiers from enterprise credential errors and traces while preserving authentication failure classification.

## Testing

Add tests for token expiry and renewal, endpoint confinement, redirects, request deadlines, revocation during renewal and streaming, delayed `401` responses, credential replacement and logout races, and credential error privacy.

GitOrigin-RevId: ee3e5cf7ecbba3d09e1ab29ed4fbb2a35eacc60d
2026-10-01 13:57:48 +00:00
jif a933dd77db Share byte buffers across exec-server output chunks (#49972)
## Why

Retaining process output, publishing events, and serving reads cloned the underlying byte buffers. Sharing those buffers avoids copying output bytes when chunks are cloned.

## What changed

Store `ByteChunk` bytes in `Arc<Vec<u8>>` and retain `ProcessOutputChunk` values directly. Add borrowed byte access for the MCP process transport while preserving base64 serialization and owned byte extraction through `into_inner()`.

## Testing

Add a unit test covering base64 serialization, deserialization, and independent owned bytes extracted from shared chunks.

GitOrigin-RevId: 6bba114af48424aa844487aa75163cfc604e0575
2026-10-01 12:41:39 +00:00
Adam Perry @ OpenAI a73898c249 Use dedicated parameters for sandboxed file opens (#49818)
## What changed

Add `FsHelperOpenParams` with only a `path` field and use it for the exec-server filesystem helper's `fs/open` requests. Replace reuse of `FsReadFileParams`, removing unused read-file options from the open request type.

GitOrigin-RevId: ca84447d06fbf391cc5ad189ac6c46e6aeaa1f63
2026-10-01 02:06:27 +00:00
Adam Perry @ OpenAI c51f5bfb82 Handle unsupported fs/writeBlock requests in exec-server (#49811)
## What changed

Register `fs/writeBlock` and require filesystem initialization before handling it. Validate the file handle ID, then return an invalid-request error stating that writable file streams are unsupported.

GitOrigin-RevId: 13440e497a88ca6505ee60d95bbb771d3cae06b8
2026-10-01 01:47:35 +00:00
Adam Perry @ OpenAI e7798c9944 Add capability-gated writable file streams to the exec-server client (#49805)
## Why

Older executors can ignore the file open mode and silently return a read-only handle for a writable open.

## What changed

Add `ExecServerClient::fs_write_block` and require the `file_write_streaming` capability for both block writes and `FsOpenMode::Replace` opens. Return a protocol error before sending either request when the executor lacks support, while allowing read-only opens.

## Testing

Add a WebSocket regression test verifying that unsupported writable opens and block writes are rejected locally and read-only opens still reach the executor.

GitOrigin-RevId: f206e1da80c12af76ead14c75f8ffe71f82cce89
2026-10-01 01:36:03 +00:00
Adam Perry @ OpenAI c538fbabe5 Share cached exec-server environment info with Arc (#49798)
## What changed

Return `Arc<EnvironmentInfo>` from `ExecServerClient::environment_info()` so repeated reads and cloned clients share cached metadata without cloning its contents. Wrap metadata from initialization and lazy RPC fetches in `Arc`, while preserving the owned return value in `LazyRemoteExecServerClient`.

## Testing

Extend the cache test to assert pointer identity across cloned clients for both initialization-provided metadata and lazy fetching after connecting to a legacy server.

GitOrigin-RevId: 3f56f4d51a4aebc0c4821c0b128a70efb23933d4
2026-10-01 01:22:28 +00:00
jif 1a913493dc Clean up process groups for failed shell snapshot captures (#49782)
## Why

Failed shell snapshot captures could leave processes launched by shell startup files running after the capture ended.

## What changed

Run each Unix shell snapshot capture in its own process group and kill that group on failure, timeout, or cancellation. Keep the capture leader unreaped until output and exit status are validated so its process group ID cannot be reused during cleanup. Preserve startup helpers after a successful capture.

## Testing

Add regression coverage for startup child cleanup after nonzero exits, invalid output, cancellation, and timeout, alongside fallback and retry behavior. Verify that successful captures preserve delayed startup output and background services and reuse the cached snapshot.

GitOrigin-RevId: a56ef5d8615325952bdc8bb78727de1559e7e9c7
2026-10-01 00:48:08 +00:00
Adam Perry @ OpenAI 875bf9209b Define exec-server protocol types for streamed file writes (#49778)
## What changed

- Add `read` and `replace` modes to `fs/open`, defaulting omitted modes to `read` for existing callers.
- Define `fs/writeBlock` request and response types for offset-based writes, with a maximum decoded chunk size of 1 MiB.
- Add the `fileWriteStreaming` capability, defaulting to `false`. Keep writable streams unsupported in the server and explicitly reject replacement opens.

## Testing

Add a protocol test verifying that legacy `fs/open` requests without a mode deserialize as read-only opens.

GitOrigin-RevId: 4d3997717e821cd1f62df12a03c8eec36332a66d
2026-10-01 00:43:55 +00:00
Adam Perry @ OpenAI 3b16b5a5b0 Rename exec-server file handle management identifiers (#49702)
## What changed

Rename `file_read` to `file_handle` and `FileReadHandleManager` to `FileHandleManager`. Update the filesystem handler field, handle ID validation helper, and related constants to use file handle terminology. File operations, limits, and error messages remain unchanged.

GitOrigin-RevId: 25ad81a917386da23fd42ecff79bd47a482ce430
2026-09-30 18:37:18 +00:00
Charlie Marsh f2b2e5b2a9 Make exec-server file reads cancellable between chunks (#49696)
## What changed

Run direct `read_file` operations in a blocking task with bounded read chunks and cancellation checks. Dropping the async caller cancels further reads between chunks. Preserve the 512 MiB size limit, symlink-following options, and regular-file validation.

## Testing

Add regression coverage for 4 MiB reads and oversized-file rejection with both symlink-following options, cancellation after the first chunk, and FIFO rejection without waiting for a writer.

GitOrigin-RevId: 19f2816de15a03bd89b463de6b002367e6a692a9
2026-09-30 18:18:03 +00:00
Vivian Fang 67352b5b4a Recover exec-server sessions after environment info timeouts (#49407)
## Why

A stuck transport can fill the outbound queue, leaving an `environment/info` request blocked while sending. The timeout must cover sending as well as waiting for a response.

## What changed

Wrap the live metadata RPC in a 30-second timeout. On timeout, close the probed connection and request session recovery, returning the timeout error without retrying the failed request. Document the experimental `environment/info` endpoint and its timeout behavior.

## Testing

Extend the WebSocket session recovery test to cover an unanswered `environment/info` request, checking that it times out, closes the connection, and resumes the same session while retaining the client instance.

GitOrigin-RevId: 9035d2edab3626e780d8bd40ebcdf0ca327bfddb
2026-09-30 00:22:43 +00:00
jgershen-oai 9212b3eca8 Serialize tests that share Windows sandbox accounts (#49389)
## Why

Elevated sandbox tests share machine-local Windows accounts. Concurrent setup can rotate account passwords between another test's setup and logon.

## What changed

- Add a shared file-lock guard for elevated sandbox tests in `codex-core`, `codex-exec-server`, and `codex-windows-sandbox`, held through sandbox commands and cleanup.
- Queue these tests in a single-threaded Nextest group before their timeouts start, while retaining the file lock to coordinate other test processes.
- Limit account locking to tests that use elevated accounts and remove the sandbox crate's blanket Bazel `exclusive-if-local` tag.

GitOrigin-RevId: 26d4606cb1fdcac65926d29835bed4eac04c19c0
2026-09-29 22:50:07 +00:00
jif ed9e5a26a8 Clean up canceled exec-server RPC requests immediately (#49332)
## Why

Canceled RPC calls could leave entries in the pending request map until further traffic or disconnect. Cleanup should happen when the call is dropped, even if no response arrives.

## What changed

Use a `PendingRequestGuard` to remove each registration when its call completes or is canceled. Protect the pending map with a synchronous mutex so cleanup can run in `Drop`, replacing opportunistic pruning and explicit error-path removals.

## Testing

Add a regression test that drops an in-flight call and verifies that the pending request count immediately reaches zero without further traffic.

GitOrigin-RevId: 82c0629f37a2f4bb89b8d10e167e2a09765b26eb
2026-09-29 18:34:48 +00:00
jif 65c3f40bef Model exec-server session attachment state as an enum (#49286)
Replace the three optional fields in `AttachmentState` with `Attached` and
`Detached` variants, making inconsistent field combinations unrepresentable.
Keep the connection ID in both variants and the expiration deadline only in
`Detached`, and update attachment and expiration checks to match on the state.

GitOrigin-RevId: 6a5f05f0ce2f064acc8f5cacd00bc374c4f47986
2026-09-29 15:41:22 +00:00
Eric Traut fbc169827e Suppress Windows console windows for background subprocesses (#49164)
## Why

Background helpers launched from a detached Windows process can allocate console windows. Job Object launches and containment fallbacks need to preserve console suppression as well.

## What changed

- Add `codex_utils_process::background_command` to set `CREATE_NO_WINDOW` on Windows, and use it across background subprocess launches, including Git, plugins, authentication, diagnostics, and sandbox helpers.
- Centralize console suppression in Job Object launches. Keep `CREATE_NO_WINDOW` when retrying without containment, and clear `CREATE_SUSPENDED` so the fallback child can run.
- Preserve console inheritance for interactive shell launches and interactive AWS authentication refreshes.

## Testing

Add Windows regression tests covering console-free launches from detached parents through standard and Tokio commands, stdout/stderr capture, successful containment, Job Object creation and assignment failures, and sandbox setup refresh helpers.

GitOrigin-RevId: b2c238fa7d4f9fbd868e5adf7d4be9958ff01e6c
2026-09-29 04:38:37 +00:00
zm-oai f5430515a8 Resolve Windows sandbox PowerShell fallbacks on the exec server (#49098)
## Why

Remote controllers cannot resolve a sandbox-compatible PowerShell executable on the execution host.

## What changed

Apply the existing PowerShell fallback during exec-server request preparation for the `Elevated` and `Mxc` Windows sandbox backends. Match `pwsh` and `powershell` executable names case-insensitively and replace inaccessible Store PowerShell paths when a compatible executable is available.

## Testing

Add Windows RPC regression tests for lowercase and mixed-case PowerShell aliases with a restricted server `PATH`, verifying successful command execution in the `Mxc` sandbox.

GitOrigin-RevId: 365541af2f026a662b1988429f5d182c98e4a236
2026-09-28 23:21:26 +00:00
jif 18344a972d Centralize executable fixture creation to avoid Linux ETXTBSY races (#48727)
## Why

Concurrent tests can inherit writable descriptors for executable fixtures, causing `ETXTBSY` when those fixtures launch on Linux.

## What changed

Expose shared `write_executable` and `copy_executable` helpers from `codex_utils_cargo_bin` and adopt them in CLI, exec-server, and MCP tests. On Linux, writes and copies complete in separate processes so sibling test spawns cannot inherit the writable descriptors. Script fixtures receive mode `0o755`, and copied executables retain their source permissions.

Remove the executable-busy retry loop from the program resolver test now that its script uses the shared helper.

GitOrigin-RevId: 61624158190bb1e75c27d9eb9c87a2defc147fb7
2026-09-27 15:25:13 +00:00
richardopenai 985cf47a4e Allow provisioned executors more time to come online (#48575)
## Why

A provisioned executor can still be resuming after readiness is reported. Initial connection attempts can exhaust the ordinary registry retry limits before the executor comes online.

## What changed

Retry `environment_offline` registry responses during initial Noise rendezvous connections for provisioned environments until a fixed five-minute deadline, starting after provisioning succeeds. Keep the existing retry limits for other registry errors and stop on permanent failures.

## Testing

Add tests covering the five-minute deadline, ordinary limits for other errors and stalled requests, and termination on a later permanent error. Verify that readiness and info requests remain pending through an extended offline period and succeed using the same environment handle once the executor comes online.

GitOrigin-RevId: e22211499d9ec2f3590e75224eb39e2e4bf3538d
2026-09-27 00:01:17 +00:00
open-matt b8d5e3f12e Allow exec-server to proxy permitted private IPs upstream (#48568)
## Why

Private IP destinations always bypassed inherited upstream proxies, preventing their use for private networks reachable through an upstream VPN proxy.

## What changed

- Add `codex exec-server --proxy-private-ips-via-upstream`, also configurable with `CODEX_EXEC_SERVER_PROXY_PRIVATE_IPS_VIA_UPSTREAM=true`. The setting defaults to disabled.
- Allow permitted RFC 1918, carrier-grade NAT, and IPv6 unique-local destinations to use an applicable upstream proxy. Loopback and link-local destinations retain direct routing, and destination access policy still applies.
- Keep connections direct when no valid upstream proxy applies or `allow_upstream_proxy=false`. Errors after selecting an upstream proxy do not trigger a direct retry.
- Rename `ExecServerRuntimePaths` to `ExecServerRuntimeOptions` and carry the routing setting from executor startup into the managed network proxy.

## Testing

Add routing coverage for private address ranges, special-use addresses, and public targets with the option enabled and disabled. Verify that HTTP and CONNECT requests still enforce destination allowlists and denylists, and update the CLI help snapshot.

GitOrigin-RevId: b7c9cc7da0e0f545694a6521b74c9b36b7b92769
2026-09-26 23:17:41 +00:00
jif 8f0b05910e Fix zsh alias quoting in sourced shell snapshots (#48187)
## Why

Sourced snapshots parse options and aliases as a group before restored options take effect. Aliases serialized with `RC_QUOTES` enabled can therefore be misinterpreted by the replay shell.

## What changed

Serialize zsh aliases for sourced snapshots with `NO_RC_QUOTES` in a subshell, preserving the captured shell options and avoiding a dependency on the optional `zsh/parameter` module.

## Testing

Extend regression coverage to execute restored aliases with `RC_QUOTES` enabled and disabled across source and eval replay. Expand macOS zsh concurrent replay tests to cover quoted aliases, preserved options, and blocked descriptor paths with and without a TTY.

GitOrigin-RevId: 48086f380c21318bece9226dfe6486c179c2a440
2026-09-25 19:43:06 +00:00
jif c98e263fb5 Replay exec-server shell snapshots through unnamed files (#48078)
## Why

Large shell snapshots need a replay path that does not add their state to the child process environment.

## What changed

- Keep captured state cached in memory and give each Bash or Zsh launch an independent, read-only file descriptor to source. Unlink the file before writing shell state, create it under the sandbox-protected daemon directory, and close the carrier descriptor before restoring functions.
- Probe descriptor-path access inside the capture sandbox. Retain environment replay for `sh` and when descriptor paths are unavailable; use normal shell startup if preparing the replay file fails.
- Group options and aliases during capture so sourcing preserves their parsing behavior.

## Testing

Add coverage for concurrent replays with 480 KiB payloads, pipe and TTY execution, stdin preservation, descriptor cleanup, sandbox protection, blocked descriptor-path fallback, and alias/option parsing equivalence.

GitOrigin-RevId: 8103d5c37ce4d1885628a4efba3551549f12bea8
2026-09-25 12:23:15 +00:00
open-matt aa380897f6 Add startup-only PID namespace inheritance to exec-server (#47989)
## Why

When a container denies fresh `/proc` mounts, the existing sandbox fallback retains the caller's `/proc` while creating a new PID namespace. Process IDs inside the sandbox can then differ from those exposed by `/proc`, breaking process lookups.

## What changed

- Add `codex exec-server --linux-sandbox-pid-namespace=inherit` to reuse the caller's PID namespace and `/proc` for both process and filesystem helpers. Repository config and command environment variables cannot enable it.
- Keep `isolate` as the default, preserving the existing mount fallback and compatibility with older helpers. Inheritance requires an updated helper and omits `--unshare-pid` and `--as-pid-1`.
- Preserve other sandbox restrictions. With `:minimal`, bind the inherited `/proc` read-only with its container masks and apply explicit filesystem denials afterward.

Inheritance is intended for dedicated environments: it allows sandboxed commands to signal other same-UID processes, including the executor.

## Testing

Add unit and integration coverage for namespace flags, denied proc mounts, consistent process IDs, retained sandbox restrictions, and startup-only selection across process and filesystem helpers.

GitOrigin-RevId: dd13f2b9286d7edcf366b3a42a455f4d78daaf27
2026-09-25 03:12:10 +00:00
felixxia-oai 6f51c65958 Fix macOS system-alias matching in patch permission checks (#47879)
## Why

Local `apply_patch` permission checks can treat a macOS system alias and its canonical spelling as different locations, sending writes covered by temporary-directory grants for unnecessary approval.

## What changed

- Normalize trusted top-level aliases in local policy roots and patch targets, reusing a prepared matcher for permission requests and patch safety checks.
- Share alias normalization with Seatbelt and the macOS executor sandbox while preserving mutable symlinks and missing descendants.
- Preserve read-only and deny precedence, protected metadata restrictions, and remote URI matching. Propagate normalization failures from fallible permission checks.

## Testing

Add macOS regressions for multi-file patches with missing parent directories through both direct `apply_patch` calls and shell interception, asserting automatic approval and file contents. Add unit coverage for alias restriction precedence, mutable symlink preservation, missing descendants, and remote permission isolation.

GitOrigin-RevId: 0822ff951eaab728cb1ad91281745fa1b8809f15
2026-09-24 16:36:57 +00:00
jif 51d4562070 Support close-on-exec attachments without changing PTY semantics (#47797)
## Why

Passing extra descriptors to a PTY previously selected behavior intended for inherited escalation sockets: no EOF on stdin close, different signal exit statuses, and no default `SHELL`. Launch attachments need ordinary PTY behavior and must survive execution even when marked `FD_CLOEXEC`.

## What changed

- Add `ChildFds::Attached` alongside `ChildFds::Inherited` to distinguish launch attachments from legacy inherited descriptors.
- Preserve ordinary EOF, default `SHELL`, and signal exit status behavior for PTY attachments.
- Allow explicitly supplied close-on-exec descriptors through pipe and PTY launches without changing the parent's descriptor flags, using child-side flag updates and macOS spawn inheritance actions.
- Update existing callers to use `ChildFds::Inherited`.

## Testing

Add Unix coverage for attachment accessibility, unchanged parent descriptor flags, default `SHELL`, and signal exit statuses. Extend the PTY stdin-draining test to cover attachments and EOF delivery.

GitOrigin-RevId: 864aedc6c5717d8b43c9d71057c9f54409834509
2026-09-24 09:25:19 +00:00
Ahmed Ibrahim e0ef5a1a0f Reduce generic code duplication in RPC and Markdown rendering (#47751)
## Why

RPC sending and waiting do not depend on request or response types, and Markdown layout does not depend on the parser iterator. Share these implementations across typed calls and parser variants.

## What changed

- Extract `RpcClient::send_request_and_wait` into a non-generic async method, preserving registration before serialization and disconnected-client error precedence.
- Remove the iterator type parameter from `Writer` and pass iterators to event traversal methods, retaining static dispatch and dropping the parser before rendering state, including on unwind.
- Update streaming rendering and existing rendering tests to use the separate parser.

GitOrigin-RevId: 4cc07223111b7c08211028948d13fe04598f8fc7
2026-09-24 04:48:03 +00:00
Anthony Tafoya ab7439231c Add executor capability discovery V2 infrastructure (#47683)
## What changed

- Define `capabilities/discoverV2` request and inventory types and advertise `capabilityDiscoveryV2` in executor metadata.
- Prewarm installed plugin and global skill locations at server startup, with nonfatal scan failures.
- Add sandbox-scoped discovery caching with file watcher invalidation and request-time reloads when watching is unavailable.
- Batch metadata reads through the filesystem sandbox helper and bound discovery responses to 4 MiB and 2,048 capabilities.
- Share plugin identity and installed-version selection in `codex-core-plugin-common`, and fall back to `.app.json` when a plugin does not declare an apps configuration.

The V2 discovery manager is not yet wired into RPC request dispatch.

## Testing

Add coverage for inventory metadata, sandbox cache isolation, watcher invalidation, startup scan failures, response limits, and compatibility with older executor metadata.

GitOrigin-RevId: a223a5bc15fdf251023c0c71f468fd92c3b2d847
2026-09-23 22:20:34 +00:00
Adam Perry @ OpenAI 6fa3bcaae8 Add exec-server RPC timing and process startup tracing (#47680)
## Why

Detached work can keep request spans open beyond response enqueueing. Record explicit phase timings to distinguish request handling from the full span lifetime.

## What changed

- Record server dispatch and response enqueue offsets from request receipt, plus a response enqueue event for HTTP responses that bypass the dispatcher.
- Emit client request enqueue and response receipt events, including success or server-error outcomes and reader-to-caller delay. Carry completion timestamps to the awaiting task so receipt events retain its tracing context.
- Add spans for process startup, sandbox preparation, shell snapshot preparation and capture, and process spawning. Record process identifiers only when nonempty and at most 64 bytes long.

GitOrigin-RevId: 237db898b3284fe8a6a36cb0055b3c7991d8e8a4
2026-09-23 22:10:28 +00:00
Ian MacLeod 7e5054d32f Bump the exec-server stable compatibility test to Codex 0.156.1 (#47655)
Update the Bazel release archive version and checksum from `0.153.1` to
`0.156.1`, and point `exec-server-stable-release-test` at the new archive.

GitOrigin-RevId: 1d28566d2447c027a67c4197b213458a0838fde0
2026-09-23 20:21:18 +00:00
Ruslan Nigmatullin ad26b2520a Support bearer tokens for app-server executor connections (#47648)
## Why

App-server clients need a way to connect to executors that require bearer authentication through `environment/add` and `environments.toml`.

## What changed

- Add optional `authBearerToken` to `environment/add` and `auth_bearer_token` to URL entries in `environments.toml`.
- Send the token as an `Authorization: Bearer` header on initial connections and reconnects, without automatic refresh. Require `wss://` or a loopback destination when a token is supplied.
- Redact tokens in debug output, mark connection headers sensitive, and omit source text from TOML parse errors.
- Preserve unauthenticated behavior when tokens are omitted, including requests with a null `authBearerToken`.

## Testing

Add integration coverage for authenticated and unauthenticated executors through both RPC and TOML configuration, including missing, null, incorrect, and malformed RPC tokens. Extend tests for reconnect authorization headers, token redaction, URL-only token configuration, and timeout preservation.

GitOrigin-RevId: 2a5d48a1846df1720e4a9b295968348378c287c6
2026-09-23 20:05:37 +00:00
mtsui-oai c847294c60 Classify retryable exec-server preparation errors by type (#47638)
## Why

Transient connection and registry failures can reach remote filesystem callers as generic `io::ErrorKind::Other` errors. Callers need a typed signal to identify failures that read-only preparation can retry.

## What changed

- Add `ExecServerError::is_retryable_preparation_error()` to classify transient registry, connection, handshake, timeout, and session-attachment failures, including errors wrapped in `ConnectionAttempt`.
- Map these failures to `io::ErrorKind::BrokenPipe` in the remote filesystem adapter.
- Keep authentication, TLS, and malformed protocol failures outside the retryable classification; error text alone does not trigger it.

## Testing

Add a regression test showing that a wrapped registry service-unavailable error maps to `BrokenPipe`, while a protocol error containing transport-closed text remains `Other`.

GitOrigin-RevId: c3e1bbab8f977a0b421eba5d6d3071ada72c09ff
2026-09-23 19:37:16 +00:00
Sean Huang 13869ca39e Add portable project trust lookup APIs (#47620)
## What changed

Add `resolve_root_git_project_uri_for_trust` to resolve repository trust roots through `ExecutorFileSystem` using executor path conventions. Share repository and linked-worktree validation with native lookup while preserving native ancestry for paths with opaque URI representations.

Extract `ProjectTrustLookup` to match merged project settings using supplied path spellings and an explicit path convention. Preserve canonical-before-original and cwd-before-repository-root precedence, including cwd entries without a trust level, with ASCII case-insensitive matching for Windows.

## Testing

Add coverage for POSIX, Windows drive and UNC trust roots, project-key precedence and case handling, and native/URI lookup parity. Extend environment-config coverage to verify returned `projects` entries include entries without a trust level.

GitOrigin-RevId: 315434802e86cceee85b14bc1c3767a45e3139f5
2026-09-23 18:40:12 +00:00
Free Wortley df3ecee6f0 Launch Linux pipe processes through a fresh setup helper (#47612)
## Why

Linux pipe launches need session, parent-death signal, and descriptor setup. Move this work into a fresh, single-threaded executable image to avoid forking the app-server for child setup.

## What changed

- Register an early setup helper and launch it through `posix_spawn` for Linux pipe processes.
- Start the helper with an empty environment, then transfer the target environment over a control socket so loader settings cannot interfere with helper startup.
- Await target execution asynchronously, propagate setup and execution errors, and kill incomplete launches on cancellation.
- Preserve direct spawning as a fallback when the helper is unavailable or fails before target execution.

## Testing

Add coverage for launch semantics, avoiding fork, loader environment isolation, early argument dispatch, closed standard descriptors, and fallback under bootstrap failure or descriptor pressure. Add an app-server regression test that reuses a process handle after an execution failure.

GitOrigin-RevId: 079c673f0f22ebd531f8c57e5338095cc98acfdc
2026-09-23 18:25:07 +00:00
Charlie Marsh b8d365b18e Extend child commands with session and descriptor controls (#47604)
## What changed

- Add `ProcessMode::NewSession`, null stdin, and opt-in Linux parent-death termination to the shared child command API.
- Replace `DescriptorPolicy::StdioOnly` with `Explicit` and add `preserve_fds` to allow selected inheritable Unix descriptors alongside stdio. Preserve descriptor numbers without duplicating or closing the parent's descriptors, keeping POSIX record locks intact.
- Support session creation and preserved descriptors in the native macOS backend, with a compatible fallback for high descriptor numbers rejected by native file actions.

## Testing

Add regression coverage for process groups and sessions, descriptor preservation across native and executable-text launches, the last descriptor slot below the file limit, and retention of parent record locks.

GitOrigin-RevId: 29ecd859d3b673da6ae6412cc06a32fa10d11346
2026-09-23 17:59:47 +00:00
Ruslan Nigmatullin 2210190435 Add opt-in WebSocket authentication to exec-server (#47601)
## What changed

Expose the shared `--ws-auth` options on `codex exec-server` for direct WebSocket listeners. Support capability tokens configured by token file or SHA-256 digest, and signed JWT bearer tokens. Validate `Authorization: Bearer TOKEN` before each WebSocket upgrade, rejecting missing or invalid credentials with HTTP 401 when authentication is enabled.

Reject listener authentication with stdio, `--remote`, or `forward`. Document the options and connection-time authentication behavior.

## Testing

Add CLI integration tests for all three credential configurations, unauthorized upgrade rejection, authenticated RPC initialization and reconnects, invalid configuration, and incompatible transports.

GitOrigin-RevId: 941fbd3d43e732c910d29b6f8137077b7c332835
2026-09-23 17:56:46 +00:00
acrognale-oai db3cb33eca Honor network policy in remote control and recover remote execution (#47410)
## What changed

- Route remote-control enrollment, pairing, client management, and WebSocket connections through the authenticated HTTP client factory. Keep policy denials distinct from authentication failures and wait for policy changes before reconnecting.
- Preserve policy denials through exec-server connection failures so later connection attempts and capability discovery can recover. Keep direct executors running through temporary policy outages while rejecting permanent policy failures.
- Build cached HTTP transports on blocking workers, serialize construction, and retain successful builds after callers time out so request deadlines cover queued construction.

## Testing

Add regression coverage for policy recovery during remote startup, direct registration, accepted WebSocket reconnection, and capability discovery; queued transport construction timeouts; and remote-control WebSocket fallback with invalid custom CA files.

GitOrigin-RevId: c81db18e83de957175bb213d165281ac701089dd
2026-09-23 00:48:53 +00:00
acrognale-oai 8f8ace78cb Enforce application network policy for AWS auth and telemetry (#47408)
## Why

AWS credential discovery, analytics, and telemetry used clients that did not share the application's network policy. These requests need to honor destination restrictions and permission revocation.

## What changed

- Route AWS credential and region HTTP requests through the shared HTTP client, and check the signing destination before loading credentials. Skip discovery for static access keys with an explicit region.
- Apply account-scoped policy to Bedrock authentication. Require unrestricted policy for credential exporters and reauthentication commands, and cancel active work when permission is revoked. Document that AWS profile `credential_process` network traffic remains outside the application's HTTP policy.
- Send analytics through the authenticated account's HTTP client factory.
- Guard OTLP log, trace, and metric exports with revocable permits, disable them under destination restrictions, and make managed HTTP exports cancellable. Suppress global Statsig settings while managed policy is active.

## Testing

Add coverage for metadata credential request cancellation, allowed and denied SigV4 destinations, AWS credential precedence and endpoint configuration, and blocked credential exporter recovery. Update telemetry tests for account transitions and managed-policy Statsig suppression.

GitOrigin-RevId: d8a2018bfbbe971ec430699b0d3f86a7a9e1e072
2026-09-23 00:47:34 +00:00
acrognale-oai 888e02db34 Enforce network policy throughout HTTP and WebSocket requests (#47389)
## Why

Destination restrictions and policy revocation must remain effective during redirects, response body reads, and established WebSocket traffic. Policy denials must also survive error handling so callers do not retry them or report a revoked operation as successful.

## What changed

- Route managed HTTP clients through a shared `RequestBuilder` and policy-aware execution, checking each redirect destination before route resolution and retaining a network permit while consuming response bodies.
- Guard WebSocket connection setup, reads, and writes with revocable permits, including independent wakeups for split readers and writers.
- Preserve `TransportError::Policy` through HTTP, SSE, and realtime error handling, and treat policy denials as non-retryable.
- Keep the supplied network policy in plugin startup HTTP requests and propagate response body failures from backend and plugin requests.

## Testing

Add regression coverage for rejection before connecting, revocation during redirect routing and streamed body reads, split WebSocket revocation, realtime writer error propagation, and revoked plugin upload responses.

GitOrigin-RevId: fba36700444c98a8364c09b4dc5452c4d78a90fb
2026-09-22 23:37:39 +00:00
viyatb-oai 54487a5b61 Bound inbound exec-server requests across client transports (#47362)
## What changed

- Enforce an 8 KiB encoded-message limit for requests, unrecognized notifications, and malformed messages received by exec-server clients over stdio, WebSocket, relay, and Noise relay transports.
- Allow process output, exit, close, and HTTP request body notifications up to 2 MiB. Keep responses and errors subject to existing transport limits, and preserve executor-side request limits.
- Read stdio stderr in chunks of at most 8 KiB.
- Drop outgoing server-request `tracestate` values larger than 512 bytes while preserving `traceparent`.

## Testing

Add regression coverage for oversized requests across transports, malformed messages, requests wrapped in `RawValue`, fragmented Noise messages, large responses, streamed notifications, and trace-context preservation.

GitOrigin-RevId: 3fb87b6dc334296985ef40983d7276acfe9b9796
2026-09-22 21:07:20 +00:00
iceweasel-oai 023d81b057 Preserve required Windows runtime variables for filesystem helpers (#47108)
## Why

On Windows, MXC needs `SystemDrive` to resolve platform directories and
`LOCALAPPDATA` to create the sandboxed helper process. The helper environment
filter previously dropped both variables.

## What changed

Allow `SystemDrive` and `LOCALAPPDATA` alongside `PATH` in the Windows helper
environment, using case-insensitive name matching.

## Testing

Extend the Windows environment-filtering test to verify that mixed-case runtime
variable names are preserved while `PATH_INJECTION` and `OPENAI_API_KEY` remain
excluded.

GitOrigin-RevId: bab242dd59da59ac6e7f428436e1c139aadadfdd
2026-09-21 20:42:25 +00:00
Charlie Marsh 595cc91e8c Avoid fork when spawning macOS filesystem helpers (#46661)
## Why

Filesystem helpers use a `pre_exec` callback to close inherited descriptors on macOS, forcing a fork before execution. Native spawning needs to preserve that isolation and support the socket used for file descriptor transfer.

## What changed

- Launch filesystem helpers through `codex_utils_pty::Command`, using `posix_spawn` with `POSIX_SPAWN_CLOEXEC_DEFAULT` on macOS and returning native launch errors without a fork fallback.
- Extend the shared command wrapper with explicit descriptor and fallback policies, socket-backed stdin, and custom `argv[0]` support.
- Add `Child::wait_with_output` to drain stdout and stderr concurrently, retain kill-on-drop behavior on cancellation, and keep output pipes open until the child exits.

## Testing

Add regression tests for fork-free sandboxed reads, writes, and file descriptor transfers; sandbox denial of outside paths and symlink escapes; descriptor isolation; bidirectional socket stdin; custom `argv[0]`; executable-format errors; and output-pipe lifetimes.

GitOrigin-RevId: d49c00787f30ec0bc196f9e066a0770fc8151152
2026-09-19 15:15:25 +00:00
viyatb-oai 328feb0c29 Track executor registrations across connection refresh and recovery (#46555)
## Why

An executor can renew its registration while retaining its Noise identity. Connection refresh must distinguish registrations even when their keys match, and a stale registry lookup must not retire a session that recovery has already renewed.

## What changed

- Track the installed session's registration and expose it through `Environment::cached_executor_registration_id()` without connecting. Publish registration changes only when the new connection is installed.
- Require both registration and executor key to match before refresh reuses a session. Retry stale lookups and prevent recovery from installing a connection after retirement.
- Pin session recovery to the original Noise key while allowing registration renewal to preserve the session and running processes.
- Expose `CodexThread::active_turn_environment_selections()` so hosts can authorize steering against the active turn's selections, including starting and failed environments, independently of later settings updates.

## Testing

Add regression coverage for registration replacement, renewal with a running process, stale refresh lookups, missing sessions, and rejection of changed Noise keys. Extend active-turn tests to check selection snapshots across settings updates, deferred startup, and turn completion.

GitOrigin-RevId: 4395bc6c57f137691887e6585f52dcc5b958101c
2026-09-19 01:27:02 +00:00
iceweasel-oai a633ebc124 Always use private desktops for legacy Windows sandboxes (#46554)
## What changed

- Remove the private-desktop opt-out from elevated and unelevated Windows sandbox launches.
- Remove `windows.sandbox_private_desktop` and its managed requirement and API fields. Warn users to remove the obsolete setting.
- Require a private desktop name when launching through the Windows sandbox wrapper and command runner.

## Testing

Add coverage for the obsolete-setting migration warning and update wrapper tests to verify a live private desktop is passed and a missing desktop name is rejected.

GitOrigin-RevId: c7135f8d211aac8d812180691c2c1e433d77cde4
2026-09-19 01:21:32 +00:00
Sean Huang 3724dc8361 Share platform identity across path, network, and sandbox configuration (#46334)
## What changed

- Add `Platform` to `codex-utils-path-uri` with metadata parsing, native platform detection, and path convention mapping. Preserve missing or unrecognized metadata as `Unknown`.
- Replace `NetworkProxyExecutorOs` with the shared type and keep executor-specific socket path validation in the network proxy.
- Extract `effective_sandbox_mode` with explicit platform and Windows sandbox level inputs, preserving the native Windows fallback from `workspace-write` to `read-only` when the sandbox is disabled.

## Testing

Add unit tests for platform metadata, path conventions, native platform detection, and sandbox mode selection across platforms and Windows sandbox levels.

GitOrigin-RevId: 4fe0972e3a91040e35f2a6dfa5bcdf6c9a29be88
2026-09-18 00:51:34 +00:00
Sean Huang ea218f5cd8 Validate network socket policies using the executor OS (#46302)
## Why

A controller and its executor can run different operating systems. Validating socket paths against the controller's OS can reject absolute paths that are valid on the executor, such as Windows paths on a Linux controller.

## What changed

- Thread `NetworkProxyExecutorOs` through network policy validation, proxy construction, and policy updates.
- Require allowed socket paths to be NUL-free and absolute for the executor OS, while preserving deny entries unchanged.
- Accept either Unix or Windows absolute syntax when executor metadata omits the OS, then validate against the executor's own OS at launch.
- Keep native path normalization and socket support checks at execution time.

## Testing

Add coverage for cross-platform absolute path syntax, invalid allow entries, preserved deny entries, and remote policy round trips that retain executor semantics through domain edits and proxy construction.

GitOrigin-RevId: 1ebc09cbce7138f60ec5fd62875591a3df52d067
2026-09-17 20:59:55 +00:00
iceweasel-oai 8b78600dc8 Enable MXC selection through Windows sandbox configuration (#46271)
## What changed

- Accept `windows.sandbox = "mxc"` and preserve the selected backend through environment configuration, command execution, patch writes, and sandbox metadata.
- Treat MXC as enabled in the TUI and report Windows sandbox readiness as `ready`, avoiding legacy setup prompts.
- Keep `allowed_sandbox_implementations` scoped to the legacy elevated and unelevated backends without restricting MXC.
- Default `windows.sandbox_private_desktop` to `false` for MXC while retaining `true` for legacy sandboxes.

## Testing

Add coverage for MXC configuration precedence, legacy requirement handling, sandbox selection, and TUI state. Add a Wine integration test that verifies command and patch routing fails when native MXC is unavailable and reports `windows_mxc` in turn metadata.

GitOrigin-RevId: e2162447d0750f60753864c92a20e02a7f297bca
2026-09-17 18:20:28 +00:00
Adam Perry @ OpenAI 3d3ae4965a Add filesystem accessors bound to environment permissions (#46268)
## What changed

Add `EnvironmentAccess` and `FileSystemEnvironmentAccessor` to expose filesystem operations with a captured sandbox configuration, without allowing consumers to extract the filesystem or select another sandbox. Include a text-reading helper and an explicit unrestricted constructor.

Provide opaque cache keys that compare filesystem identity and captured permissions without keeping the filesystem alive. Allow opened read streams to outlive the accessor. Export the new APIs through `codex-exec-server` and add `Environment::filesystem_ref()` for borrowing the shared filesystem.

## Testing

Add local and remote coverage for text reads through `EnvironmentAccess`, streams surviving accessor disposal, and cache keys distinguishing changed permissions or a replacement filesystem.

GitOrigin-RevId: 4f6787ed9ba0fb94adea2f31716c4d3132fed07d
2026-09-17 17:59:19 +00:00
Adam Perry @ OpenAI a4ee536f01 Route filesystem reads and writes by their own sandbox permissions (#46122)
## Why

Filesystem reads previously required a sandbox whenever writes were restricted, even with full-disk read permission. This made permitted reads depend on sandbox availability.

## What changed

- Select sandboxing independently for reads and writes, allowing full-disk reads directly while keeping restricted operations sandboxed.
- Use the executor's path convention when evaluating full-disk access, including `:slash_tmp` denials.
- Apply read-specific checks to capability discovery and skill resource reads, allowing unrestricted reads on executors without sandboxed discovery support.

## Testing

Add regression tests for direct read APIs, restricted writes and reads, executor-specific permission rules, and capability discovery without sandbox support. Update Windows tests to verify sandbox enforcement through writes.

GitOrigin-RevId: a03844bd1f0ea583bb54326683cddbfdd050119f
2026-09-17 05:09:03 +00:00
Adam Perry @ OpenAI 841b5490b2 Preserve filesystem sandbox policy context when the cwd disappears (#46112)
## Why

Removing the selected working directory can prevent filesystem sandbox helpers from launching, even when the requested absolute paths remain accessible. Permission rules must stay anchored to the selected directory while those operations continue.

## What changed

- Require a policy `cwd` in `FileSystemSandboxContext` and launch filesystem helpers from the filesystem root while preserving the policy directory and workspace roots.
- Carry explicit `policyContext` in filesystem RPCs, preserving legacy wire fields and resolving omitted directories from older clients at executor ingress.
- Keep permission paths as executor file URIs and validate host compatibility where they are enforced.
- Bind Windows relative denial globs to the policy directory before changing the helper's launch directory, preserving home-relative patterns.

## Testing

Add regression coverage for `apply_patch` after working-directory removal, legacy RPC directory fallbacks, cross-platform permission URI transport, and Windows relative read denials. The patch regression verifies that an allowed file is updated while an explicitly denied file remains unreadable and unchanged.

GitOrigin-RevId: b0f4db722b27cb72ec129fc297c85732afac11f7
2026-09-17 04:37:54 +00:00
viyatb-oai 105fe8761c Keep Noise relay streams alive after repeated handshake failures (#46031)
## Why

Exhausting the handshake failure budget closed the physical relay, disconnecting authenticated streams along with failed attempts.

## What changed

After eight failed handshakes, pause new handshake admission for 10 seconds. Reset incoming handshake attempts before parsing them while existing streams and pending validations continue. Failures during the cooldown do not extend it, and the failure budget resets when handshake admission resumes.

## Testing

Update relay tests to cover duplicate handshakes and early data without disconnecting the relay. Verify that encrypted traffic on an established stream continues during cooldown, rejected attempts skip authorization checks, and new handshakes succeed after cooldown expires.

GitOrigin-RevId: 0a5098ed1b3c31466f9c091f46cbb20415c7aa1d
2026-09-16 21:21:45 +00:00