Commit Graph

16 Commits

  • Allow global network allowlist wildcard (#15549)
    ## Problem
    
    Today `codex-network-proxy` rejects a global `*` in
    `network.allowed_domains`, so there is no static way to configure a
    denylist-only posture for public hosts. Users have to enumerate broad
    allowlist patterns instead.
    
    ## Approach
    
    - Make global wildcard acceptance field-specific: `allowed_domains` can
    use `*`, while `denied_domains` still rejects a global wildcard.
    - Keep the existing evaluation order, so explicit denies still win first
    and local/private protections still apply unless separately enabled.
    - Add coverage for the denylist-only behavior and update the README to
    document it.
    
    ## Validation
    
    - `just fmt`
    - `cargo test -p codex-network-proxy` (full run had one unrelated flaky
    telemetry test:
    `network_policy::tests::emit_block_decision_audit_event_emits_non_domain_event`;
    reran in isolation and it passed)
    - `cargo test -p codex-network-proxy
    network_policy::tests::emit_block_decision_audit_event_emits_non_domain_event
    -- --exact --nocapture`
    - `just fix -p codex-network-proxy`
    - `just argument-comment-lint`
  • fix: support managed network allowlist controls (#12752)
    ## Summary
    - treat `requirements.toml` `allowed_domains` and `denied_domains` as
    managed network baselines for the proxy
    - in restricted modes by default, build the effective runtime policy
    from the managed baseline plus user-configured allowlist and denylist
    entries, so common hosts can be pre-approved without blocking later user
    expansion
    - add `experimental_network.managed_allowed_domains_only = true` to pin
    the effective allowlist to managed entries, ignore user allowlist
    additions, and hard-deny non-managed domains without prompting
    - apply `managed_allowed_domains_only` anywhere managed network
    enforcement is active, including full access, while continuing to
    respect denied domains from all sources
    - add regression coverage for merged-baseline behavior, managed-only
    behavior, and full-access managed-only enforcement
    
    ## Behavior
    Assuming `requirements.toml` defines both
    `experimental_network.allowed_domains` and
    `experimental_network.denied_domains`.
    
    ### Default mode
    - By default, the effective allowlist is
    `experimental_network.allowed_domains` plus user or persisted allowlist
    additions.
    - By default, the effective denylist is
    `experimental_network.denied_domains` plus user or persisted denylist
    additions.
    - Allowlist misses can go through the network approval flow.
    - Explicit denylist hits and local or private-network blocks are still
    hard-denied.
    - When `experimental_network.managed_allowed_domains_only = true`, only
    managed `allowed_domains` are respected, user allowlist additions are
    ignored, and non-managed domains are hard-denied without prompting.
    - Denied domains continue to be respected from all sources.
    
    ### Full access
    - With managed requirements present, the effective allowlist is pinned
    to `experimental_network.allowed_domains`.
    - With managed requirements present, the effective denylist is pinned to
    `experimental_network.denied_domains`.
    - There is no allowlist-miss approval path in full access.
    - Explicit denylist hits are hard-denied.
    - `experimental_network.managed_allowed_domains_only = true` now also
    applies in full access, so managed-only behavior remains in effect
    anywhere managed network enforcement is active.
  • fix: reject global wildcard network proxy domains (#13789)
    ## Summary
    - reject the global `*` domain pattern in proxy allow/deny lists and
    managed constraints introduced for testing earlier
    - keep exact hosts plus scoped wildcards like `*.example.com` and
    `**.example.com`
    - update docs and regression tests for the new invalid-config behavior
  • refactor: remove proxy admin endpoint (#13687)
    ## Summary
    - delete the network proxy admin server and its runtime listener/task
    plumbing
    - remove the admin endpoint config, runtime, requirement, protocol,
    schema, and debug-surface fields
    - update proxy docs to reflect the remaining HTTP and SOCKS listeners
    only
  • feat(network-proxy): add embedded OTEL policy audit logging (#12046)
    **PR Summary**
    
    This PR adds embedded-only OTEL policy audit logging for
    `codex-network-proxy` and threads audit metadata from `codex-core` into
    managed proxy startup.
    
    ### What changed
    - Added structured audit event emission in `network_policy.rs` with
    target `codex_otel.network_proxy`.
    - Emitted:
    - `codex.network_proxy.domain_policy_decision` once per domain-policy
    evaluation.
      - `codex.network_proxy.block_decision` for non-domain denies.
    - Added required policy/network fields, RFC3339 UTC millisecond
    `event.timestamp`, and fallback defaults (`http.request.method="none"`,
    `client.address="unknown"`).
    - Added non-domain deny audit emission in HTTP/SOCKS handlers for
    mode-guard and proxy-state denies, including unix-socket deny paths.
    - Added `REASON_UNIX_SOCKET_UNSUPPORTED` and used it for unsupported
    unix-socket auditing.
    - Added `NetworkProxyAuditMetadata` to runtime/state, re-exported from
    `lib.rs` and `state.rs`.
    - Added `start_proxy_with_audit_metadata(...)` in core config, with
    `start_proxy()` delegating to default metadata.
    - Wired metadata construction in `codex.rs` from session/auth context,
    including originator sanitization for OTEL-safe tagging.
    - Updated `network-proxy/README.md` with embedded-mode audit schema and
    behavior notes.
    - Refactored HTTP block-audit emission to a small local helper to reduce
    duplication.
    - Preserved existing unix-socket proxy-disabled host/path behavior for
    responses and blocked history while using an audit-only endpoint
    override (`server.address="unix-socket"`, `server.port=0`).
    
    ### Explicit exclusions
    - No standalone proxy OTEL startup work.
    - No `main.rs` binary wiring.
    - No `standalone_otel.rs`.
    - No standalone docs/tests.
    
    ### Tests
    - Extended `network_policy.rs` tests for event mapping, metadata
    propagation, fallbacks, timestamp format, and target prefix.
    - Extended HTTP tests to assert unix-socket deny block audit events.
    - Extended SOCKS tests to cover deny emission from handler deny
    branches.
    - Added/updated core tests to verify audit metadata threading into
    managed proxy state.
    
    ### Validation run
    - `just fmt`
    - `cargo test -p codex-network-proxy` 
    - `cargo test -p codex-core` ran with one unrelated flaky timeout
    (`shell_snapshot::tests::snapshot_shell_does_not_inherit_stdin`), and
    the test passed when rerun directly 
    
    ---------
    
    Co-authored-by: viyatb-oai <viyatb@openai.com>
  • feat(network-proxy): add MITM support and gate limited-mode CONNECT (#9859)
    ## Description
    - Adds MITM support (CA load/issue, TLS termination, optional body
    inspection).
    - Adds `codex-network-proxy init` to create
    `CODEX_HOME/network_proxy/mitm`.
    - Enforces limited-mode HTTPS correctly: `CONNECT` requires MITM,
    otherwise blocked with `mitm_required`.
    - Keeps `origin/main` layering/reload semantics (managed layers included
    in reload checks).
    - Centralizes block reasons (`REASON_MITM_REQUIRED`) and removes
    `println!`.
    - Scope is MITM-only (no SOCKS changes).
    
    gated by `mitm=false` (default)
  • fix(network-proxy): add unix socket allow-all and update seatbelt rules (#11368)
    ## Summary
    Adds support for a Unix socket escape hatch so we can bypass socket
    allowlisting when explicitly enabled.
    
    ## Description
    * added a new flag, `network.dangerously_allow_all_unix_sockets` as an
    explicit escape hatch
    * In codex-network-proxy, enabling that flag now allows any absolute
    Unix socket path from x-unix-socket instead of requiring each path to be
    explicitly allowlisted. Relative paths are still rejected.
    * updated the macOS seatbelt path in core so it enforces the same Unix
    socket behavior:
      * allowlisted sockets generate explicit network* subpath rules
      * allow-all generates a broad network* (subpath "/") rule
    
    ---------
    
    Co-authored-by: Codex <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
  • 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>
  • chore: change ConfigState so it no longer depends on a single config.toml file for reloading (#11262)
    If anything, it should depend on `ConfigLayerStack`.
    
    ---
    [//]: # (BEGIN SAPLING FOOTER)
    Stack created with [Sapling](https://sapling-scm.com). Best reviewed
    with [ReviewStack](https://reviewstack.dev/openai/codex/pull/11262).
    * #11207
    * __->__ #11262
  • chore: refactor network-proxy so that ConfigReloader is injectable behavior (#11114)
    Currently, `codex-network-proxy` depends on `codex-core`, but this
    should be the other way around. As a first step, refactor out
    `ConfigReloader`, which should make it easier to move
    `codex-rs/network-proxy/src/state.rs` to `codex-core` in a subsequent
    commit.
  • refactor(network-proxy): flatten network config under [network] (#10965)
    Summary:
    - Rename config table from network_proxy to network.
    - Flatten allowed_domains, denied_domains, allow_unix_sockets, and
    allow_local_binding onto NetworkProxySettings.
    - Update runtime, state constraints, tests, and README to the new config
    shape.
  • Wire up cloud reqs in exec, app-server (#10241)
    We're fetching cloud requirements in TUI in
    https://github.com/openai/codex/pull/10167.
    
    This adds the same fetching in exec and app-server binaries also.
  • Fetch Requirements from cloud (#10167)
    Load requirements from Codex Backend. It only does this for enterprise
    customers signed in with ChatGPT.
    
    Todo in follow-up PRs:
    * Add to app-server and exec too
    * Switch from fail-open to fail-closed on failure
  • 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: introducing a network sandbox proxy (#8442)
    This add a new crate, `codex-network-proxy`, a local network proxy
    service used by Codex to enforce fine-grained network policy (domain
    allow/deny) and to surface blocked network events for interactive
    approvals.
    
    - New crate: `codex-rs/network-proxy/` (`codex-network-proxy` binary +
    library)
    - Core capabilities:
      - HTTP proxy support (including CONNECT tunneling)
      - SOCKS5 proxy support (in the later PR)
    - policy evaluation (allowed/denied domain lists; denylist wins;
    wildcard support)
      - small admin API for polling/reload/mode changes
    - optional MITM support for HTTPS CONNECT to enforce “limited mode”
    method restrictions (later PR)
    
    Will follow up integration with codex in subsequent PRs.
    
    ## Testing
    
    - `cd codex-rs && cargo build -p codex-network-proxy`
    - `cd codex-rs && cargo run -p codex-network-proxy -- proxy`