9 Commits

  • Disable empty Cargo test targets (#21584)
    ## Summary
    
    `cargo test` has entails both running standard Rust tests and doctests.
    It turns out that the doctest discovery is fairly slow, and it's a cost
    you pay even for crates that don't include any doctests.
    
    This PR disables doctests with `doctest = false` for crates that lack
    any doctests.
    
    For the collection of crates below, this speeds up test execution by
    >4x.
    
    E.g., before this PR:
    
    ```
    Benchmark 1: cargo test     -p codex-utils-absolute-path     -p codex-utils-cache     -p codex-utils-cli     -p codex-utils-home-dir     -p codex-utils-output-truncation     -p codex-utils-path     -p codex-utils-string     -p codex-utils-template     -p codex-utils-elapsed     -p codex-utils-json-to-toml
      Time (mean ± σ):      1.849 s ±  4.455 s    [User: 0.752 s, System: 1.367 s]
      Range (min … max):    0.418 s … 14.529 s    10 runs
    ```
    
    And after:
    
    ```
    Benchmark 1: cargo test     -p codex-utils-absolute-path     -p codex-utils-cache     -p codex-utils-cli     -p codex-utils-home-dir     -p codex-utils-output-truncation     -p codex-utils-path     -p codex-utils-string     -p codex-utils-template     -p codex-utils-elapsed     -p codex-utils-json-to-toml
      Time (mean ± σ):     428.6 ms ±   6.9 ms    [User: 187.7 ms, System: 219.7 ms]
      Range (min … max):   418.0 ms … 436.8 ms    10 runs
    ```
    
    For a single crate, with >2x speedup, before:
    
    ```
    Benchmark 1: cargo test -p codex-utils-string
      Time (mean ± σ):     491.1 ms ±   9.0 ms    [User: 229.8 ms, System: 234.9 ms]
      Range (min … max):   480.9 ms … 512.0 ms    10 runs
    ```
    
    And after:
    
    ```
    Benchmark 1: cargo test -p codex-utils-string
      Time (mean ± σ):     213.9 ms ±   4.3 ms    [User: 112.8 ms, System: 84.0 ms]
      Range (min … max):   206.8 ms … 221.0 ms    13 runs
    ```
    
    Co-authored-by: Codex <noreply@openai.com>
  • [codex] add responses proxy JSON dumps (#16753)
    This makes Responses API proxy request/response dumping first-class by
    adding an optional `--dump-dir` flag that emits paired JSON files with
    shared sequence/timestamp prefixes, captures full request and response
    headers and records parsed JSON bodies.
  • feat: support proxy for ws connection (#9409)
    unfortunately tokio-tungstenite doesn't support proxy configuration
    outbox, while https://github.com/snapview/tokio-tungstenite/pull/370 is
    in review, we can depend on source code for now.
  • chore: add cargo-deny configuration (#7119)
    - add GitHub workflow running cargo-deny on push/PR
    - document cargo-deny allowlist with workspace-dep notes and advisory
    ignores
    - align workspace crates to inherit version/edition/license for
    consistent checks
  • chore: remove responses-api-proxy from the multitool (#4404)
    This removes the `codex responses-api-proxy` subcommand in favor of
    running it as a standalone CLI.
    
    As part of this change, we:
    
    - remove the dependency on `tokio`/`async/await` as well as `codex_arg0`
    - introduce the use of `pre_main_hardening()` so `CODEX_SECURE_MODE=1`
    is not required
    
    ---
    [//]: # (BEGIN SAPLING FOOTER)
    Stack created with [Sapling](https://sapling-scm.com). Best reviewed
    with [ReviewStack](https://reviewstack.dev/openai/codex/pull/4404).
    * #4406
    * __->__ #4404
    * #4403
  • feat: introduce responses-api-proxy (#4246)
    Details are in `responses-api-proxy/README.md`, but the key contribution
    of this PR is a new subcommand, `codex responses-api-proxy`, which reads
    the auth token for use with the OpenAI Responses API from `stdin` at
    startup and then proxies `POST` requests to `/v1/responses` over to
    `https://api.openai.com/v1/responses`, injecting the auth token as part
    of the `Authorization` header.
    
    The expectation is that `codex responses-api-proxy` is launched by a
    privileged user who has access to the auth token so that it can be used
    by unprivileged users of the Codex CLI on the same host.
    
    If the client only has one user account with `sudo`, one option is to:
    
    - run `sudo codex responses-api-proxy --http-shutdown --server-info
    /tmp/server-info.json` to start the server
    - record the port written to `/tmp/server-info.json`
    - relinquish their `sudo` privileges (which is irreversible!) like so:
    
    ```
    sudo deluser $USER sudo || sudo gpasswd -d $USER sudo || true
    ```
    
    - use `codex` with the proxy (see `README.md`)
    - when done, make a `GET` request to the server using the `PORT` from
    `server-info.json` to shut it down:
    
    ```shell
    curl --fail --silent --show-error "http://127.0.0.1:$PORT/shutdown"
    ```
    
    To protect the auth token, we:
    
    - allocate a 1024 byte buffer on the stack and write `"Bearer "` into it
    to start
    - we then read from `stdin`, copying to the contents into the buffer
    after the prefix
    - after verifying the input looks good, we create a `String` from that
    buffer (so the data is now on the heap)
    - we zero out the stack-allocated buffer using
    https://crates.io/crates/zeroize so it is not optimized away by the
    compiler
    - we invoke `.leak()` on the `String` so we can treat its contents as a
    `&'static str`, as it will live for the rest of the processs
    - on UNIX, we `mlock(2)` the memory backing the `&'static str`
    - when using the `&'static str` when building an HTTP request, we use
    `HeaderValue::from_static()` to avoid copying the `&str`
    - we also invoke `.set_sensitive(true)` on the `HeaderValue`, which in
    theory indicates to other parts of the HTTP stack that the header should
    be treated with "special care" to avoid leakage:
    
    
    https://github.com/hyperium/http/blob/439d1c50d71e3be3204b6c4a1bf2255ed78e1f93/src/header/value.rs#L346-L376