Commit Graph

5 Commits

  • feat(network-proxy): structured policy signaling and attempt correlation to core (#11662)
    ## Summary
    When network requests were blocked, downstream code often had to infer
    ask vs deny from free-form response text. That was brittle and led to
    incorrect approval behavior.
    This PR fixes the proxy side so blocked decisions are structured and
    request metadata survives reliably.
    
    ## Description
    - Blocked proxy responses now carry consistent structured policy
    decision data.
    - Request attempt metadata is preserved across proxy env paths
    (including ALL_PROXY flows).
    - Header stripping was tightened so we still remove unsafe forwarding
    headers, but keep metadata needed for policy handling.
    - Block messages were clarified (for example, allowlist miss vs explicit
    deny).
    - Added unified violation log entries so policy failures can be
    inspected in one place.
    - Added/updated tests for these behaviors.
    
    ---------
    
    Co-authored-by: Codex <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
  • feat: reserve loopback ephemeral listeners for managed proxy (#11269)
    Codex may run many per-thread proxy instances, so hardcoded proxy ports
    are brittle and conflict-prone. The previous "ephemeral" approach still
    had a race: `build()` read `local_addr()` from temporary listeners and
    dropped them before `run()` rebound the ports. That left a
    [TOCTOU](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use)
    window where the OS (or another process) could reuse the same port,
    causing intermittent `EADDRINUSE` and partial proxy startup.
    
    Change the managed proxy path to reserve real listener sockets up front
    and keep them alive until startup:
    
    - add `ReservedListeners` on `NetworkProxy` to hold HTTP/SOCKS/admin std
    listeners allocated during `build()`
    - in managed mode, bind `127.0.0.1:0` for each listener and carry those
    bound sockets into `run()` instead of rebinding by address later
    - add `run_*_with_std_listener` entry points for HTTP, SOCKS5, and admin
    servers so `run()` can start services from already-reserved sockets
    - keep static/configured ports only when `managed_by_codex(false)`,
    including explicit `socks_addr` override support
    - remove fallback synthetic port allocation and add tests for managed
    ephemeral loopback binding and unmanaged configured-port behavior
    
    This makes managed startup deterministic, avoids port collisions, and
    preserves the intended distinction between Codex-managed ephemeral ports
    and externally managed fixed ports.
  • feat(network-proxy): add structured policy decision to blocked errors (#10420)
    ## Summary
    Add explicit, model-visible network policy decision metadata to blocked
    proxy responses/errors.
    
    Introduces a standardized prefix line: `CODEX_NETWORK_POLICY_DECISION
    {json}`
    
    and wires it through blocked paths for:
    - HTTP requests
    - HTTPS CONNECT
    - SOCKS5 TCP/UDP denials
    
    ## Why
    The model should see *why* a request was blocked
    (reason/source/protocol/host/port) so it can choose the correct next
    action.
    
    ## Notes
    - This PR is intentionally independent of config-layering/network-rule
    runtime integration.
    - Focus is blocked decision surface only.
  • chore: introduce *Args types for new() methods (#10009)
    Constructors with long param lists can be hard to reason about when a
    number of the args are `None`, in practice. Introducing a struct to use
    as the args type helps make things more self-documenting.
  • feat(network-proxy): add a SOCKS5 proxy with policy enforcement (#9803)
    ### Summary
    - Adds an optional SOCKS5 listener via `rama-socks5`
    - SOCKS5 is disabled by default and gated by config
    - Reuses existing policy enforcement and blocked-request recording
    - Blocks SOCKS5 in limited mode to prevent method-policy bypass
    - Applies bind clamping to the SOCKS5 listener
    
    ### Config
    New/used fields under `network_proxy`:
    - `enable_socks5`
    - `socks_url`
    - `enable_socks5_udp`
    
    ### Scope
    - Changes limited to `codex-rs/network-proxy` (+ `codex-rs/Cargo.lock`)
    
    ### Testing
    ```bash
    cd codex-rs
    just fmt
    cargo test -p codex-network-proxy --offline