Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
f65edf9
Add codex-network-proxy crate
viyatb-oai Dec 21, 2025
eceb76b
use better examples
viyatb-oai Dec 21, 2025
83e8a70
use rama instead of implementing our own proxy stack
viyatb-oai Dec 22, 2025
9b20af6
use a general path
viyatb-oai Dec 23, 2025
127b89b
Merge branch 'main' into pr/network-proxy-crate
viyatb-oai Dec 23, 2025
9d47392
address feedback
viyatb-oai Dec 24, 2025
dc063ff
add unit tests and re-add crate back to cargo
viyatb-oai Dec 24, 2025
fc35891
fix old artifacts from refactor
viyatb-oai Dec 24, 2025
6f4edec
consolidate docs
viyatb-oai Dec 24, 2025
2d79803
add comments
viyatb-oai Dec 24, 2025
10abb38
tighten escape mechanisms
viyatb-oai Dec 24, 2025
9b2a353
explicitly name controls
viyatb-oai Dec 24, 2025
4f3097b
Merge branch 'main' into pr/network-proxy-crate
viyatb-oai Dec 24, 2025
e60d43c
fix cargo shear
viyatb-oai Dec 24, 2025
3e90461
adding back assert_cmd
viyatb-oai Dec 24, 2025
ee102bc
fix test
viyatb-oai Dec 24, 2025
310c79e
Merge branch 'main' into pr/network-proxy-crate
viyatb-oai Jan 12, 2026
d2042b9
Update network proxy rama deps
viyatb-oai Jan 12, 2026
ef2c2d3
Fix CI: cargo-shear, cargo-deny, bazel
viyatb-oai Jan 13, 2026
6ef1dd9
Remove vendored rama-tls-rustls
viyatb-oai Jan 13, 2026
a60515b
Install cmake for Bazel CI
viyatb-oai Jan 13, 2026
826e406
Bazel: disable cmake for aws-lc-sys
viyatb-oai Jan 13, 2026
981c7c3
Bazel: drop aws-lc bindgen in rama-crypto
viyatb-oai Jan 13, 2026
74d748c
Patch rama-crypto to drop bindgen
viyatb-oai Jan 13, 2026
0dd7093
Bazel: skip aws-lc-sys memcmp check
viyatb-oai Jan 13, 2026
1906a23
Fix aws-lc-sys patch hunk header
viyatb-oai Jan 13, 2026
0bbe48c
Revert "Fix aws-lc-sys patch hunk header"
viyatb-oai Jan 14, 2026
e6194d5
Revert "Bazel: skip aws-lc-sys memcmp check"
viyatb-oai Jan 14, 2026
ab28660
Revert "Patch rama-crypto to drop bindgen"
viyatb-oai Jan 14, 2026
b49b838
Revert "Bazel: drop aws-lc bindgen in rama-crypto"
viyatb-oai Jan 14, 2026
258b7ec
Revert "Bazel: disable cmake for aws-lc-sys"
viyatb-oai Jan 14, 2026
a61ab56
Merge origin/main into pr/network-proxy-crate
viyatb-oai Jan 15, 2026
8f6413c
Bazel: disable cmake for aws-lc-sys
viyatb-oai Jan 15, 2026
be94fb6
CI: install libclang for Bazel
viyatb-oai Jan 15, 2026
6c1df8b
Merge origin/main
viyatb-oai Jan 16, 2026
cbb5f48
Remove metadata extraction from proxy
viyatb-oai Jan 17, 2026
bd0ff89
Revert cargo-bin fallback to origin/main
viyatb-oai Jan 17, 2026
302e6ee
Revert cargo-bin Cargo.toml to origin/main
viyatb-oai Jan 17, 2026
8338beb
Make upstream proxy opt-in
viyatb-oai Jan 18, 2026
c656278
Disable aws-lc bindgen in rama-crypto for Bazel
viyatb-oai Jan 19, 2026
d85717d
use individual rama crates and boring-ssl
viyatb-oai Jan 20, 2026
e8cff7e
Install musl g++ for CI
viyatb-oai Jan 20, 2026
7f44c72
Fallback to musl-gcc for musl CXX
viyatb-oai Jan 20, 2026
3d1e12b
Fix musl compiler path quoting
viyatb-oai Jan 20, 2026
5d66111
Install g++ for musl C++ headers
viyatb-oai Jan 20, 2026
57c9714
Use clang++ for musl C++ headers
viyatb-oai Jan 20, 2026
c8b7c00
Force pthreads for musl CMake
viyatb-oai Jan 20, 2026
fe1c1c8
Use clang as musl C compiler
viyatb-oai Jan 20, 2026
8637043
Revert "Disable aws-lc bindgen in rama-crypto for Bazel"
viyatb-oai Jan 20, 2026
741b661
Tighten domain policy matching
viyatb-oai Jan 20, 2026
90c2470
Fix CONNECT proxy handling and enforce managed network constraints
viyatb-oai Jan 20, 2026
f1cc7fb
Clamp proxy binds when unix sockets enabled
viyatb-oai Jan 20, 2026
bcdedf5
update messaging
viyatb-oai Jan 20, 2026
e4c003d
Honor proxy enablement and local binding rules
viyatb-oai Jan 21, 2026
e3d1906
Harden local binding checks for IPv6 literals
viyatb-oai Jan 21, 2026
4995f09
refactor state.rs into manageable modules
viyatb-oai Jan 21, 2026
58562a2
Merge branch 'main' into pr/network-proxy-crate
viyatb-oai Jan 21, 2026
5d7f98a
Split network proxy state into runtime and policy modules
viyatb-oai Jan 21, 2026
872d0ae
Adjust runtime formatting for rustfmt
viyatb-oai Jan 21, 2026
1dd6952
remove cmake and clang setup from bazel.yml
viyatb-oai Jan 22, 2026
4a0c292
ci: dedupe musl install steps
viyatb-oai Jan 22, 2026
fc33c31
ci: call musl setup script via GITHUB_WORKSPACE
viyatb-oai Jan 22, 2026
d54757b
network-proxy: harden policy enforcement
viyatb-oai Jan 22, 2026
4196294
network-proxy: fix clippy test literals
viyatb-oai Jan 22, 2026
6cb436a
network-proxy: focus PR1 on core http + policy
viyatb-oai Jan 22, 2026
5738cf1
network-proxy: add SOCKS5 listener
viyatb-oai Jan 23, 2026
d116357
Merge origin/main into pr-network-proxy-socks
viyatb-oai Jan 24, 2026
9db0fe4
chore: remove unused SOCKS5 builder override
viyatb-oai Jan 24, 2026
6803979
Merge remote-tracking branch 'origin/main' into pr-network-proxy-socks
viyatb-oai Jan 25, 2026
d003072
docs: note full mode default in network proxy
viyatb-oai Jan 25, 2026
3e8470a
Refactor SOCKS5 policy closures into helpers
viyatb-oai Jan 26, 2026
349eec4
Merge remote-tracking branch 'origin/main' into pr-network-proxy-socks
viyatb-oai Jan 27, 2026
d9b0a7f
Merge branch 'main' into pr-network-proxy-socks
viyatb-oai Jan 27, 2026
a5fb56e
Merge branch 'main' into pr-network-proxy-socks
viyatb-oai Jan 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions codex-rs/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions codex-rs/network-proxy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ rama-core = { version = "=0.3.0-alpha.4" }
rama-http = { version = "=0.3.0-alpha.4" }
rama-http-backend = { version = "=0.3.0-alpha.4", features = ["tls"] }
rama-net = { version = "=0.3.0-alpha.4", features = ["http", "tls"] }
rama-socks5 = { version = "=0.3.0-alpha.4" }
rama-tcp = { version = "=0.3.0-alpha.4", features = ["http"] }
rama-tls-boring = { version = "=0.3.0-alpha.4", features = ["http"] }

