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:
viyatb-oai
2026-02-06 21:22:44 -08:00
committed by GitHub
parent 5d2702f6b8
commit 8cd46ebad6
7 changed files with 190 additions and 241 deletions

View File

@@ -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());