mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
dev/kyleb/plugin-script-command-resolver
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9e905528bb |
Fix custom CA login behind TLS-inspecting proxies (#20676)
Refs: https://linear.app/openai/issue/SE-6311/login-fails-for-experian-users-behind-tls-inspecting-proxy ## Summary - When a custom CA bundle is configured, force the shared `codex-client` reqwest builder onto rustls before registering custom roots. - Add the `rustls-tls-native-roots` reqwest feature so the rustls client preserves native roots plus the enterprise CA bundle. - Add subprocess TLS coverage for both a direct local TLS 1.3 server and a hermetic local CONNECT TLS-intercepting proxy that forwards a token-exchange-shaped POST to a local origin. ## Plain-language explanation Experian users are behind a TLS-inspecting proxy, so the login token exchange needs to trust the enterprise CA bundle from `CODEX_CA_CERTIFICATE` or `SSL_CERT_FILE`. Before this change, that custom-CA branch still used reqwest default TLS selection, which could fail in the proxy environment. Now, only when a custom CA is configured, Codex selects rustls first and then adds the custom CA roots, matching the validated behavior from the Experian test build while leaving normal system-root clients unchanged. The new regression test recreates the enterprise-proxy shape locally: the probe client sends an HTTPS `POST /oauth/token` through an explicit HTTP CONNECT proxy, the proxy presents a leaf certificate signed by a runtime-generated test CA, decrypts the request, forwards it to a local origin, and relays the `ok` response back. ## Scope note - The actual production fix is the first commit: `8368119282 Fix custom CA reqwest clients to use rustls`. - The second commit is integration-test coverage only. It generates all test CA and localhost certificate material at runtime. ## Validation - `cd codex-rs && cargo test -p codex-client --test ca_env posts_to_token_origin_through_tls_intercepting_proxy_with_custom_ca_bundle -- --nocapture` - `cd codex-rs && cargo test -p codex-client` - `cd codex-rs && cargo test -p codex-login` - `cd codex-rs && just fmt` - `cd codex-rs && just bazel-lock-update` - `cd codex-rs && just bazel-lock-check` - `cd codex-rs && just fix -p codex-client` |
||
|
|
8f705b0702 |
[codex] Defer steering until after sampling the model post-compaction (#17163)
## Summary - keep pending steered input buffered until the active user prompt has received a model response - keep steering pending across auto-compact when there is real model/tool continuation to resume - allow queued steering to follow compaction immediately when the prior model response was already final - keep pending-input follow-up owned by `run_turn` instead of folding it into `SamplingRequestResult` - add regression coverage for mid-turn compaction, final-response compaction, and compaction triggered before the next request after tool output ## Root Cause Steered input was drained at the top of every `run_turn` loop. After auto-compaction, the loop continued and immediately appended any pending steer after the compact summary, making a queued prompt look like the newest task instead of letting the model first resume interrupted model/tool work. ## Implementation Notes This patch keeps the follow-up signals separated: - `SamplingRequestResult.needs_follow_up` means model/tool continuation is needed - `sess.has_pending_input().await` means queued user steering exists - `run_turn` computes the combined loop condition from those two signals In `run_turn`: ```rust let has_pending_input = sess.has_pending_input().await; let needs_follow_up = model_needs_follow_up || has_pending_input; ``` After auto-compact we choose whether the next request may drain steering: ```rust can_drain_pending_input = !model_needs_follow_up; ``` That means: - model/tool continuation + pending steer: compact -> resume once without draining steer - completed model answer + pending steer: compact -> drain/send the steer immediately - fresh user prompt: do not drain steering before the model has answered the prompt once The drain is still only `sess.get_pending_input().await`; when `can_drain_pending_input` is false, core uses an empty local vec and leaves the steer pending in session state. ## Validation - PASS `cargo test -p codex-core --test all steered_user_input -- --nocapture` - PASS `just fmt` - PASS `git diff --check` - NOT PASSING HERE `just fix -p codex-core` currently stops before linting this change on an unrelated mainline test-build error: `core/src/tools/spec_tests.rs` initializes `ToolsConfigParams` without `image_generation_tool_auth_allowed`; this PR does not touch that file. |
||
|
|
3e96c867fe |
use scopes_supported for OAuth when present on MCP servers (#14419)
Fixes [#8889](https://github.com/openai/codex/issues/8889). ## Summary - Discover and use advertised MCP OAuth `scopes_supported` when no explicit or configured scopes are present. - Apply the same scope precedence across `mcp add`, `mcp login`, skill dependency auto-login, and app-server MCP OAuth login. - Keep discovered scopes ephemeral and non-persistent. - Retry once without scopes for CLI and skill auto-login flows if the OAuth provider rejects discovered scopes. ## Motivation Some MCP servers advertise the scopes they expect clients to request during OAuth, but Codex was ignoring that metadata and typically starting OAuth with no scopes unless the user manually passed `--scopes` or configured `server.scopes`. That made compliant MCP servers harder to use out of the box and is the behavior described in [#8889](https://github.com/openai/codex/issues/8889). This change also brings our behavior in line with the MCP authorization spec's scope selection guidance: https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#scope-selection-strategy ## Behavior Scope selection now follows this order everywhere: 1. Explicit request scopes / CLI `--scopes` 2. Configured `server.scopes` 3. Discovered `scopes_supported` 4. Legacy empty-scope behavior Compatibility notes: - Existing working setups keep the same behavior because explicit and configured scopes still win. - Discovered scopes are never written back into config or token storage. - If discovery is missing, malformed, or empty, behavior falls back to the previous empty-scope path. - App-server login gets the same precedence rules, but does not add a transparent retry path in this change. ## Implementation - Extend streamable HTTP OAuth discovery to parse and normalize `scopes_supported`. - Add a shared MCP scope resolver in `core` so all login entrypoints use the same precedence rules. - Preserve provider callback errors from the OAuth flow so CLI/skill flows can safely distinguish provider rejections from other failures. - Reuse discovered scopes from the existing OAuth support check where possible instead of persisting new config. |