Files
codex/codex-rs/network-proxy/src/main_tests.rs
T
viyatb-oai 457441bca9 Add constraint-aware standalone network proxy configuration (#57180)
## What changed

- Export `StaticNetworkProxyConfig` to parse and serialize network policy with constraints, and validate them before building proxy state.
- Add `--strict` and `from_slice_strict` for managed callers, requiring explicit `constraints` and rejecting unknown fields at every typed level. Default parsing permits top-level `metadata` and omitted constraints while still rejecting unknown policy fields.
- Match allowed Unix socket paths case-sensitively when validating constraints.
- Bound configuration file reads to the size limit plus one byte.

## Testing

Add coverage for constraint round trips, weakened policy rejection, exact socket path matching, parsing modes, and CLI flag selection. Exercise automatic MITM enablement through both parsers.

GitOrigin-RevId: c45d094624240f23dd4659128e72a4208d5d5f1c
2026-10-26 18:22:40 +00:00

104 lines
3.2 KiB
Rust

use clap::Parser;
use codex_network_proxy::NetworkMitmCaConfig;
use codex_network_proxy::StaticNetworkProxyConfig;
use pretty_assertions::assert_eq;
use serde_json::json;
#[test]
fn enables_mitm_for_limited_mode_and_hooks() {
for (network, expected_mitm, expected_ca) in [
(json!({"enabled": true, "mode": "full"}), false, None),
(
json!({"enabled": true, "mode": "full", "mitm": true}),
true,
None,
),
(json!({"enabled": true, "mode": "limited"}), true, None),
(
json!({
"enabled": true,
"mitm_hooks": [{"host": "api.example.com"}]
}),
true,
None,
),
(
json!({
"enabled": true,
"mode": "limited",
"mitm_ca": {
"certificate_file": "/run/proxy/ca.pem",
"private_key_file": "/run/proxy/key.pem"
}
}),
true,
Some(NetworkMitmCaConfig {
certificate_file: "/run/proxy/ca.pem".to_string(),
private_key_file: "/run/proxy/key.pem".to_string(),
}),
),
] {
let bytes = serde_json::to_vec(&json!({"network": network, "constraints": {}})).unwrap();
for parse in [
StaticNetworkProxyConfig::from_slice,
StaticNetworkProxyConfig::from_slice_strict,
] {
let config = parse(&bytes).unwrap();
assert_eq!(
(config.network.mitm, config.network.mitm_ca),
(expected_mitm, expected_ca.clone())
);
}
}
}
#[test]
fn accepts_dynamic_domain_socket_and_hook_matcher_keys() {
let bytes = serde_json::to_vec(&json!({
"network": {
"enabled": true,
"domains": {"api.example.com": "allow"},
"unix_sockets": {"/tmp/example.sock": "allow"},
"mitm_hooks": [{
"host": "api.example.com",
"match": {
"query": {"scope": ["read"]},
"headers": {"authorization": ["Bearer token"]}
}
}]
},
"constraints": {}
}))
.unwrap();
let config = StaticNetworkProxyConfig::from_slice_strict(&bytes).unwrap();
assert_eq!(
config.network.allowed_domains(),
Some(vec!["api.example.com".to_string()])
);
assert_eq!(
config.network.allow_unix_sockets(),
vec!["/tmp/example.sock".to_string()]
);
}
#[test]
fn strict_flag_controls_config_parsing() {
let base = ["codex-network-proxy", "--config", "policy.json"];
let lenient = super::Args::try_parse_from(base).unwrap();
let strict = super::Args::try_parse_from(base.into_iter().chain(["--strict"])).unwrap();
for bytes in [
br#"{"network":{"enabled":true}}"#.as_slice(),
br#"{"network":{"enabled":true},"metadata":{"future_setting":true},"constraints":{}}"#,
] {
assert!(lenient.parse_config(bytes).is_ok());
assert!(strict.parse_config(bytes).is_err());
}
assert!(
strict
.parse_config(br#"{"network":{"enabled":true},"constraints":{}}"#)
.is_ok()
);
}