Expand Down
17 changes: 14 additions & 3 deletions codex-rs/network-proxy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
`codex-network-proxy` is Codex's local network policy enforcement proxy. It runs:

- an HTTP proxy (default `127.0.0.1:3128`)
- an optional SOCKS5 proxy (default `127.0.0.1:8081`, disabled by default)
- 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.
Expand All @@ -20,6 +21,10 @@ Example config:
enabled = true
proxy_url = "http://127.0.0.1:3128"
admin_url = "http://127.0.0.1:8080"
# Optional SOCKS5 listener (disabled by default).
enable_socks5 = false
socks_url = "http://127.0.0.1:8081"
enable_socks5_udp = false
# When `enabled` is false, the proxy no-ops and does not bind listeners.
# When true, respect HTTP(S)_PROXY/ALL_PROXY for upstream requests (HTTP(S) proxies only),
# including CONNECT tunnels in full mode.
Expand All @@ -28,7 +33,7 @@ allow_upstream_proxy = false
# If you want to expose these listeners beyond localhost, you must opt in explicitly.
dangerously_allow_non_loopback_proxy = false
dangerously_allow_non_loopback_admin = false
mode = "limited" # or "full"
mode = "full" # default when unset; use "limited" for read-only mode

[network_proxy.policy]
# Hosts must match the allowlist (unless denied).
Expand Down Expand Up @@ -60,6 +65,12 @@ export HTTP_PROXY="http://127.0.0.1:3128"
export HTTPS_PROXY="http://127.0.0.1:3128"
```

For SOCKS5 traffic (when `enable_socks5 = true`):

```bash
export ALL_PROXY="socks5h://127.0.0.1:8081"
```

### 4) Understand blocks / debugging

When a request is blocked, the proxy responds with `403` and includes:
Expand All @@ -70,8 +81,8 @@ When a request is blocked, the proxy responds with `403` and includes:
- `blocked-by-method-policy`
- `blocked-by-policy`

In "limited" mode, only `GET`, `HEAD`, and `OPTIONS` are allowed for plain HTTP. HTTPS `CONNECT`
remains a transparent tunnel, so limited-mode method enforcement does not apply to HTTPS.
In "limited" mode, only `GET`, `HEAD`, and `OPTIONS` are allowed. HTTPS `CONNECT` and SOCKS5 are
blocked because they would bypass method enforcement.

## Library API

Expand Down
50 changes: 45 additions & 5 deletions codex-rs/network-proxy/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ pub struct NetworkProxySettings {
#[serde(default = "default_admin_url")]
pub admin_url: String,
#[serde(default)]
pub enable_socks5: bool,
#[serde(default = "default_socks_url")]
pub socks_url: String,
#[serde(default)]
pub enable_socks5_udp: bool,
#[serde(default)]
pub allow_upstream_proxy: bool,
#[serde(default)]
pub dangerously_allow_non_loopback_proxy: bool,
Expand All @@ -40,6 +46,9 @@ impl Default for NetworkProxySettings {
enabled: false,
proxy_url: default_proxy_url(),
admin_url: default_admin_url(),
enable_socks5: false,
socks_url: default_socks_url(),
enable_socks5_udp: false,
allow_upstream_proxy: false,
dangerously_allow_non_loopback_proxy: false,
dangerously_allow_non_loopback_admin: false,
Expand Down Expand Up @@ -90,6 +99,10 @@ fn default_admin_url() -> String {
"http://127.0.0.1:8080".to_string()
}

fn default_socks_url() -> String {
"http://127.0.0.1:8081".to_string()
}

/// Clamp non-loopback bind addresses to loopback unless explicitly allowed.
fn clamp_non_loopback(addr: SocketAddr, allow_non_loopback: bool, name: &str) -> SocketAddr {
if addr.ip().is_loopback() {
Expand All @@ -110,21 +123,27 @@ fn clamp_non_loopback(addr: SocketAddr, allow_non_loopback: bool, name: &str) ->

pub(crate) fn clamp_bind_addrs(
http_addr: SocketAddr,
socks_addr: SocketAddr,
admin_addr: SocketAddr,
cfg: &NetworkProxySettings,
) -> (SocketAddr, SocketAddr) {
) -> (SocketAddr, SocketAddr, SocketAddr) {
let http_addr = clamp_non_loopback(
http_addr,
cfg.dangerously_allow_non_loopback_proxy,
"HTTP proxy",
);
let socks_addr = clamp_non_loopback(
socks_addr,
cfg.dangerously_allow_non_loopback_proxy,
"SOCKS5 proxy",
);
let admin_addr = clamp_non_loopback(
admin_addr,
cfg.dangerously_allow_non_loopback_admin,
"admin API",
);
if cfg.policy.allow_unix_sockets.is_empty() {
return (http_addr, admin_addr);
return (http_addr, socks_addr, admin_addr);
}

// `x-unix-socket` is intentionally a local escape hatch. If the proxy (or admin API) is
Expand All @@ -136,19 +155,26 @@ pub(crate) fn clamp_bind_addrs(
"unix socket proxying is enabled; ignoring dangerously_allow_non_loopback_proxy and clamping HTTP proxy to loopback"
);
}
if cfg.dangerously_allow_non_loopback_proxy && !socks_addr.ip().is_loopback() {
warn!(
"unix socket proxying is enabled; ignoring dangerously_allow_non_loopback_proxy and clamping SOCKS5 proxy to loopback"
);
}
if cfg.dangerously_allow_non_loopback_admin && !admin_addr.ip().is_loopback() {
warn!(
"unix socket proxying is enabled; ignoring dangerously_allow_non_loopback_admin and clamping admin API to loopback"
);
}
(
SocketAddr::from(([127, 0, 0, 1], http_addr.port())),
SocketAddr::from(([127, 0, 0, 1], socks_addr.port())),
SocketAddr::from(([127, 0, 0, 1], admin_addr.port())),
)
}

pub struct RuntimeConfig {
pub http_addr: SocketAddr,
pub socks_addr: SocketAddr,
pub admin_addr: SocketAddr,
}

Expand All @@ -159,16 +185,24 @@ pub fn resolve_runtime(cfg: &NetworkProxyConfig) -> Result<RuntimeConfig> {
cfg.network_proxy.proxy_url
)
})?;
let socks_addr = resolve_addr(&cfg.network_proxy.socks_url, 8081).with_context(|| {
format!(
"invalid network_proxy.socks_url: {}",
cfg.network_proxy.socks_url
)
Comment on lines +188 to +192
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Gate SOCKS URL validation on SOCKS5 enablement

resolve_runtime now parses network_proxy.socks_url unconditionally, but NetworkProxyBuilder::build calls resolve_runtime even when enable_socks5 is false. This means an invalid or empty socks_url (e.g., a placeholder in existing configs) will now prevent the entire proxy (HTTP + admin) from starting, despite SOCKS5 being disabled. Consider only resolving/clamping the SOCKS address when enable_socks5 is enabled, or defaulting it without validation in the disabled case.

Useful? React with 👍 / 👎.

})?;
let admin_addr = resolve_addr(&cfg.network_proxy.admin_url, 8080).with_context(|| {
format!(
"invalid network_proxy.admin_url: {}",
cfg.network_proxy.admin_url
)
})?;
let (http_addr, admin_addr) = clamp_bind_addrs(http_addr, admin_addr, &cfg.network_proxy);
let (http_addr, socks_addr, admin_addr) =
clamp_bind_addrs(http_addr, socks_addr, admin_addr, &cfg.network_proxy);

Ok(RuntimeConfig {
http_addr,
socks_addr,
admin_addr,
})
}
Expand Down Expand Up @@ -403,11 +437,14 @@ mod tests {
..Default::default()
};
let http_addr = "0.0.0.0:3128".parse::<SocketAddr>().unwrap();
let socks_addr = "0.0.0.0:8081".parse::<SocketAddr>().unwrap();
let admin_addr = "0.0.0.0:8080".parse::<SocketAddr>().unwrap();

let (http_addr, admin_addr) = clamp_bind_addrs(http_addr, admin_addr, &cfg);
let (http_addr, socks_addr, admin_addr) =
clamp_bind_addrs(http_addr, socks_addr, admin_addr, &cfg);

assert_eq!(http_addr, "0.0.0.0:3128".parse::<SocketAddr>().unwrap());
assert_eq!(socks_addr, "0.0.0.0:8081".parse::<SocketAddr>().unwrap());
assert_eq!(admin_addr, "0.0.0.0:8080".parse::<SocketAddr>().unwrap());
}

Expand All @@ -423,11 +460,14 @@ mod tests {
..Default::default()
};
let http_addr = "0.0.0.0:3128".parse::<SocketAddr>().unwrap();
let socks_addr = "0.0.0.0:8081".parse::<SocketAddr>().unwrap();
let admin_addr = "0.0.0.0:8080".parse::<SocketAddr>().unwrap();

let (http_addr, admin_addr) = clamp_bind_addrs(http_addr, admin_addr, &cfg);
let (http_addr, socks_addr, admin_addr) =
clamp_bind_addrs(http_addr, socks_addr, admin_addr, &cfg);

assert_eq!(http_addr, "127.0.0.1:3128".parse::<SocketAddr>().unwrap());
assert_eq!(socks_addr, "127.0.0.1:8081".parse::<SocketAddr>().unwrap());
assert_eq!(admin_addr, "127.0.0.1:8080".parse::<SocketAddr>().unwrap());
}
}
1 change: 1 addition & 0 deletions codex-rs/network-proxy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod proxy;
mod reasons;
mod responses;
mod runtime;
mod socks5;
mod state;
mod upstream;

Expand Down
Loading
Loading