Commit Graph
416 Commits
Author SHA1 Message Date
iceweasel-oai cba716c0f1 Run sandbox integrity checks before commands and filesystem operations (#51843)
## What changed

Wire existing sandbox integrity checks into local command preparation, exec-server process preparation, and sandboxed filesystem helper and file-open operations. Make execution request preparation asynchronous so callers can await the checks.

The checks remain observational: failures and timeouts do not prevent command execution.

## Testing

Add regression tests that launch a real command after checker preparation fails or exceeds its timeout, verifying successful output and exit status.

GitOrigin-RevId: a82399f8aeb8b08f9965e6121b4c7f460552af3f
2026-10-07 21:52:43 +00:00
iceweasel-oai c2eb1f42a0 Add a sandbox integrity runner with outcome and timing metrics (#51842)
## What changed

Export `run_integrity_checks` from `exec-server` to check whether the effective filesystem policy permits writing containment dependencies on Linux, macOS, and Windows. Run preparation and checks on a blocking worker, limit waiting to five seconds, and keep results observational without affecting execution.

Skip mismatched sandbox backends, full-disk-write policies, and `EscalatedSandboxWithRestrictions` overrides. Continue checking ordinary configured policies with root write access and deny restrictions.

Record check outcomes, preparation time, and total duration with bounded metric tags that omit filesystem paths.

## Testing

Add coverage for findings, clean results, missing dependencies, preparation errors, eligibility rules, and timeouts. Verify that timed-out workers emit no late results and that metrics contain no filesystem paths.

GitOrigin-RevId: a234f4a2f629f9bb090da622cea352c99456cb00
2026-10-07 21:52:20 +00:00
iceweasel-oai b5c37c35fd Add a macOS Seatbelt backend for sandbox integrity (#51841)
## What changed

Enable the exec server's `sandbox_integrity` module on macOS and select the Seatbelt backend. Inventory the Codex executable and the system Seatbelt executable as critical dependencies.

Preserve the filesystem sandbox policy unchanged: Seatbelt handles deny globs as native patterns, so no snapshot scan is needed.

GitOrigin-RevId: 78299dd61e168f5ce34454c8b3bb887e67c5f342
2026-10-07 21:51:13 +00:00
iceweasel-oai d9960e12bb Add a bubblewrap backend for sandbox integrity checks (#51840)
## What changed

Add Linux dependency discovery and policy preparation to `exec-server`'s sandbox integrity module. Inventory bundled and system `bwrap` candidates and the deny-glob scanner using the launcher's location and the command's `PATH` and working directory.

Resolve `:tmpdir` and tilde-prefixed deny globs using the command's `TMPDIR` and `HOME`, with account home-directory fallback. Reuse Linux sandbox helpers to expand deny globs in the command's explicit environment.

## Testing

Add Linux tests covering symlinked launchers, relative and empty `PATH` entries, and empty, relative, and tilde-prefixed `TMPDIR` values alongside home-relative deny globs.

GitOrigin-RevId: fe404fa4be77ece677b22d52d77a7234dbf0cffe
2026-10-07 21:50:48 +00:00
iceweasel-oai 3342ee8c07 Add MXC sandbox integrity dependency and policy preparation (#51831)
## What changed

Add Windows MXC backend helpers to inventory the Codex executable, sandbox
launcher, and available `rg` scanner when deny globs are configured. Prepare
filesystem policies for inspection by reusing MXC temporary-directory and volume
resolution and replacing deny globs with concrete path snapshots.

Allow Windows deny-glob resolution to run its scanner with an explicit command
environment and working directory, including an empty environment. The integrity
helpers are not yet invoked by an execution runner.

## Testing

Add a backend test verifying that deny-glob snapshots replace the original
patterns, including empty snapshots, and affect `FileContentsChecker` results.

GitOrigin-RevId: 409c527663d230d76d65be3bf0a37959f694d77e
2026-10-07 21:16:25 +00:00
iceweasel-oai 622e9e3696 Preserve sandbox overrides across execution requests (#51786)
## What changed

Move `SandboxOverride` into the shared protocol and carry the controller's selection through tool attempts, execution requests, and exec-server process and filesystem sandbox preparation. Include it as `sandboxOverride` in filesystem sandbox contexts for observation without granting broader permissions or altering sandbox commands.

Default missing values to `NoOverride` and omit that value when serializing to preserve compatibility with existing requests.

## Testing

Extend tests to cover override propagation, wire round-trips for all three variants, and deserialization of requests without `sandboxOverride`.

GitOrigin-RevId: 2f438cf4aef1134e3149959d14aa731682168ae5
2026-10-07 17:59:22 +00:00
zm-oai ed59a6c1cd Preserve the CLI MXC preference in executor config reads (#51525)
## Why

Executor config reads omitted the startup `features.prefer_mxc` override, so clients could not see the CLI sandbox preference.

## What changed

- Include the explicit CLI `features.prefer_mxc` value in `environmentConfig/read` as a `session-flags` layer, above project config and below legacy managed file and MDM config.
- Retain only this preference from startup overrides.
- Expose `windows_mxc_allowed_by_config` to share MXC eligibility checks after callers resolve the active permission profile.

## Testing

Add CLI and remote executor coverage for preference propagation and filtering, plus a unit test verifying that both legacy managed config sources retain precedence.

GitOrigin-RevId: 5ac6f5257f1e807c2f197dcf5dcb2385cedca0ea
2026-10-07 00:29:04 +00:00
zm-oai 7efc49b258 Align Windows sandbox temp permissions with the child environment (#51512)
## Why

Windows temp grants could fall back to host `TEMP`/`TMP` values and bypass read-only or denied subpaths. Sandbox permissions must match the environment passed to the child process.

## What changed

- Resolve `:tmpdir` from absolute `TEMP`/`TMP` paths in the completed workload environment, preserving access modes and missing-path rules without falling back to host values.
- Deduplicate Windows environment keys case-insensitively in a deterministic order so permission resolution and the child environment select the same value.
- Use the resolved temp policy for elevated sandbox overrides across core execution, exec-server, and direct spawning.
- Launch direct-spawn sandbox wrappers with the supplied Codex executable, materializing an inner helper only when it is that executable.

## Testing

Add Windows regression coverage for temp-only writes, read-only and denied carveouts, mixed-case and duplicate environment keys, unavailable temp paths, and empty or missing write-root overrides. Exercise core execution and direct spawning, and extend exec-server RPC coverage to the elevated backend with temp values set through the environment policy.

GitOrigin-RevId: 16b8bd4702cc434fd743a08c75a3e4515780bff3
2026-10-06 23:21:06 +00:00
zm-oai 9545947c6d Fix Windows 10 drive-letter opens for no-follow filesystem operations (#51511)
## Why

On Windows 10, strict native opens can reject the DOS drive alias itself as a reparse point, preventing no-follow filesystem operations on ordinary drive-letter paths.

## What changed

Retry rejected drive-letter opens relative to a verified local volume root. Require the root to resolve to a physical disk volume directory without reparse attributes, and retain `OBJ_DONT_REPARSE` for paths beneath it so junctions remain blocked.

## Testing

Add Windows tests for file creation and reading through the volume fallback, opening the drive root, and rejecting junction traversal and creation. Validate accepted volume-root names and verify that named pipes are rejected without establishing a client connection.

GitOrigin-RevId: 51ffde4f77d2af45d18dfc4cb026d73a0e69b061
2026-10-06 23:20:40 +00:00
Alexi Christakis ddabe594e6 Bound relay connection attempts and handle pongs during blocked writes (#51502)
## Why

A stalled rendezvous WebSocket upgrade can prevent reconnects, while short-lived connections reset reconnect backoff too early. Blocked relay writes also prevent received pongs from clearing their heartbeat deadline.

## What changed

- Bound rendezvous WebSocket connection attempts with `DEFAULT_REMOTE_EXEC_SERVER_CONNECT_TIMEOUT`.
- Retain exponential reconnect backoff across short-lived connections, resetting it only after a connection lasts at least 120 seconds.
- Process pongs during blocked data writes while preserving the in-flight send and its independent write timeout. Prefer queued pongs over an expired heartbeat deadline.
- Abort the relay writer when its owning connection task is dropped.

## Testing

Add coverage for pongs arriving during blocked writes, missing and queued pongs, independent write timeouts, and writer cancellation. Extend reconnect tests to cover stalled WebSocket upgrades without re-registration and backoff reset after a stable session.

GitOrigin-RevId: 0efa350c2b4ada9b89e23df8909063fbb69f33dc
2026-10-06 23:07:25 +00:00
Alexi Christakis 0b47040dc9 Add correlated, credential-free rendezvous connection diagnostics (#51483)
## Why

Rendezvous connection warnings report only a generic WebSocket error, while debug logs include raw error text. Structured diagnostics make failures easier to investigate without logging potentially sensitive error payloads.

## What changed

- Generate a request ID for each connection attempt, send it as `x-request-id`, and include it in the connection span and connection, disconnection, and failure logs alongside the attempt count.
- Replace raw error logging with typed error categories, I/O error kinds, HTTP status codes, and allowlisted values from `x-codex-rendezvous-rejection-reason`.
- Ignore unknown rejection reasons and response bodies.

## Testing

Add tests for rejection-header allowlisting, typed I/O failures, and a rejected WebSocket handshake that verifies the request ID header and preserves the HTTP status and known rejection reason.

GitOrigin-RevId: a8274fec965bcf5b8453b047c0bb79396cdf6ba4
2026-10-06 21:30:08 +00:00
jif e32365a2c6 Allow larger shell snapshots when replaying from a file (#51350)
## Why

File replay can accommodate shell state larger than the 512 KiB budget used for environment replay.

## What changed

Allow up to 4 MiB of shell state and 8 MiB of capture output for file replay. Keep captured environments capped at 512 KiB and preserve the 512 KiB combined state-and-environment limit for environment replay. Report distinct failures for oversized capture output, state, and environments.

## Testing

Add replay-specific size-limit tests and enlarge the Bash integration-test snapshot to exercise file replay beyond the environment replay budget.

GitOrigin-RevId: 0210848eb398d75426cb8b4b3bfaa0bce25264b8
2026-10-06 12:10:58 +00:00
jif 588f616e8b Measure shell snapshot use and wait time per command (#51347)
## What changed

Add `codex.shell_snapshot.command` and `codex.shell_snapshot.wait_ms` metrics for eligible command preparations in the unified exec runtime and exec server. Tag observations with snapshot version, availability state, and whether replay was selected (`used`) or normal shell startup was used (`fallback`). Exclude background prewarming from command observations; `used` measures replay selection, not successful restoration or command completion.

## Testing

Extend snapshot retry tests to verify command counts and wait observations across fallback and recovery, excluding prewarm captures. Extend credential-broker approval tests to verify one `protected` snapshot observation for login-shell commands.

GitOrigin-RevId: d3d9f370b6bbba6dfc930a44044ce09373841799
2026-10-06 11:43:45 +00:00
viyatb-oai 7aa8f51049 Reject sandbox-writable bubblewrap executables from PATH (#51211)
## Why

Bubblewrap discovery probes executables before confinement. Excluding only the command's current directory leaves candidates in other writable roots eligible to run outside the sandbox.

## What changed

- Filter canonical `PATH` candidates using the filesystem policy and effective user permissions, including writable ancestors, symlinked roots, and full-disk write access. Preserve protected system installations while rejecting replaceable paths.
- Select the launcher with the command's permissions before the proc-mount preflight, retaining the bundled bubblewrap fallback.
- Use the effective permission profile and policy working directory for startup warning probes.

## Testing

Add unit coverage for writable roots, symlinks, read-only carveouts, replaceable parents, and full-disk policies. Add Linux integration tests showing writable `bwrap` candidates are neither probed nor launched, including when the command runs in a workspace subdirectory or uses managed networking with full-disk write access.

GitOrigin-RevId: 188c9f45e727eaace062f5abb1205dc23fdf3c51
2026-10-06 00:58:19 +00:00
Adam Perry @ OpenAI 42312d4ff4 Enforce required environment skills before model inference (#51157)
## What changed

- Accept per-environment `skills.required` lists through `environment/add` and `environments.toml`.
- Before inference, require each named skill to be enabled and supplied by the selected environment. Missing skills fail the turn before a model request, including when environment setup fails.
- Stop applying an environment's requirements after it is deselected. Exempt isolated Guardian reviewers, which have no skill catalog.

## Testing

Add tests for available, missing, disabled, and wrong-environment skills, failed environment setup, recovery after deselection, and propagation of TOML requirements to the correct environment.

GitOrigin-RevId: 302ced4774697d2f414f745fe0535e71f747eda2
2026-10-05 18:54:17 +00:00
Anton Panasenko ef8cfe5e96 Retry registry authentication outages and jitter executor reconnects (#50465)
## Why

Remote executors need to recover from confirmed authentication-service outages and spread reconnect attempts after a shared outage. Registration retries must remain limited to confirmed failures before a write, since replaying an ambiguous request can replace a newer registration.

## What changed

- Retry registry responses with HTTP 502 and `authentication_service_unavailable`, alongside the existing HTTP 503 `registration_conflict` retries.
- Accept structured registry errors in `detail`, keeping the canonical `error` authoritative when both are present.
- Randomize reconnect delays between half and all of the current exponential backoff, retaining the 30-second cap.

## Testing

Add coverage for reconnect jitter bounds, authentication-outage retry cancellation, error-envelope precedence, and preservation of Noise identity and initialized sessions across retries. Make the HTTP-header helper cleanup test wait for the helper PID before cancellation and verify process termination when the provider is dropped.

GitOrigin-RevId: 35fdb57732d17b0bbfeca8a4dc557a0988e29a31
2026-10-02 23:54:32 +00:00
Adam Perry @ OpenAI c39bfa4c8f Enable writable file streaming in exec-server (#50177)
## What changed

Advertise `fileWriteStreaming` and support `fs/open` with `mode: "replace"` to create or truncate a file for writing. Implement `fs/writeBlock` with explicit offsets and nonempty chunks of up to 1 MiB, rejecting ranges beyond the signed 64-bit file offset limit.

Apply write sandbox permissions when opening writable handles, including when full-disk reads are allowed. Keep `read` as the default open mode.

## Testing

Add integration coverage for positional writes, chunk and offset bounds, replacement truncation, read/write handle permissions, and sandbox write restrictions. Verify that duplicate handle IDs and exhausted handle capacity reject replacement opens without creating or truncating files.

GitOrigin-RevId: 696ee6437dd5f5b69d5a7667dddea0ff44472094
2026-10-02 04:25:52 +00:00
Adam Perry @ OpenAI d25c114d49 Bound in-flight file opens in exec-server (#50162)
## Why

The per-connection limit of 128 file read handles was checked only after opening the file, leaving pending opens outside the limit.

## What changed

Reserve a semaphore permit before polling the file-open future, counting pending opens and registered handles against the same limit. Release capacity when an open fails or is cancelled, or when a handle closes, even if a read still retains the file.

Use synchronous handle-table locks that never cross an await, and recheck duplicate IDs after opening to preserve the winning handle during concurrent opens.

## Testing

Add tests for stalled-open progress, pending-open admission limits, permit cleanup after failure or cancellation, capacity reuse while a file remains in use, and concurrent duplicate IDs.

GitOrigin-RevId: caabf38c74dda5951f2fc75234a7149daaa01263
2026-10-02 03:31:52 +00:00
Tamir Duberstein b06b7d2f77 Upgrade Windows bindings to windows-sys 0.61.2 (#50058)
## What changed

- Centralize `windows-sys` at version `0.61.2` in the workspace and migrate dependent crates to it.
- Adapt Windows API calls to the updated handle, boolean, and type definitions. Replace custom handle owners with `OwnedHandle` and use `BorrowedHandle` where ownership stays with the caller.
- Add explicit wrappers for non-owning Windows handles passed between threads.

## Testing

Enable the MCP refresh cleanup test on Windows. Retain process handles to verify that a superseded MCP server stays alive during an in-flight call, exits after cancellation, and leaves the replacement running until shutdown.

GitOrigin-RevId: 86f53d9b300d13edff7154f4a7c32e34dacd2919
2026-10-01 18:05:05 +00:00
swastik-oai 9552906b2b Protect the guardian decisions API key from environment forwarding (#50019)
## What changed

Add `CODEX_GUARDIAN_DECISIONS_API_KEY` to the non-inheritable environment variables and the HTTP header environment denylist. Case-insensitive filtering removes it from child process environments, including explicit shell policy and command overrides, and rejects its use through `http/request` header `value_env_var`.

## Testing

Extend regression coverage for inherited and overridden variables, mixed-case names, and HTTP header rejection before any network request is sent.

GitOrigin-RevId: 1adeef814fdccb2d6c77dd68f7a5dfcec0b41cc6
2026-10-01 15:57:53 +00:00
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