fix(core): enforce managed plaintext injection policy

Co-authored-by: Codex noreply@openai.com
This commit is contained in:
viyatb-oai
2026-06-25 09:50:54 -07:00
committed by Winston Howes
parent 336612bc25
commit c03bca9a33
3 changed files with 78 additions and 0 deletions

View File

@@ -178,6 +178,13 @@ fn apply_network_constraints(network: NetworkToml, constraints: &mut NetworkProx
if let Some(allow_local_binding) = network.allow_local_binding {
constraints.allow_local_binding = Some(allow_local_binding);
}
if let Some(dangerously_allow_plaintext_credential_injection) = network
.mitm
.and_then(|mitm| mitm.dangerously_allow_plaintext_credential_injection)
{
constraints.dangerously_allow_plaintext_credential_injection =
Some(dangerously_allow_plaintext_credential_injection);
}
}
#[derive(Debug, Clone, Default, Deserialize)]

View File

@@ -214,6 +214,55 @@ dangerously_allow_plaintext_credential_injection = true
);
}
#[test]
fn managed_config_can_disable_plaintext_credential_injection() {
let managed_layer = ConfigLayerEntry::new(
ConfigLayerSource::System {
file: AbsolutePathBuf::try_from(std::path::PathBuf::from("/tmp/system.toml"))
.expect("system config path should be absolute"),
},
toml::toml! {
default_permissions = "workspace"
[permissions.workspace.network.mitm]
dangerously_allow_plaintext_credential_injection = false
}
.into(),
);
let user_layer = ConfigLayerEntry::new(
ConfigLayerSource::User {
file: AbsolutePathBuf::try_from(std::path::PathBuf::from("/tmp/config.toml"))
.expect("user config path should be absolute"),
profile: None,
},
toml::toml! {
[permissions.workspace.network.mitm]
dangerously_allow_plaintext_credential_injection = true
}
.into(),
);
let layers = ConfigLayerStack::new(
vec![managed_layer, user_layer],
ConfigRequirements::default(),
ConfigRequirementsToml::default(),
)
.expect("layer stack should be valid");
let config = config_from_layers(&layers, &Policy::empty())
.expect("merged network proxy config should load");
assert!(
config
.network
.dangerously_allow_plaintext_credential_injection
);
let err = enforce_trusted_constraints(&layers, &config)
.expect_err("managed config should disable plaintext credential injection");
assert_eq!(
format!("{err:#}"),
"network proxy constraints: invalid value for network.dangerously_allow_plaintext_credential_injection: true (allowed false (disabled by managed config))"
);
}
#[test]
fn execpolicy_network_rules_overlay_network_lists() {
let mut config = NetworkProxyConfig::default();

View File

@@ -30,6 +30,7 @@ pub struct NetworkProxyConstraints {
pub allow_upstream_proxy: Option<bool>,
pub dangerously_allow_non_loopback_proxy: Option<bool>,
pub dangerously_allow_all_unix_sockets: Option<bool>,
pub dangerously_allow_plaintext_credential_injection: Option<bool>,
pub allowed_domains: Option<Vec<String>>,
pub allowlist_expansion_enabled: Option<bool>,
pub denied_domains: Option<Vec<String>>,
@@ -198,6 +199,27 @@ pub fn validate_policy_against_constraints(
},
)?;
if let Some(allow_plaintext_credential_injection) =
constraints.dangerously_allow_plaintext_credential_injection
{
validate(
config
.network
.dangerously_allow_plaintext_credential_injection,
move |candidate| {
if *candidate && !allow_plaintext_credential_injection {
Err(invalid_value(
"network.dangerously_allow_plaintext_credential_injection",
"true",
"false (disabled by managed config)",
))
} else {
Ok(())
}
},
)?;
}
let allow_all_unix_sockets = constraints
.dangerously_allow_all_unix_sockets
.unwrap_or(constraints.allow_unix_sockets.is_none());