mirror of
https://github.com/openai/codex.git
synced 2026-04-24 14:45:27 +00:00
consolidate docs
This commit is contained in:
117
codex-rs/network-proxy/README.md
Normal file
117
codex-rs/network-proxy/README.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# codex-network-proxy
|
||||
|
||||
`codex-network-proxy` is Codex's local network policy enforcement proxy. It runs:
|
||||
|
||||
- an HTTP proxy (default `127.0.0.1:3128`)
|
||||
- a SOCKS5 proxy (default `127.0.0.1:8081`)
|
||||
- an admin HTTP API (default `127.0.0.1:8080`)
|
||||
|
||||
It enforces an allow/deny policy and a "limited" mode intended for read-only network access.
|
||||
|
||||
## Quickstart
|
||||
|
||||
### 1) Configure
|
||||
|
||||
`codex-network-proxy` reads from Codex's merged `config.toml` (via `codex-core` config loading).
|
||||
|
||||
Example config:
|
||||
|
||||
```toml
|
||||
[network_proxy]
|
||||
enabled = true
|
||||
proxy_url = "http://127.0.0.1:3128"
|
||||
admin_url = "http://127.0.0.1:8080"
|
||||
mode = "limited" # or "full"
|
||||
|
||||
[network_proxy.policy]
|
||||
# If allowed_domains is non-empty, hosts must match it (unless denied).
|
||||
allowed_domains = ["*.openai.com"]
|
||||
denied_domains = ["evil.example"]
|
||||
|
||||
# If false, loopback (localhost/127.0.0.1/::1) is rejected unless explicitly allowlisted.
|
||||
allow_local_binding = false
|
||||
|
||||
# macOS-only: allows proxying to a unix socket when request includes `x-unix-socket: /path`.
|
||||
allow_unix_sockets = ["/tmp/example.sock"]
|
||||
|
||||
[network_proxy.mitm]
|
||||
# Enables CONNECT MITM for limited-mode HTTPS. If disabled, CONNECT is blocked in limited mode.
|
||||
enabled = true
|
||||
|
||||
# When true, logs request/response body sizes (up to max_body_bytes).
|
||||
inspect = false
|
||||
max_body_bytes = 4096
|
||||
|
||||
# These are relative to the directory containing config.toml when relative.
|
||||
ca_cert_path = "network_proxy/mitm/ca.pem"
|
||||
ca_key_path = "network_proxy/mitm/ca.key"
|
||||
```
|
||||
|
||||
### 2) Initialize MITM directories (optional)
|
||||
|
||||
This ensures the MITM directory exists (and is a good smoke test that the binary runs):
|
||||
|
||||
```bash
|
||||
cargo run -p codex-network-proxy -- init
|
||||
```
|
||||
|
||||
### 3) Run the proxy
|
||||
|
||||
```bash
|
||||
cargo run -p codex-network-proxy --
|
||||
```
|
||||
|
||||
### 4) Point a client at it
|
||||
|
||||
For HTTP(S) traffic:
|
||||
|
||||
```bash
|
||||
export HTTP_PROXY="http://127.0.0.1:3128"
|
||||
export HTTPS_PROXY="http://127.0.0.1:3128"
|
||||
```
|
||||
|
||||
For SOCKS5 traffic:
|
||||
|
||||
```bash
|
||||
export ALL_PROXY="socks5://127.0.0.1:8081"
|
||||
```
|
||||
|
||||
### 5) Understand blocks / debugging
|
||||
|
||||
When a request is blocked, the proxy responds with `403` and includes:
|
||||
|
||||
- `x-proxy-error`: one of:
|
||||
- `blocked-by-allowlist`
|
||||
- `blocked-by-denylist`
|
||||
- `blocked-by-method-policy`
|
||||
- `blocked-by-mitm-required`
|
||||
- `blocked-by-policy`
|
||||
|
||||
In "limited" mode, only `GET`, `HEAD`, and `OPTIONS` are allowed. In addition, HTTPS `CONNECT`
|
||||
requires MITM to be enabled to allow read-only HTTPS; otherwise the proxy blocks CONNECT with
|
||||
reason `mitm_required`.
|
||||
|
||||
## Admin API
|
||||
|
||||
The admin API is a small HTTP server intended for debugging and runtime adjustments.
|
||||
|
||||
Endpoints:
|
||||
|
||||
```bash
|
||||
curl -sS http://127.0.0.1:8080/health
|
||||
curl -sS http://127.0.0.1:8080/config
|
||||
curl -sS http://127.0.0.1:8080/patterns
|
||||
curl -sS http://127.0.0.1:8080/blocked
|
||||
|
||||
# Switch modes without restarting:
|
||||
curl -sS -X POST http://127.0.0.1:8080/mode -d '{"mode":"full"}'
|
||||
|
||||
# Force a config reload:
|
||||
curl -sS -X POST http://127.0.0.1:8080/reload
|
||||
```
|
||||
|
||||
## Platform notes
|
||||
|
||||
- Unix socket proxying via the `x-unix-socket` header is **macOS-only**; other platforms will
|
||||
reject unix socket requests.
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
# Codex Network Proxy Design
|
||||
|
||||
This document describes the Codex network proxy that runs outside the sandbox and enforces an allow-only network policy for sandboxed subprocesses. The proxy is a single binary with HTTP proxying, SOCKS5, and an admin API. Codex owns the policy state in `~/.codex/config.toml`; the proxy reads that configuration and applies it at the network edge.
|
||||
|
||||
## Goals
|
||||
|
||||
1. Enforce allow-only network access with denylist precedence.
|
||||
2. Support wildcard domain patterns, including apex match for `*.domain.tld`.
|
||||
3. Allow two modes: **limited** (read-only) and **full** (all methods).
|
||||
4. Provide optional **MITM** to enforce read-only on HTTPS.
|
||||
5. Allow hot-reloaded configuration via admin API.
|
||||
6. Provide clear audit logging of allow/deny decisions and policy changes.
|
||||
7. Enable a single binary with HTTP proxy, SOCKS5 proxy, and admin API.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Enterprise policy distribution or centralized multi-tenant orchestration.
|
||||
- Deep packet inspection beyond the supported HTTP/HTTPS interception modes.
|
||||
- Perfect protocol coverage for all network traffic types.
|
||||
|
||||
## Architecture
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Sandbox["Codex (sandboxed)"]
|
||||
Tools["commands / tools<br/>curl, git, python"]
|
||||
SocksClients["SOCKS clients"]
|
||||
end
|
||||
|
||||
subgraph Proxy["codex-network-proxy (host process)"]
|
||||
HttpProxy["HTTP Proxy :3128<br/>CONNECT tunnel<br/>MITM (optional)"]
|
||||
SocksProxy["SOCKS5 Proxy :8081"]
|
||||
Admin["Admin API :8080<br/>/health /config /blocked<br/>/reload /mode"]
|
||||
end
|
||||
|
||||
Config["~/.codex/config.toml<br/>[network_proxy.*]"]
|
||||
|
||||
Tools -->|HTTP| HttpProxy
|
||||
SocksClients -->|SOCKS5| SocksProxy
|
||||
Admin -->|reads + reloads| Config
|
||||
```
|
||||
|
||||
## Configuration Model
|
||||
|
||||
The proxy reads `~/.codex/config.toml`:
|
||||
|
||||
- `[network_proxy]` for endpoints, mode, and toggles.
|
||||
- `[network_proxy.policy]` for `allowed_domains` / `denied_domains` (and, on macOS, optional local IPC allowances).
|
||||
- `[network_proxy.mitm]` for MITM CA paths and inspection settings.
|
||||
|
||||
Codex is the source of truth. Approval actions update the config and trigger a proxy reload.
|
||||
|
||||
## Enforcement Model
|
||||
|
||||
- **Allow/deny precedence:** denylist wins; allowlist is required for access.
|
||||
- **Limited mode:** only GET/HEAD/OPTIONS are permitted. HTTPS requires MITM to enforce method constraints; otherwise CONNECT is blocked with a clear reason.
|
||||
- **Full mode:** all methods allowed; CONNECT tunneling is permitted without MITM.
|
||||
|
||||
## macOS Sandbox Integration (Seatbelt)
|
||||
|
||||
On macOS, Codex uses Seatbelt (`sandbox-exec`) for OS-level enforcement.
|
||||
|
||||
Key points:
|
||||
|
||||
- **Per-domain gating happens in the proxy**, not in Seatbelt: Seatbelt network rules are intentionally limited to loopback proxy ports (e.g. `localhost:3128` / `localhost:8081`) so all outbound traffic is forced through the proxy, which then applies the allow/deny policy and prompts.
|
||||
- **Local IPC is deny-by-default** when proxy-restricted network access is active. Some tools rely on Unix domain sockets (e.g. the SSH agent). These are blocked unless explicitly allowed via:
|
||||
- `network_proxy.policy.allow_unix_sockets` (absolute socket paths, `$SSH_AUTH_SOCK`, or the `ssh-agent` preset), and/or
|
||||
- `network_proxy.policy.allow_local_binding` (if you need to bind/listen on localhost ports).
|
||||
|
||||
When approvals are enabled, Codex can preflight commands that appear to require the SSH agent and prompt to allow the SSH agent socket before running.
|
||||
|
||||
## Logging and Auditability
|
||||
|
||||
The proxy logs:
|
||||
|
||||
- Allow/deny decisions (host, client, reason).
|
||||
- Policy updates (allowlist/denylist adds/removes).
|
||||
- Mode changes and config reloads.
|
||||
- MITM lifecycle events (CA generated, TLS established).
|
||||
|
||||
## Decision to Make: Preflight Strictness
|
||||
|
||||
Codex performs a preflight check before running some commands. Preflight currently scans CLI args for URLs on known network tools (curl, git, etc.) and shell `-c` snippets.
|
||||
|
||||
We need to decide how strict preflight should be:
|
||||
|
||||
Option A: **Heuristic preflight (current)**
|
||||
- Pros: catches obvious `curl https://...` style commands early.
|
||||
- Cons: misses dynamic URLs inside scripts; can still overprompt on shell snippets.
|
||||
|
||||
Option B: **Strict preflight**
|
||||
- Only preflight when a URL argument is present in the command.
|
||||
- For everything else, rely on the proxy `/blocked` prompt at connect time.
|
||||
- Pros: fewer false positives, clearer user experience.
|
||||
- Cons: fewer early prompts; approvals shift to runtime events.
|
||||
|
||||
Decision: **TBD**. We should choose a configuration flag (`network_proxy.preflight_mode = "heuristic" | "strict"`) and default based on observed UX.
|
||||
|
||||
## Open Items
|
||||
|
||||
- Finalize preflight strictness and expose a config toggle if needed.
|
||||
- Confirm documentation for MITM trust steps and CA injection into sandboxed commands.
|
||||
@@ -1,93 +0,0 @@
|
||||
# Codex Network Proxy Quickstart (Local)
|
||||
|
||||
This is a compact guide to build and validate the Codex network proxy locally.
|
||||
|
||||
## Build
|
||||
|
||||
From the Codex repo:
|
||||
|
||||
```bash
|
||||
cd codex/codex-rs
|
||||
cargo build -p codex-network-proxy
|
||||
```
|
||||
|
||||
For MITM support:
|
||||
|
||||
```bash
|
||||
cargo build -p codex-network-proxy --features mitm
|
||||
```
|
||||
|
||||
## Configure
|
||||
|
||||
Add this to `~/.codex/config.toml`:
|
||||
|
||||
```toml
|
||||
[network_proxy]
|
||||
enabled = true
|
||||
proxy_url = "http://127.0.0.1:3128"
|
||||
admin_url = "http://127.0.0.1:8080"
|
||||
mode = "limited" # or "full"
|
||||
poll_interval_ms = 1000
|
||||
|
||||
[network_proxy.policy]
|
||||
allowed_domains = ["azure.com", "*.openai.com"]
|
||||
denied_domains = ["169.254.*"]
|
||||
# macOS only: allow specific local IPC when proxy-restricted.
|
||||
allow_local_binding = false
|
||||
# Example: allow SSH agent socket for git/ssh.
|
||||
allow_unix_sockets = ["$SSH_AUTH_SOCK"]
|
||||
|
||||
[network_proxy.mitm]
|
||||
enabled = false
|
||||
```
|
||||
|
||||
## Run the proxy
|
||||
|
||||
```bash
|
||||
cd codex/codex-rs
|
||||
cargo run -p codex-network-proxy -- proxy
|
||||
```
|
||||
|
||||
With MITM:
|
||||
|
||||
```bash
|
||||
cargo run -p codex-network-proxy --features mitm -- proxy
|
||||
```
|
||||
|
||||
## Test with curl
|
||||
|
||||
HTTP/HTTPS via proxy:
|
||||
|
||||
```bash
|
||||
export HTTP_PROXY="http://127.0.0.1:3128"
|
||||
export HTTPS_PROXY="http://127.0.0.1:3128"
|
||||
curl -sS https://example.com
|
||||
```
|
||||
|
||||
Limited mode + HTTPS requires MITM. If MITM is on, trust the generated CA:
|
||||
|
||||
```bash
|
||||
security add-trusted-cert -d -r trustRoot \
|
||||
-k ~/Library/Keychains/login.keychain-db \
|
||||
~/.codex/network_proxy/mitm/ca.pem
|
||||
```
|
||||
|
||||
Or pass the CA directly:
|
||||
|
||||
```bash
|
||||
curl --cacert ~/.codex/network_proxy/mitm/ca.pem -sS https://example.com
|
||||
```
|
||||
|
||||
## Admin endpoints
|
||||
|
||||
Reload config after edits:
|
||||
|
||||
```bash
|
||||
curl -fsS -X POST http://127.0.0.1:8080/reload
|
||||
```
|
||||
|
||||
Switch modes:
|
||||
|
||||
```bash
|
||||
curl -fsS -X POST http://127.0.0.1:8080/mode -d '{"mode":"full"}'
|
||||
```
|
||||
Reference in New Issue
Block a user