mirror of
https://github.com/openai/codex.git
synced 2026-10-20 08:19:50 +00:00
Add a Windows MXC sandbox opt-out (#51547)
## What changed Add `windows.allow_mxc` to configuration and its JSON schema. Setting it to `false` blocks automatic MXC selection even when `features.prefer_mxc` is enabled, and rejects explicit `windows.sandbox = "mxc"` configuration with a clear error. Omitting the setting preserves existing behavior. ## Testing Extend configuration tests to cover disabling automatic MXC selection and rejecting explicit MXC configuration when `windows.allow_mxc = false`. GitOrigin-RevId: bf7c0648cfcb3cc1d0dc41b9faffcb8078672780
This commit is contained in:
@@ -194,6 +194,8 @@ pub enum WindowsSandboxModeToml {
|
||||
#[schemars(deny_unknown_fields)]
|
||||
pub struct WindowsToml {
|
||||
pub sandbox: Option<WindowsSandboxModeToml>,
|
||||
/// False blocks both explicit MXC configuration and automatic selection.
|
||||
pub allow_mxc: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, JsonSchema)]
|
||||
|
||||
@@ -6738,6 +6738,10 @@
|
||||
"WindowsToml": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"allow_mxc": {
|
||||
"description": "False blocks both explicit MXC configuration and automatic selection.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"sandbox": {
|
||||
"$ref": "#/definitions/WindowsSandboxModeToml"
|
||||
}
|
||||
|
||||
@@ -1913,6 +1913,7 @@ async fn network_proxy_feature_matrix_preserves_sandbox_network_semantics() -> s
|
||||
}),
|
||||
windows: Some(WindowsToml {
|
||||
sandbox: Some(WindowsSandboxModeToml::Elevated),
|
||||
..Default::default()
|
||||
}),
|
||||
features,
|
||||
..Default::default()
|
||||
@@ -3682,6 +3683,7 @@ async fn implicit_builtin_workspace_profile_preserves_sandbox_workspace_write_se
|
||||
}),
|
||||
windows: Some(WindowsToml {
|
||||
sandbox: Some(WindowsSandboxModeToml::Elevated),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
@@ -3746,6 +3748,7 @@ async fn implicit_builtin_workspace_profile_preserves_add_dir_metadata_carveouts
|
||||
)])),
|
||||
windows: Some(WindowsToml {
|
||||
sandbox: Some(WindowsSandboxModeToml::Elevated),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
@@ -11118,6 +11121,12 @@ async fn local_mxc_preference_preserves_configured_backend() -> anyhow::Result<(
|
||||
use codex_sandboxing::SandboxType::WindowsRestrictedToken as RestrictedToken;
|
||||
|
||||
let codex_home = TempDir::new()?;
|
||||
let permission_selection = EffectivePermissionSelection {
|
||||
profiles: None,
|
||||
selected_profile_id: None,
|
||||
persisted_profile_id_was_provided: false,
|
||||
requirements_force_profile_selection: false,
|
||||
};
|
||||
for (prefer, resolved_preference, binding, allow_mxc, mode, expected) in [
|
||||
(true, true, true, true, "unelevated", WindowsMxc),
|
||||
(true, false, true, true, "unelevated", RestrictedToken),
|
||||
@@ -11150,16 +11159,11 @@ async fn local_mxc_preference_preserves_configured_backend() -> anyhow::Result<(
|
||||
.config_layer_stack
|
||||
.requirements()
|
||||
.windows_sandbox_mode,
|
||||
&EffectivePermissionSelection {
|
||||
profiles: None,
|
||||
selected_profile_id: None,
|
||||
persisted_profile_id_was_provided: false,
|
||||
requirements_force_profile_selection: false,
|
||||
},
|
||||
&permission_selection,
|
||||
/*profiles_are_active*/ false,
|
||||
/*permission_profile*/ None,
|
||||
/*network_requirements*/ None,
|
||||
cfg.features.as_ref(),
|
||||
&cfg,
|
||||
/*enable_network_proxy*/ true,
|
||||
)?,
|
||||
binding && allow_mxc,
|
||||
@@ -11186,6 +11190,36 @@ async fn local_mxc_preference_preserves_configured_backend() -> anyhow::Result<(
|
||||
"prefer={prefer}, resolved={resolved_preference}, binding={binding}, mode={mode}"
|
||||
);
|
||||
}
|
||||
for sandbox in ["unelevated", "mxc"] {
|
||||
let cfg: ConfigToml = toml::from_str(&format!(
|
||||
"[windows]\nsandbox = {sandbox:?}\nallow_mxc = false\n[features]\nprefer_mxc = true\n"
|
||||
))?;
|
||||
assert!(!config_allows_mxc(
|
||||
&ConfigRequirements::default().windows_sandbox_mode,
|
||||
&permission_selection,
|
||||
/*profiles_are_active*/ false,
|
||||
/*permission_profile*/ None,
|
||||
/*network_requirements*/ None,
|
||||
&cfg,
|
||||
/*enable_network_proxy*/ false,
|
||||
)?);
|
||||
let result = Config::load_from_base_config_with_overrides(
|
||||
cfg,
|
||||
ConfigOverrides::default(),
|
||||
codex_home.abs(),
|
||||
)
|
||||
.await;
|
||||
if sandbox == "mxc" {
|
||||
assert_eq!(
|
||||
result
|
||||
.expect_err("explicit MXC must respect the opt-out")
|
||||
.to_string(),
|
||||
"windows.sandbox = \"mxc\" is not allowed when windows.allow_mxc = false",
|
||||
);
|
||||
} else {
|
||||
assert!(!result?.prefer_mxc);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -3442,6 +3442,14 @@ impl Config {
|
||||
};
|
||||
let respect_system_proxy = features.enabled(Feature::RespectSystemProxy);
|
||||
let enable_network_proxy = features.enabled(Feature::NetworkProxy);
|
||||
let allow_mxc =
|
||||
cfg.windows.as_ref().and_then(|windows| windows.allow_mxc) != Some(false);
|
||||
if !allow_mxc && resolve_windows_sandbox_mode(&cfg) == Some(WindowsSandboxModeToml::Mxc) {
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::InvalidInput,
|
||||
"windows.sandbox = \"mxc\" is not allowed when windows.allow_mxc = false",
|
||||
));
|
||||
}
|
||||
let PreparedWindowsSandboxConfig {
|
||||
mode: windows_sandbox_mode,
|
||||
sandbox_type: windows_sandbox_type,
|
||||
@@ -3537,7 +3545,7 @@ impl Config {
|
||||
profiles_are_active,
|
||||
permission_profile.as_ref(),
|
||||
network_requirements.as_ref(),
|
||||
cfg.features.as_ref(),
|
||||
&cfg,
|
||||
enable_network_proxy,
|
||||
)?
|
||||
&& codex_sandboxing::windows_mxc_available();
|
||||
|
||||
@@ -11,6 +11,7 @@ use super::profile_allows_configured_network_proxy;
|
||||
use codex_config::ConstrainedWithSource;
|
||||
use codex_config::NetworkConstraints;
|
||||
use codex_config::Sourced;
|
||||
use codex_config::config_toml::ConfigToml;
|
||||
use codex_config::types::WindowsSandboxModeToml;
|
||||
use codex_features::FeaturesToml;
|
||||
use codex_protocol::config_types::WindowsSandboxLevel;
|
||||
@@ -94,20 +95,20 @@ pub fn prepare_windows_sandbox_config(
|
||||
})
|
||||
}
|
||||
|
||||
/// Managed requirements take precedence; otherwise preserve explicit
|
||||
/// feature-level or active-profile binding denials during automatic selection.
|
||||
/// Preserve ordinary and managed MXC opt-outs plus network binding denials.
|
||||
pub(super) fn config_allows_mxc(
|
||||
windows_sandbox_mode: &ConstrainedWithSource<Option<WindowsSandboxModeToml>>,
|
||||
permission_selection: &EffectivePermissionSelection<'_>,
|
||||
profiles_are_active: bool,
|
||||
permission_profile: Option<&PermissionProfile>,
|
||||
network_requirements: Option<&Sourced<NetworkConstraints>>,
|
||||
features: Option<&FeaturesToml>,
|
||||
cfg: &ConfigToml,
|
||||
enable_network_proxy: bool,
|
||||
) -> std::io::Result<bool> {
|
||||
if windows_sandbox_mode
|
||||
.can_set(&Some(WindowsSandboxModeToml::Mxc))
|
||||
.is_err()
|
||||
if cfg.windows.as_ref().and_then(|windows| windows.allow_mxc) == Some(false)
|
||||
|| windows_sandbox_mode
|
||||
.can_set(&Some(WindowsSandboxModeToml::Mxc))
|
||||
.is_err()
|
||||
{
|
||||
return Ok(false);
|
||||
}
|
||||
@@ -123,7 +124,7 @@ pub(super) fn config_allows_mxc(
|
||||
Ok(windows_mxc_allowed_by_config(
|
||||
windows_sandbox_mode,
|
||||
network_requirements,
|
||||
features,
|
||||
cfg.features.as_ref(),
|
||||
enable_network_proxy,
|
||||
profile_local_binding,
|
||||
))
|
||||
|
||||
Reference in New Issue
Block a user