## Why
The fixture token `new` can appear in randomly generated Base64 public keys, causing the executor registration response's credential check to reject valid test responses.
## What changed
Use hyphenated fixture tokens that cannot occur in Base64 keys. Set the retry test's X25519 public key to a value containing `new` so the former collision is exercised deterministically.
GitOrigin-RevId: 059043eddc388a69c4659d6cdcac6ee107ae1973
## What changed
Remove `AuthProvider::resolve_auth_headers` and use `apply_auth_headers` as the async interface for header-only authentication. Migrate providers, callers, and existing tests to the shared interface, passing an empty `HeaderMap` when only authentication headers are needed.
Document that providers may refresh credentials asynchronously and that callers must use the returned header map so providers can remove superseded credentials.
GitOrigin-RevId: 42449de6fddd2be2c50c475c8e92628493197007
## Why
Remote registry requests need to recover when credentials are rejected or rotated while `exec-server` is running. Concurrent requests should reuse refreshed credentials rather than refresh the replacement token again.
## What changed
- Add an `AuthProvider` recovery hook and retry registry registration, connection, and harness-key validation once after a `401` when the provider supplies replacement credentials.
- Use live ChatGPT authentication for remote `exec-server` and guard proactive and unauthorized refreshes so concurrent callers share the completed refresh.
- Allow executor credentials to retry when the parent has already supplied a valid replacement.
- Keep connection authentication, refresh, and retry within the original connection deadline.
## Testing
Add coverage for concurrent refreshes, stored and parent-supplied credential rotation, refresh failures, retry limits, and connection deadlines, plus a CLI integration test for refresh and credential reload in a running executor.
GitOrigin-RevId: 9ed533e410762c7ac8b7c0c30bb93fd20d96778b
## Why
Synchronous auth header construction could silently return no credentials when managed authentication became unavailable. Callers need an error to avoid sending requests with missing or partial authentication.
## What changed
- Make `AuthProvider::add_auth_headers`, `to_auth_headers`, and auth header telemetry fallible, and propagate failures through request and WebSocket setup.
- Return a transient error when managed authentication is unavailable, and preserve network policy denials through auth error conversion.
- Retry transient MCP authentication errors while treating build errors and policy denials as terminal.
- Cancel local MCP event streams before resolving authentication so cleanup still works when credentials become unavailable.
## Testing
Add regression coverage for rejected partial authentication, async header resolution, terminal auth errors without sending requests, managed account changes, MCP retry classification, and local stream cancellation after authentication becomes unavailable.
GitOrigin-RevId: 39d981e232cba1e302de502a2fa6239101114ed1
## What changed
- Record executor handshake rejections and pending-validation resets in promptly completed diagnostic spans, with classified reasons and registry HTTP status when available. Normalize stream IDs as UUIDs and cap diagnostics at 100 per minute per relay connection, followed by a suppression marker.
- Add elapsed time and connection identifiers to harness handshake diagnostics, including initialization timeouts, and classify WebSocket read failures from typed errors.
- Forward valid stream UUIDs to harness key validation requests through the `x-codex-noise-stream-id` header.
## Testing
Extend tests to cover diagnostic rate limits, timeout correlation, prompt span export, typed WebSocket error classification, and optional stream ID headers. Verify that diagnostic output excludes authorization secrets, registry response text, reset reasons, and invalid stream IDs.
GitOrigin-RevId: 2c224e2d2828b300164868b10806add410e148b2
## What changed
- Add `RemoteEnvironmentConfig::with_executor_credential_auth()` for Noise transport, requiring exactly one `Authorization: Bearer <credential>` header without accompanying account credentials.
- Require HTTPS registry URLs except on loopback, and bypass system proxies for loopback HTTP requests.
- Mark credentials as sensitive, suppress registry diagnostics that could echo them, and reject registration responses containing the credential while preserving recognized retry error codes.
- Reject scoped executor credentials for Direct registration and WebSocket connections. Keep legacy authentication as the default.
## Testing
Add tests for invalid credential headers, HTTPS and loopback restrictions, proxy bypass, credential echoes in registry responses, and rejection before Direct transport sends requests.
GitOrigin-RevId: a427d648a0520d2e187dd40ca63268903a949f94
## Why
Direct mode serves executor requests but applied the client's 8 KiB inbound request limit, causing larger `fs/writeFile` requests to disconnect the executor.
## What changed
Use a dedicated direct WebSocket connection constructor that omits the client inbound request limit while retaining WebSocket message and frame limits.
## Testing
Add a regression test that runs the direct environment and verifies successful file writes above the client request limit using both text and binary WebSocket messages.
GitOrigin-RevId: e8e77a5e8581ab9eb98446e23b77a6da41d64868
## 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
## 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
## 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
## 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
## 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
## Why
Allow remote exec servers to connect directly to AWS-hosted registries that
authenticate registry requests and WebSocket handshakes with AWS SigV4.
## What changed
- Add `--remote-transport direct` with SigV4 profile, region, and service
options while keeping Noise as the default transport.
- Register the `direct_jsonrpc_v1` transport and carry plain exec-server
JSON-RPC messages over the authenticated WebSocket.
- Reuse direct registrations across transient disconnects, refresh them after
a `409 Conflict`, and require TLS for non-loopback endpoints.
## Testing
- Cover CLI validation and SigV4 request signing.
- Exercise direct registration, handshake retry behavior, JSON-RPC
interoperability, and process recovery after reconnecting.
GitOrigin-RevId: 0755df330ba3abe5db0a516fdaa49338d9bbe2d2
## Why
Remote environment registration can return an explicit `503` `registration_conflict` after the registry finishes its own recovery attempts. Retrying ambiguous failures is unsafe because a timed-out request may still have replaced a newer registration.
## What changed
- Retry only explicit `registration_conflict` responses with jittered backoff, both during initial registration and after a rejected relay connection.
- Apply the existing connection timeout to the complete registration attempt, including response-body diagnostics.
- Keep retry waits and in-flight requests cancellable while preserving the Noise identity and initialized session across successful recovery.
## Testing
Added unit coverage for retry eligibility and timeout handling, plus relay tests for identity and session preservation and prompt shutdown during registration.
GitOrigin-RevId: 374e6fdac4755f377cbea9400c76a228b790945a
## Why
Noise environment registry requests need to follow the exec server's effective
outbound proxy policy without exposing registry URLs or response headers in HTTP
diagnostics.
## What changed
- Build the registry client from the supplied `HttpClientFactory` and use a
route-aware API client with redirects and request logging disabled.
- Defer construction of the Noise connection provider until the outbound HTTP
policy is available.
- Map route-aware request failures into registry errors while retaining timeout
detection across response body reads.
## Testing
Add coverage for system-proxy routing, sensitive registry metadata redaction,
stalled response-body timeouts, and prepared Noise configuration validation.
GitOrigin-RevId: d312dfe037f72732085bf38109af44df76ed0b53
## Why
Delegated HTTP requests need to honor the same outbound proxy policy as the
Codex process that starts the exec server.
## What changed
- Pass the configured `HttpClientFactory` through local and remote exec-server
startup and use route-aware client pools for delegated HTTP and local MCP
requests.
- Preserve per-request timeouts and follow-or-stop redirect behavior while
keeping request URLs and sensitive response headers out of diagnostics.
## Testing
- Cover configured system-proxy routing across the exec-server transport.
- Cover both redirect policies and verify that success and failure logs do not
expose request or response secrets.
GitOrigin-RevId: 4af6aec1d265c4db62dfcb6e1fb076fb31736137
## Why
The transport in
[openai/codex#26242](https://github.com/openai/codex/pull/26242) needs
to be used by every remote orchestrator-to-executor connection before
JSON-RPC traffic starts.
## Changes
- Generates one executor Noise identity when remote exec-server starts
and registers its public key.
- Creates a harness identity for each physical remote environment
connection.
- Fetches a fresh registry bundle before connecting and validates the
authenticated harness key before completing the executor handshake.
- Multiplexes encrypted logical streams over the existing executor
WebSocket.
- Adds bounded stream, handshake-failure, and reassembly state.
- Adds safe lifecycle diagnostics without logging keys, authorizations,
plaintext, or ciphertext.
- Covers reconnects, replay rejection, validation failure, framing
limits, and encrypted JSON-RPC tool traffic.
## Stack
1. [openai/codex#26242](https://github.com/openai/codex/pull/26242):
Noise channel and relay transport
2. **[openai/codex#26245](https://github.com/openai/codex/pull/26245)**:
remote registration and runtime activation
## Verification
- `just test -p codex-exec-server`
- `just fix -p codex-exec-server`
- `just bazel-lock-check`
- `cargo shear`
---------
Co-authored-by: Codex <noreply@openai.com>