From bf72be59278e23002a352a53207182985cabb9d0 Mon Sep 17 00:00:00 2001 From: viyatb-oai Date: Thu, 28 May 2026 16:53:26 -0700 Subject: [PATCH] fix(config): use deny for Unix socket permissions (#24970) ## Why Unix socket permissions still accepted and displayed `"none"` while file permissions use the clearer `"deny"` spelling. This keeps network Unix socket policy vocabulary consistent with filesystem policy vocabulary. ## What changed - Replace the Unix socket permission variant and serialized spelling from `none` to `deny` across config, feature configuration, and network proxy types. - Update app-server v2 serialization, TUI debug output, focused tests, and generated schemas to expose `"deny"`. - Add coverage for denied Unix socket entries in managed requirements and profile overlay behavior. ## Security This is a vocabulary change for explicit Unix socket rejection, not a network access expansion. Denied entries continue to be omitted from the effective allowlist. ## Validation - `just fmt` - `just write-config-schema` - `just write-app-server-schema` - `just test -p codex-config -p codex-core -p codex-app-server-protocol -p codex-tui -E 'test(network_requirements_are_preserved_as_constraints_with_source) | test(network_permission_containers_project_allowed_and_denied_entries) | test(network_toml_overlays_unix_socket_permissions_by_path) | test(permissions_profiles_resolve_extends_parent_first_with_child_overrides) | test(network_requirements_serializes_canonical_and_legacy_fields) | test(debug_config_output_formats_unix_socket_permissions)'`\n- Automatic `bench-smoke` follow-up from `just test`\n- `cargo clippy -p codex-config -p codex-core -p codex-features -p codex-network-proxy -p codex-app-server-protocol -p codex-app-server -p codex-tui --all-targets -- -D warnings` --- .../codex_app_server_protocol.schemas.json | 2 +- .../codex_app_server_protocol.v2.schemas.json | 2 +- .../v2/ConfigRequirementsReadResponse.json | 2 +- .../v2/NetworkUnixSocketPermission.ts | 2 +- .../src/protocol/v2/config.rs | 2 +- .../src/protocol/v2/tests.rs | 4 ++-- .../request_processors/config_processor.rs | 2 +- codex-rs/config/src/config_requirements.rs | 21 ++++++++++++------- codex-rs/config/src/permissions_toml.rs | 6 +++--- codex-rs/core/config.schema.json | 4 ++-- codex-rs/core/src/config/permissions.rs | 4 ++-- codex-rs/core/src/config/permissions_tests.rs | 8 ++++--- codex-rs/features/src/feature_configs.rs | 2 +- codex-rs/network-proxy/src/config.rs | 2 +- codex-rs/tui/src/debug_config.rs | 6 +++--- 15 files changed, 39 insertions(+), 30 deletions(-) diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json index 80c2053a5..b78690a4f 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json @@ -11845,7 +11845,7 @@ "NetworkUnixSocketPermission": { "enum": [ "allow", - "none" + "deny" ], "type": "string" }, diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json index 8fc70ab73..b74ed83f8 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json @@ -8374,7 +8374,7 @@ "NetworkUnixSocketPermission": { "enum": [ "allow", - "none" + "deny" ], "type": "string" }, diff --git a/codex-rs/app-server-protocol/schema/json/v2/ConfigRequirementsReadResponse.json b/codex-rs/app-server-protocol/schema/json/v2/ConfigRequirementsReadResponse.json index 63a209cc7..a82421fb0 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ConfigRequirementsReadResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ConfigRequirementsReadResponse.json @@ -460,7 +460,7 @@ "NetworkUnixSocketPermission": { "enum": [ "allow", - "none" + "deny" ], "type": "string" }, diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/NetworkUnixSocketPermission.ts b/codex-rs/app-server-protocol/schema/typescript/v2/NetworkUnixSocketPermission.ts index 466c6e5f8..c5474cbb6 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/NetworkUnixSocketPermission.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/NetworkUnixSocketPermission.ts @@ -2,4 +2,4 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type NetworkUnixSocketPermission = "allow" | "none"; +export type NetworkUnixSocketPermission = "allow" | "deny"; diff --git a/codex-rs/app-server-protocol/src/protocol/v2/config.rs b/codex-rs/app-server-protocol/src/protocol/v2/config.rs index fffe21381..e30b3012e 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2/config.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2/config.rs @@ -490,7 +490,7 @@ pub enum NetworkDomainPermission { #[ts(export_to = "v2/")] pub enum NetworkUnixSocketPermission { Allow, - None, + Deny, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)] diff --git a/codex-rs/app-server-protocol/src/protocol/v2/tests.rs b/codex-rs/app-server-protocol/src/protocol/v2/tests.rs index 4fcb9a2c9..7d57f6e09 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2/tests.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2/tests.rs @@ -2278,7 +2278,7 @@ fn network_requirements_serializes_canonical_and_legacy_fields() { ), ( "/tmp/ignored.sock".to_string(), - NetworkUnixSocketPermission::None, + NetworkUnixSocketPermission::Deny, ), ])), allow_unix_sockets: Some(vec!["/tmp/proxy.sock".to_string()]), @@ -2302,7 +2302,7 @@ fn network_requirements_serializes_canonical_and_legacy_fields() { "allowedDomains": ["api.openai.com"], "deniedDomains": ["blocked.example.com"], "unixSockets": { - "/tmp/ignored.sock": "none", + "/tmp/ignored.sock": "deny", "/tmp/proxy.sock": "allow" }, "allowUnixSockets": ["/tmp/proxy.sock"], diff --git a/codex-rs/app-server/src/request_processors/config_processor.rs b/codex-rs/app-server/src/request_processors/config_processor.rs index 39dbd17fe..5ba6d02ec 100644 --- a/codex-rs/app-server/src/request_processors/config_processor.rs +++ b/codex-rs/app-server/src/request_processors/config_processor.rs @@ -611,7 +611,7 @@ fn map_network_unix_socket_permission_to_api( ) -> NetworkUnixSocketPermission { match permission { codex_config::NetworkUnixSocketPermissionToml::Allow => NetworkUnixSocketPermission::Allow, - codex_config::NetworkUnixSocketPermissionToml::None => NetworkUnixSocketPermission::None, + codex_config::NetworkUnixSocketPermissionToml::Deny => NetworkUnixSocketPermission::Deny, } } diff --git a/codex-rs/config/src/config_requirements.rs b/codex-rs/config/src/config_requirements.rs index 93d16d3cc..9be87746e 100644 --- a/codex-rs/config/src/config_requirements.rs +++ b/codex-rs/config/src/config_requirements.rs @@ -245,14 +245,14 @@ impl NetworkUnixSocketPermissionsToml { #[serde(rename_all = "lowercase")] pub enum NetworkUnixSocketPermissionToml { Allow, - None, + Deny, } impl std::fmt::Display for NetworkUnixSocketPermissionToml { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let permission = match self { Self::Allow => "allow", - Self::None => "none", + Self::Deny => "deny", }; f.write_str(permission) } @@ -2868,6 +2868,7 @@ command = "python3 /enterprise/hooks/pre.py" [experimental_network.unix_sockets] "/tmp/example.sock" = "allow" + "/tmp/blocked.sock" = "deny" "#; let source = RequirementSource::CloudRequirements; @@ -2912,10 +2913,16 @@ command = "python3 /enterprise/hooks/pre.py" assert_eq!( sourced_network.value.unix_sockets.as_ref(), Some(&NetworkUnixSocketPermissionsToml { - entries: BTreeMap::from([( - "/tmp/example.sock".to_string(), - NetworkUnixSocketPermissionToml::Allow, - )]), + entries: BTreeMap::from([ + ( + "/tmp/blocked.sock".to_string(), + NetworkUnixSocketPermissionToml::Deny, + ), + ( + "/tmp/example.sock".to_string(), + NetworkUnixSocketPermissionToml::Allow, + ), + ]), }) ); assert_eq!(sourced_network.value.allow_local_binding, Some(false)); @@ -3053,7 +3060,7 @@ command = "python3 /enterprise/hooks/pre.py" ), ( "/tmp/ignored.sock".to_string(), - NetworkUnixSocketPermissionToml::None, + NetworkUnixSocketPermissionToml::Deny, ), ]), }; diff --git a/codex-rs/config/src/permissions_toml.rs b/codex-rs/config/src/permissions_toml.rs index a4ef5d266..0baec2a5c 100644 --- a/codex-rs/config/src/permissions_toml.rs +++ b/codex-rs/config/src/permissions_toml.rs @@ -327,14 +327,14 @@ impl NetworkUnixSocketPermissionsToml { #[serde(rename_all = "lowercase")] pub enum NetworkUnixSocketPermissionToml { Allow, - None, + Deny, } impl std::fmt::Display for NetworkUnixSocketPermissionToml { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let permission = match self { Self::Allow => "allow", - Self::None => "none", + Self::Deny => "deny", }; f.write_str(permission) } @@ -547,7 +547,7 @@ impl NetworkToml { NetworkUnixSocketPermissionToml::Allow => { ProxyNetworkUnixSocketPermission::Allow } - NetworkUnixSocketPermissionToml::None => ProxyNetworkUnixSocketPermission::None, + NetworkUnixSocketPermissionToml::Deny => ProxyNetworkUnixSocketPermission::Deny, }; proxy_unix_sockets.entries.insert(path.clone(), permission); } diff --git a/codex-rs/core/config.schema.json b/codex-rs/core/config.schema.json index 1dd6bda8a..b7bdff813 100644 --- a/codex-rs/core/config.schema.json +++ b/codex-rs/core/config.schema.json @@ -1773,7 +1773,7 @@ "NetworkProxyUnixSocketPermissionToml": { "enum": [ "allow", - "none" + "deny" ], "type": "string" }, @@ -1825,7 +1825,7 @@ "NetworkUnixSocketPermissionToml": { "enum": [ "allow", - "none" + "deny" ], "type": "string" }, diff --git a/codex-rs/core/src/config/permissions.rs b/codex-rs/core/src/config/permissions.rs index 3aaa7d66f..a8546858f 100644 --- a/codex-rs/core/src/config/permissions.rs +++ b/codex-rs/core/src/config/permissions.rs @@ -176,8 +176,8 @@ pub(crate) fn apply_network_proxy_feature_config( NetworkProxyUnixSocketPermissionToml::Allow => { NetworkUnixSocketPermissionToml::Allow } - NetworkProxyUnixSocketPermissionToml::None => { - NetworkUnixSocketPermissionToml::None + NetworkProxyUnixSocketPermissionToml::Deny => { + NetworkUnixSocketPermissionToml::Deny } }; (path.clone(), permission) diff --git a/codex-rs/core/src/config/permissions_tests.rs b/codex-rs/core/src/config/permissions_tests.rs index 8f9d6732e..41f4179ba 100644 --- a/codex-rs/core/src/config/permissions_tests.rs +++ b/codex-rs/core/src/config/permissions_tests.rs @@ -149,7 +149,7 @@ fn network_permission_containers_project_allowed_and_denied_entries() { ), ( "/tmp/ignored.sock".to_string(), - NetworkUnixSocketPermissionToml::None, + NetworkUnixSocketPermissionToml::Deny, ), ]), }; @@ -211,7 +211,7 @@ fn network_toml_overlays_unix_socket_permissions_by_path() { ), ( "/tmp/override.sock".to_string(), - NetworkUnixSocketPermissionToml::None, + NetworkUnixSocketPermissionToml::Deny, ), ]), }), @@ -233,7 +233,7 @@ fn network_toml_overlays_unix_socket_permissions_by_path() { ), ( "/tmp/override.sock".to_string(), - ProxyNetworkUnixSocketPermission::None, + ProxyNetworkUnixSocketPermission::Deny, ), ]), }) @@ -265,6 +265,7 @@ enabled = true [base.network.unix_sockets] "/tmp/base.sock" = "allow" +"/tmp/blocked.sock" = "deny" [child] extends = "base" @@ -319,6 +320,7 @@ allow_local_binding = true [network.unix_sockets] "/tmp/base.sock" = "allow" +"/tmp/blocked.sock" = "deny" "/tmp/child.sock" = "allow" "#, ) diff --git a/codex-rs/features/src/feature_configs.rs b/codex-rs/features/src/feature_configs.rs index bfd14237d..6106431d7 100644 --- a/codex-rs/features/src/feature_configs.rs +++ b/codex-rs/features/src/feature_configs.rs @@ -124,5 +124,5 @@ pub enum NetworkProxyDomainPermissionToml { #[serde(rename_all = "lowercase")] pub enum NetworkProxyUnixSocketPermissionToml { Allow, - None, + Deny, } diff --git a/codex-rs/network-proxy/src/config.rs b/codex-rs/network-proxy/src/config.rs index 398ec321a..0b0a8233f 100644 --- a/codex-rs/network-proxy/src/config.rs +++ b/codex-rs/network-proxy/src/config.rs @@ -107,7 +107,7 @@ impl NetworkDomainPermissions { #[serde(rename_all = "lowercase")] pub enum NetworkUnixSocketPermission { Allow, - None, + Deny, } #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)] diff --git a/codex-rs/tui/src/debug_config.rs b/codex-rs/tui/src/debug_config.rs index 4c40e0445..b1f5608b8 100644 --- a/codex-rs/tui/src/debug_config.rs +++ b/codex-rs/tui/src/debug_config.rs @@ -518,7 +518,7 @@ fn format_network_unix_socket_permission( ) -> &'static str { match permission { NetworkUnixSocketPermissionToml::Allow => "allow", - NetworkUnixSocketPermissionToml::None => "none", + NetworkUnixSocketPermissionToml::Deny => "deny", } } @@ -837,7 +837,7 @@ mod tests { ), ( "/tmp/blocked.sock".to_string(), - NetworkUnixSocketPermissionToml::None, + NetworkUnixSocketPermissionToml::Deny, ), ]), }), @@ -854,7 +854,7 @@ mod tests { let rendered = render_to_text(&render_debug_config_lines(&stack)); assert!(rendered.contains( - "experimental_network: unix_sockets={/tmp/blocked.sock=none, /tmp/codex.sock=allow} (source: cloud requirements)" + "experimental_network: unix_sockets={/tmp/blocked.sock=deny, /tmp/codex.sock=allow} (source: cloud requirements)" )); }