Always use private desktops for legacy Windows sandboxes (#46554)

## What changed

- Remove the private-desktop opt-out from elevated and unelevated Windows sandbox launches.
- Remove `windows.sandbox_private_desktop` and its managed requirement and API fields. Warn users to remove the obsolete setting.
- Require a private desktop name when launching through the Windows sandbox wrapper and command runner.

## Testing

Add coverage for the obsolete-setting migration warning and update wrapper tests to verify a live private desktop is passed and a missing desktop name is rejected.

GitOrigin-RevId: c7135f8d211aac8d812180691c2c1e433d77cde4
This commit is contained in:
iceweasel-oai
2026-09-19 01:21:32 +00:00
committed by copyberry
parent c6f5d9e9b5
commit a633ebc124
94 changed files with 179 additions and 680 deletions
+51 -98
View File
@@ -178,7 +178,6 @@ pub struct ConfigRequirements {
pub auto_review_required_models: Option<Sourced<BTreeSet<String>>>,
pub permission_profile: ConstrainedWithSource<PermissionProfile>,
pub windows_sandbox_mode: ConstrainedWithSource<Option<WindowsSandboxModeToml>>,
pub windows_sandbox_private_desktop: Option<Sourced<bool>>,
pub web_search_mode: ConstrainedWithSource<WebSearchMode>,
pub allow_managed_hooks_only: Option<Sourced<bool>>,
pub allow_appshots: Option<Sourced<bool>>,
@@ -234,7 +233,6 @@ impl Default for ConfigRequirements {
Constrained::allow_any(/*initial_value*/ None),
/*source*/ None,
),
windows_sandbox_private_desktop: None,
web_search_mode: ConstrainedWithSource::new(
Constrained::allow_any(WebSearchMode::Cached),
/*source*/ None,
@@ -869,7 +867,6 @@ impl fmt::Display for WebSearchModeRequirement {
#[derive(Deserialize, Debug, Clone, Default, PartialEq, Eq)]
pub struct WindowsRequirementsToml {
pub allowed_sandbox_implementations: Option<Vec<WindowsSandboxImplementationToml>>,
pub sandbox_private_desktop: Option<bool>,
}
#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
@@ -881,7 +878,7 @@ pub enum WindowsSandboxImplementationToml {
impl WindowsRequirementsToml {
pub fn is_empty(&self) -> bool {
self.allowed_sandbox_implementations.is_none() && self.sandbox_private_desktop.is_none()
self.allowed_sandbox_implementations.is_none()
}
}
@@ -1614,16 +1611,6 @@ impl ConfigRequirementsToml {
if let Some(enabled) = self.feedback.as_ref().and_then(|feedback| feedback.enabled) {
config.feedback.get_or_insert_default().enabled = Some(enabled);
}
if let Some(sandbox_private_desktop) = self
.windows
.as_ref()
.and_then(|windows| windows.sandbox_private_desktop)
{
config
.windows
.get_or_insert_default()
.sandbox_private_desktop = Some(sandbox_private_desktop);
}
}
/// Returns the exact managed field affected by editing `segments`.
@@ -1635,7 +1622,7 @@ impl ConfigRequirementsToml {
}) {
return Some("model_providers");
}
let managed_fields: [(bool, &[&str], &'static str); 10] = [
let managed_fields: [(bool, &[&str], &'static str); 9] = [
(
self.model_provider.is_some(),
&["model_provider"],
@@ -1666,14 +1653,6 @@ impl ConfigRequirementsToml {
&["feedback", "enabled"],
"feedback.enabled",
),
(
self.windows
.as_ref()
.and_then(|windows| windows.sandbox_private_desktop)
.is_some(),
&["windows", "sandbox_private_desktop"],
"windows.sandbox_private_desktop",
),
(
self.cli_auth_credentials_store.is_some(),
&["cli_auth_credentials_store"],
@@ -1915,74 +1894,62 @@ impl TryFrom<ConfigRequirementsWithSources> for ConfigRequirements {
/*source*/ None,
),
};
let (windows_sandbox_mode, windows_sandbox_private_desktop) = match windows {
let windows_sandbox_mode = match windows {
Some(Sourced {
value:
WindowsRequirementsToml {
allowed_sandbox_implementations,
sandbox_private_desktop,
allowed_sandbox_implementations: Some(implementations),
},
source: requirement_source,
}) => {
let sandbox_private_desktop = sandbox_private_desktop
.map(|value| Sourced::new(value, requirement_source.clone()));
let sandbox_mode = match allowed_sandbox_implementations {
Some(implementations) => {
if implementations.is_empty() {
return Err(ConstraintError::empty_field(
"windows.allowed_sandbox_implementations",
));
}
// Prefer elevated when both Windows sandbox implementations are allowed.
let initial_value = if implementations
.contains(&WindowsSandboxImplementationToml::Elevated)
{
WindowsSandboxModeToml::Elevated
} else {
WindowsSandboxModeToml::Unelevated
};
if implementations.is_empty() {
return Err(ConstraintError::empty_field(
"windows.allowed_sandbox_implementations",
));
}
// Prefer elevated when both Windows sandbox implementations are allowed.
let initial_value =
if implementations.contains(&WindowsSandboxImplementationToml::Elevated) {
WindowsSandboxModeToml::Elevated
} else {
WindowsSandboxModeToml::Unelevated
};
let requirement_source_for_error = requirement_source.clone();
let constrained = Constrained::new(
Some(initial_value),
move |candidate| match candidate {
Some(WindowsSandboxModeToml::Mxc) => Ok(()),
Some(WindowsSandboxModeToml::Elevated)
if implementations
.contains(&WindowsSandboxImplementationToml::Elevated) =>
{
Ok(())
}
Some(WindowsSandboxModeToml::Unelevated)
if implementations.contains(
&WindowsSandboxImplementationToml::Unelevated,
) =>
{
Ok(())
}
_ => Err(ConstraintError::InvalidValue {
field_name: "windows.sandbox",
candidate: format!("{candidate:?}"),
allowed: format!("{implementations:?}"),
requirement_source: requirement_source_for_error.clone(),
}),
},
)?;
ConstrainedWithSource::new(constrained, Some(requirement_source))
}
None => ConstrainedWithSource::new(
Constrained::allow_any(/*initial_value*/ None),
/*source*/ None,
),
};
(sandbox_mode, sandbox_private_desktop)
let requirement_source_for_error = requirement_source.clone();
let constrained =
Constrained::new(Some(initial_value), move |candidate| match candidate {
Some(WindowsSandboxModeToml::Mxc) => Ok(()),
Some(WindowsSandboxModeToml::Elevated)
if implementations
.contains(&WindowsSandboxImplementationToml::Elevated) =>
{
Ok(())
}
Some(WindowsSandboxModeToml::Unelevated)
if implementations
.contains(&WindowsSandboxImplementationToml::Unelevated) =>
{
Ok(())
}
_ => Err(ConstraintError::InvalidValue {
field_name: "windows.sandbox",
candidate: format!("{candidate:?}"),
allowed: format!("{implementations:?}"),
requirement_source: requirement_source_for_error.clone(),
}),
})?;
ConstrainedWithSource::new(constrained, Some(requirement_source))
}
None => (
ConstrainedWithSource::new(
Constrained::allow_any(/*initial_value*/ None),
/*source*/ None,
),
None,
Some(Sourced {
value:
WindowsRequirementsToml {
allowed_sandbox_implementations: None,
},
..
})
| None => ConstrainedWithSource::new(
Constrained::allow_any(/*initial_value*/ None),
/*source*/ None,
),
};
let exec_policy = match rules {
@@ -2126,7 +2093,6 @@ impl TryFrom<ConfigRequirementsWithSources> for ConfigRequirements {
auto_review_required_models,
permission_profile,
windows_sandbox_mode,
windows_sandbox_private_desktop,
web_search_mode,
allow_managed_hooks_only,
allow_appshots,
@@ -2219,10 +2185,6 @@ mod tests {
feedback: Some(FeedbackConfigToml {
enabled: Some(false),
}),
windows: Some(WindowsRequirementsToml {
sandbox_private_desktop: Some(false),
..Default::default()
}),
..Default::default()
};
let cases: &[(&[&str], Option<&str>)] = &[
@@ -2240,16 +2202,8 @@ mod tests {
),
(&["allow_login_shell"], Some("allow_login_shell")),
(&["feedback", "enabled"], Some("feedback.enabled")),
(
&["windows", "sandbox_private_desktop"],
Some("windows.sandbox_private_desktop"),
),
(&[], Some("sqlite_home")),
(&["feedback"], Some("feedback.enabled")),
(
&["windows", "sandbox_private_desktop", "value"],
Some("windows.sandbox_private_desktop"),
),
(&["feedback", "other"], None),
(&["windows", "sandbox"], None),
];
@@ -2846,8 +2800,7 @@ mod tests {
enabled: Some(false),
};
let windows = WindowsRequirementsToml {
allowed_sandbox_implementations: None,
sandbox_private_desktop: Some(true),
allowed_sandbox_implementations: Some(vec![WindowsSandboxImplementationToml::Elevated]),
};
let enforce_residency = ResidencyRequirement::Us;
let enforce_source = source.clone();
+3
View File
@@ -268,6 +268,9 @@ pub(crate) fn ignored_config_warning(
.collect::<Vec<_>>()
.as_slice()
{
["windows", "sandbox_private_desktop"] => {
" Remove windows.sandbox_private_desktop; legacy Windows sandboxes always use a private desktop."
}
["network_proxy"] => {
" Use [permissions.<name>.network] for network settings, or [experimental_network] in requirements.toml for enforced network policy."
}
@@ -201,3 +201,20 @@ include_view_image_tool = false
"Codex is ignoring 3 unrecognized configuration settings. Check for typos or deprecated settings.\n enterprise-managed (Defaults, cfg): `model_providers.custom.unknown_timeout` is ignored.\n session-flags: `model_providers.custom.unknown_timeout` is ignored.\n session-flags: `profiles.work.features.include_view_image_tool` is ignored. Use [features].view_image to configure the image tool."
);
}
#[test]
fn removed_private_desktop_setting_has_migration_hint() {
let config = ConfigLayerStack::new(
vec![layer(
ConfigLayerSource::SessionFlags,
"[windows]\nsandbox_private_desktop = false",
)],
ConfigRequirements::default(),
ConfigRequirementsToml::default(),
)
.unwrap();
assert_eq!(
ignored_config_warning(&config, &[]).unwrap(),
"Codex is ignoring 1 unrecognized configuration setting. Check for typos or deprecated settings.\n session-flags: `windows.sandbox_private_desktop` is ignored. Remove windows.sandbox_private_desktop; legacy Windows sandboxes always use a private desktop."
);
}
-3
View File
@@ -170,9 +170,6 @@ pub enum WindowsSandboxModeToml {
#[schemars(deny_unknown_fields)]
pub struct WindowsToml {
pub sandbox: Option<WindowsSandboxModeToml>,
/// Defaults to `true` for legacy sandboxes and `false` for MXC. Set to `false`
/// to launch the final sandboxed child process on `Winsta0\\Default`.
pub sandbox_private_desktop: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, JsonSchema)]