mirror of
https://github.com/openai/codex.git
synced 2026-04-29 08:56:38 +00:00
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.
This commit is contained in:
@@ -161,15 +161,15 @@ impl NetworkProxyState {
|
||||
self.reload_if_needed().await?;
|
||||
let guard = self.state.read().await;
|
||||
Ok((
|
||||
guard.config.network_proxy.policy.allowed_domains.clone(),
|
||||
guard.config.network_proxy.policy.denied_domains.clone(),
|
||||
guard.config.network.allowed_domains.clone(),
|
||||
guard.config.network.denied_domains.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn enabled(&self) -> Result<bool> {
|
||||
self.reload_if_needed().await?;
|
||||
let guard = self.state.read().await;
|
||||
Ok(guard.config.network_proxy.enabled)
|
||||
Ok(guard.config.network.enabled)
|
||||
}
|
||||
|
||||
pub async fn force_reload(&self) -> Result<()> {
|
||||
@@ -209,9 +209,9 @@ impl NetworkProxyState {
|
||||
(
|
||||
guard.deny_set.clone(),
|
||||
guard.allow_set.clone(),
|
||||
guard.config.network_proxy.policy.allow_local_binding,
|
||||
guard.config.network_proxy.policy.allowed_domains.is_empty(),
|
||||
guard.config.network_proxy.policy.allowed_domains.clone(),
|
||||
guard.config.network.allow_local_binding,
|
||||
guard.config.network.allowed_domains.is_empty(),
|
||||
guard.config.network.allowed_domains.clone(),
|
||||
)
|
||||
};
|
||||
|
||||
@@ -305,7 +305,7 @@ impl NetworkProxyState {
|
||||
Err(_) => return Ok(false),
|
||||
};
|
||||
let requested_canonical = std::fs::canonicalize(requested_abs.as_path()).ok();
|
||||
for allowed in &guard.config.network_proxy.policy.allow_unix_sockets {
|
||||
for allowed in &guard.config.network.allow_unix_sockets {
|
||||
if allowed == path {
|
||||
return Ok(true);
|
||||
}
|
||||
@@ -327,19 +327,19 @@ impl NetworkProxyState {
|
||||
pub async fn method_allowed(&self, method: &str) -> Result<bool> {
|
||||
self.reload_if_needed().await?;
|
||||
let guard = self.state.read().await;
|
||||
Ok(guard.config.network_proxy.mode.allows_method(method))
|
||||
Ok(guard.config.network.mode.allows_method(method))
|
||||
}
|
||||
|
||||
pub async fn allow_upstream_proxy(&self) -> Result<bool> {
|
||||
self.reload_if_needed().await?;
|
||||
let guard = self.state.read().await;
|
||||
Ok(guard.config.network_proxy.allow_upstream_proxy)
|
||||
Ok(guard.config.network.allow_upstream_proxy)
|
||||
}
|
||||
|
||||
pub async fn network_mode(&self) -> Result<NetworkMode> {
|
||||
self.reload_if_needed().await?;
|
||||
let guard = self.state.read().await;
|
||||
Ok(guard.config.network_proxy.mode)
|
||||
Ok(guard.config.network.mode)
|
||||
}
|
||||
|
||||
pub async fn set_network_mode(&self, mode: NetworkMode) -> Result<()> {
|
||||
@@ -348,19 +348,19 @@ impl NetworkProxyState {
|
||||
let (candidate, constraints) = {
|
||||
let guard = self.state.read().await;
|
||||
let mut candidate = guard.config.clone();
|
||||
candidate.network_proxy.mode = mode;
|
||||
candidate.network.mode = mode;
|
||||
(candidate, guard.constraints.clone())
|
||||
};
|
||||
|
||||
validate_policy_against_constraints(&candidate, &constraints)
|
||||
.context("network_proxy.mode constrained by managed config")?;
|
||||
.context("network.mode constrained by managed config")?;
|
||||
|
||||
let mut guard = self.state.write().await;
|
||||
if guard.constraints != constraints {
|
||||
drop(guard);
|
||||
continue;
|
||||
}
|
||||
guard.config.network_proxy.mode = mode;
|
||||
guard.config.network.mode = mode;
|
||||
info!("updated network mode to {mode:?}");
|
||||
return Ok(());
|
||||
}
|
||||
@@ -417,13 +417,13 @@ async fn host_resolves_to_non_public_ip(host: &str, port: u16) -> bool {
|
||||
fn log_policy_changes(previous: &NetworkProxyConfig, next: &NetworkProxyConfig) {
|
||||
log_domain_list_changes(
|
||||
"allowlist",
|
||||
&previous.network_proxy.policy.allowed_domains,
|
||||
&next.network_proxy.policy.allowed_domains,
|
||||
&previous.network.allowed_domains,
|
||||
&next.network.allowed_domains,
|
||||
);
|
||||
log_domain_list_changes(
|
||||
"denylist",
|
||||
&previous.network_proxy.policy.denied_domains,
|
||||
&next.network_proxy.policy.denied_domains,
|
||||
&previous.network.denied_domains,
|
||||
&next.network.denied_domains,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -483,21 +483,14 @@ fn unix_timestamp() -> i64 {
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn network_proxy_state_for_policy(
|
||||
policy: crate::config::NetworkPolicy,
|
||||
mut network: crate::config::NetworkProxySettings,
|
||||
) -> NetworkProxyState {
|
||||
let config = NetworkProxyConfig {
|
||||
network_proxy: crate::config::NetworkProxySettings {
|
||||
enabled: true,
|
||||
mode: NetworkMode::Full,
|
||||
policy,
|
||||
..crate::config::NetworkProxySettings::default()
|
||||
},
|
||||
};
|
||||
network.enabled = true;
|
||||
network.mode = NetworkMode::Full;
|
||||
let config = NetworkProxyConfig { network };
|
||||
|
||||
let allow_set =
|
||||
crate::policy::compile_globset(&config.network_proxy.policy.allowed_domains).unwrap();
|
||||
let deny_set =
|
||||
crate::policy::compile_globset(&config.network_proxy.policy.denied_domains).unwrap();
|
||||
let allow_set = crate::policy::compile_globset(&config.network.allowed_domains).unwrap();
|
||||
let deny_set = crate::policy::compile_globset(&config.network.denied_domains).unwrap();
|
||||
|
||||
let state = ConfigState {
|
||||
config,
|
||||
@@ -518,7 +511,6 @@ pub(crate) fn network_proxy_state_for_policy(
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::config::NetworkPolicy;
|
||||
use crate::config::NetworkProxyConfig;
|
||||
use crate::config::NetworkProxySettings;
|
||||
use crate::policy::compile_globset;
|
||||
@@ -528,10 +520,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn host_blocked_denied_wins_over_allowed() {
|
||||
let state = network_proxy_state_for_policy(NetworkPolicy {
|
||||
let state = network_proxy_state_for_policy(NetworkProxySettings {
|
||||
allowed_domains: vec!["example.com".to_string()],
|
||||
denied_domains: vec!["example.com".to_string()],
|
||||
..NetworkPolicy::default()
|
||||
..NetworkProxySettings::default()
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
@@ -542,9 +534,9 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn host_blocked_requires_allowlist_match() {
|
||||
let state = network_proxy_state_for_policy(NetworkPolicy {
|
||||
let state = network_proxy_state_for_policy(NetworkProxySettings {
|
||||
allowed_domains: vec!["example.com".to_string()],
|
||||
..NetworkPolicy::default()
|
||||
..NetworkProxySettings::default()
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
@@ -561,9 +553,9 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn host_blocked_subdomain_wildcards_exclude_apex() {
|
||||
let state = network_proxy_state_for_policy(NetworkPolicy {
|
||||
let state = network_proxy_state_for_policy(NetworkProxySettings {
|
||||
allowed_domains: vec!["*.openai.com".to_string()],
|
||||
..NetworkPolicy::default()
|
||||
..NetworkProxySettings::default()
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
@@ -578,10 +570,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn host_blocked_rejects_loopback_when_local_binding_disabled() {
|
||||
let state = network_proxy_state_for_policy(NetworkPolicy {
|
||||
let state = network_proxy_state_for_policy(NetworkProxySettings {
|
||||
allowed_domains: vec!["example.com".to_string()],
|
||||
allow_local_binding: false,
|
||||
..NetworkPolicy::default()
|
||||
..NetworkProxySettings::default()
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
@@ -596,10 +588,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn host_blocked_rejects_loopback_when_allowlist_is_wildcard() {
|
||||
let state = network_proxy_state_for_policy(NetworkPolicy {
|
||||
let state = network_proxy_state_for_policy(NetworkProxySettings {
|
||||
allowed_domains: vec!["*".to_string()],
|
||||
allow_local_binding: false,
|
||||
..NetworkPolicy::default()
|
||||
..NetworkProxySettings::default()
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
@@ -610,10 +602,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn host_blocked_rejects_private_ip_literal_when_allowlist_is_wildcard() {
|
||||
let state = network_proxy_state_for_policy(NetworkPolicy {
|
||||
let state = network_proxy_state_for_policy(NetworkProxySettings {
|
||||
allowed_domains: vec!["*".to_string()],
|
||||
allow_local_binding: false,
|
||||
..NetworkPolicy::default()
|
||||
..NetworkProxySettings::default()
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
@@ -624,10 +616,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn host_blocked_allows_loopback_when_explicitly_allowlisted_and_local_binding_disabled() {
|
||||
let state = network_proxy_state_for_policy(NetworkPolicy {
|
||||
let state = network_proxy_state_for_policy(NetworkProxySettings {
|
||||
allowed_domains: vec!["localhost".to_string()],
|
||||
allow_local_binding: false,
|
||||
..NetworkPolicy::default()
|
||||
..NetworkProxySettings::default()
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
@@ -638,10 +630,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn host_blocked_allows_private_ip_literal_when_explicitly_allowlisted() {
|
||||
let state = network_proxy_state_for_policy(NetworkPolicy {
|
||||
let state = network_proxy_state_for_policy(NetworkProxySettings {
|
||||
allowed_domains: vec!["10.0.0.1".to_string()],
|
||||
allow_local_binding: false,
|
||||
..NetworkPolicy::default()
|
||||
..NetworkProxySettings::default()
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
@@ -652,10 +644,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn host_blocked_rejects_scoped_ipv6_literal_when_not_allowlisted() {
|
||||
let state = network_proxy_state_for_policy(NetworkPolicy {
|
||||
let state = network_proxy_state_for_policy(NetworkProxySettings {
|
||||
allowed_domains: vec!["example.com".to_string()],
|
||||
allow_local_binding: false,
|
||||
..NetworkPolicy::default()
|
||||
..NetworkProxySettings::default()
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
@@ -666,10 +658,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn host_blocked_allows_scoped_ipv6_literal_when_explicitly_allowlisted() {
|
||||
let state = network_proxy_state_for_policy(NetworkPolicy {
|
||||
let state = network_proxy_state_for_policy(NetworkProxySettings {
|
||||
allowed_domains: vec!["fe80::1%lo0".to_string()],
|
||||
allow_local_binding: false,
|
||||
..NetworkPolicy::default()
|
||||
..NetworkProxySettings::default()
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
@@ -680,10 +672,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn host_blocked_rejects_private_ip_literals_when_local_binding_disabled() {
|
||||
let state = network_proxy_state_for_policy(NetworkPolicy {
|
||||
let state = network_proxy_state_for_policy(NetworkProxySettings {
|
||||
allowed_domains: vec!["example.com".to_string()],
|
||||
allow_local_binding: false,
|
||||
..NetworkPolicy::default()
|
||||
..NetworkProxySettings::default()
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
@@ -694,10 +686,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn host_blocked_rejects_loopback_when_allowlist_empty() {
|
||||
let state = network_proxy_state_for_policy(NetworkPolicy {
|
||||
let state = network_proxy_state_for_policy(NetworkProxySettings {
|
||||
allowed_domains: vec![],
|
||||
allow_local_binding: false,
|
||||
..NetworkPolicy::default()
|
||||
..NetworkProxySettings::default()
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
@@ -714,12 +706,9 @@ mod tests {
|
||||
};
|
||||
|
||||
let config = NetworkProxyConfig {
|
||||
network_proxy: NetworkProxySettings {
|
||||
network: NetworkProxySettings {
|
||||
enabled: true,
|
||||
policy: NetworkPolicy {
|
||||
allowed_domains: vec!["example.com".to_string(), "evil.com".to_string()],
|
||||
..NetworkPolicy::default()
|
||||
},
|
||||
allowed_domains: vec!["example.com".to_string(), "evil.com".to_string()],
|
||||
..NetworkProxySettings::default()
|
||||
},
|
||||
};
|
||||
@@ -735,7 +724,7 @@ mod tests {
|
||||
};
|
||||
|
||||
let config = NetworkProxyConfig {
|
||||
network_proxy: NetworkProxySettings {
|
||||
network: NetworkProxySettings {
|
||||
enabled: true,
|
||||
mode: NetworkMode::Full,
|
||||
..NetworkProxySettings::default()
|
||||
@@ -753,12 +742,9 @@ mod tests {
|
||||
};
|
||||
|
||||
let config = NetworkProxyConfig {
|
||||
network_proxy: NetworkProxySettings {
|
||||
network: NetworkProxySettings {
|
||||
enabled: true,
|
||||
policy: NetworkPolicy {
|
||||
allowed_domains: vec!["api.example.com".to_string()],
|
||||
..NetworkPolicy::default()
|
||||
},
|
||||
allowed_domains: vec!["api.example.com".to_string()],
|
||||
..NetworkProxySettings::default()
|
||||
},
|
||||
};
|
||||
@@ -774,12 +760,9 @@ mod tests {
|
||||
};
|
||||
|
||||
let config = NetworkProxyConfig {
|
||||
network_proxy: NetworkProxySettings {
|
||||
network: NetworkProxySettings {
|
||||
enabled: true,
|
||||
policy: NetworkPolicy {
|
||||
allowed_domains: vec!["**.example.com".to_string()],
|
||||
..NetworkPolicy::default()
|
||||
},
|
||||
allowed_domains: vec!["**.example.com".to_string()],
|
||||
..NetworkProxySettings::default()
|
||||
},
|
||||
};
|
||||
@@ -795,12 +778,9 @@ mod tests {
|
||||
};
|
||||
|
||||
let config = NetworkProxyConfig {
|
||||
network_proxy: NetworkProxySettings {
|
||||
network: NetworkProxySettings {
|
||||
enabled: true,
|
||||
policy: NetworkPolicy {
|
||||
denied_domains: vec![],
|
||||
..NetworkPolicy::default()
|
||||
},
|
||||
denied_domains: vec![],
|
||||
..NetworkProxySettings::default()
|
||||
},
|
||||
};
|
||||
@@ -816,7 +796,7 @@ mod tests {
|
||||
};
|
||||
|
||||
let config = NetworkProxyConfig {
|
||||
network_proxy: NetworkProxySettings {
|
||||
network: NetworkProxySettings {
|
||||
enabled: true,
|
||||
..NetworkProxySettings::default()
|
||||
},
|
||||
@@ -833,12 +813,9 @@ mod tests {
|
||||
};
|
||||
|
||||
let config = NetworkProxyConfig {
|
||||
network_proxy: NetworkProxySettings {
|
||||
network: NetworkProxySettings {
|
||||
enabled: true,
|
||||
policy: NetworkPolicy {
|
||||
allow_local_binding: true,
|
||||
..NetworkPolicy::default()
|
||||
},
|
||||
allow_local_binding: true,
|
||||
..NetworkProxySettings::default()
|
||||
},
|
||||
};
|
||||
@@ -854,7 +831,7 @@ mod tests {
|
||||
};
|
||||
|
||||
let config = NetworkProxyConfig {
|
||||
network_proxy: NetworkProxySettings {
|
||||
network: NetworkProxySettings {
|
||||
enabled: true,
|
||||
dangerously_allow_non_loopback_admin: true,
|
||||
..NetworkProxySettings::default()
|
||||
@@ -872,7 +849,7 @@ mod tests {
|
||||
};
|
||||
|
||||
let config = NetworkProxyConfig {
|
||||
network_proxy: NetworkProxySettings {
|
||||
network: NetworkProxySettings {
|
||||
enabled: true,
|
||||
dangerously_allow_non_loopback_admin: true,
|
||||
..NetworkProxySettings::default()
|
||||
@@ -935,10 +912,10 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn unix_socket_allowlist_is_respected_on_macos() {
|
||||
let socket_path = "/tmp/example.sock".to_string();
|
||||
let state = network_proxy_state_for_policy(NetworkPolicy {
|
||||
let state = network_proxy_state_for_policy(NetworkProxySettings {
|
||||
allowed_domains: vec!["example.com".to_string()],
|
||||
allow_unix_sockets: vec![socket_path.clone()],
|
||||
..NetworkPolicy::default()
|
||||
..NetworkProxySettings::default()
|
||||
});
|
||||
|
||||
assert!(state.is_unix_socket_allowed(&socket_path).await.unwrap());
|
||||
@@ -970,10 +947,10 @@ mod tests {
|
||||
let real_s = real.to_str().unwrap().to_string();
|
||||
let link_s = link.to_str().unwrap().to_string();
|
||||
|
||||
let state = network_proxy_state_for_policy(NetworkPolicy {
|
||||
let state = network_proxy_state_for_policy(NetworkProxySettings {
|
||||
allowed_domains: vec!["example.com".to_string()],
|
||||
allow_unix_sockets: vec![real_s],
|
||||
..NetworkPolicy::default()
|
||||
..NetworkProxySettings::default()
|
||||
});
|
||||
|
||||
assert!(state.is_unix_socket_allowed(&link_s).await.unwrap());
|
||||
@@ -983,10 +960,10 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn unix_socket_allowlist_is_rejected_on_non_macos() {
|
||||
let socket_path = "/tmp/example.sock".to_string();
|
||||
let state = network_proxy_state_for_policy(NetworkPolicy {
|
||||
let state = network_proxy_state_for_policy(NetworkProxySettings {
|
||||
allowed_domains: vec!["example.com".to_string()],
|
||||
allow_unix_sockets: vec![socket_path.clone()],
|
||||
..NetworkPolicy::default()
|
||||
..NetworkProxySettings::default()
|
||||
});
|
||||
|
||||
assert!(!state.is_unix_socket_allowed(&socket_path).await.unwrap());
|
||||
|
||||
Reference in New Issue
Block a user