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
@@ -10032,12 +10032,6 @@
"string",
"null"
]
},
"windowsSandboxPrivateDesktop": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
@@ -5912,12 +5912,6 @@
"string",
"null"
]
},
"windowsSandboxPrivateDesktop": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
@@ -599,12 +599,6 @@
"string",
"null"
]
},
"windowsSandboxPrivateDesktop": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
@@ -27,4 +27,4 @@ modelProviders: { [key in string]?: JsonValue } | null, /**
* Effective login methods after managed, forced-login, and workspace restrictions.
* An empty list permits no login method. Older servers may omit this field.
*/
allowedLoginMethods: Array<ForcedLoginMethod> | null, cliAuthCredentialsStore: CliAuthCredentialsStoreMode | null, chatgptBaseUrl: string | null, additionalDeveloperInstructions: string | null, allowedApprovalPolicies: Array<AskForApproval> | null, allowedSandboxModes: Array<SandboxMode> | null, allowedWindowsSandboxImplementations: Array<WindowsSandboxImplementation> | null, allowedPermissionProfiles: { [key in string]?: boolean } | null, defaultPermissions: string | null, allowedWebSearchModes: Array<WebSearchMode> | null, allowManagedHooksOnly: boolean | null, allowBrowserAndComputerUse: boolean | null, allowAppshots: boolean | null, allowRemoteControl: boolean | null, computerUse: ComputerUseRequirements | null, browserUse: BrowserUseRequirements | null, inAppBrowser: InAppBrowserRequirements | null, featureRequirements: { [key in string]?: boolean } | null, enforceResidency: ResidencyRequirement | null, autoReview: AutoReviewRequirements | null, models: ModelsRequirements | null, sqliteHome: PathUri | null, logDir: PathUri | null, modelCatalogJson: PathUri | null, checkForUpdateOnStartup: boolean | null, allowLoginShell: boolean | null, feedback: FeedbackRequirements | null, windowsSandboxPrivateDesktop: boolean | null};
allowedLoginMethods: Array<ForcedLoginMethod> | null, cliAuthCredentialsStore: CliAuthCredentialsStoreMode | null, chatgptBaseUrl: string | null, additionalDeveloperInstructions: string | null, allowedApprovalPolicies: Array<AskForApproval> | null, allowedSandboxModes: Array<SandboxMode> | null, allowedWindowsSandboxImplementations: Array<WindowsSandboxImplementation> | null, allowedPermissionProfiles: { [key in string]?: boolean } | null, defaultPermissions: string | null, allowedWebSearchModes: Array<WebSearchMode> | null, allowManagedHooksOnly: boolean | null, allowBrowserAndComputerUse: boolean | null, allowAppshots: boolean | null, allowRemoteControl: boolean | null, computerUse: ComputerUseRequirements | null, browserUse: BrowserUseRequirements | null, inAppBrowser: InAppBrowserRequirements | null, featureRequirements: { [key in string]?: boolean } | null, enforceResidency: ResidencyRequirement | null, autoReview: AutoReviewRequirements | null, models: ModelsRequirements | null, sqliteHome: PathUri | null, logDir: PathUri | null, modelCatalogJson: PathUri | null, checkForUpdateOnStartup: boolean | null, allowLoginShell: boolean | null, feedback: FeedbackRequirements | null};
@@ -456,7 +456,6 @@ pub struct ConfigRequirements {
pub check_for_update_on_startup: Option<bool>,
pub allow_login_shell: Option<bool>,
pub feedback: Option<FeedbackRequirements>,
pub windows_sandbox_private_desktop: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
@@ -2159,7 +2159,6 @@ fn config_requirements_granular_allowed_approval_policy_is_marked_experimental()
check_for_update_on_startup: None,
allow_login_shell: None,
feedback: None,
windows_sandbox_private_desktop: None,
});
assert_eq!(reason, Some("askForApproval.granular"));
-3
View File
@@ -719,7 +719,6 @@ mod tests {
SandboxType::WindowsRestrictedToken,
vec![cwd],
WindowsSandboxLevel::Disabled,
/*windows_sandbox_private_desktop*/ false,
PermissionProfile::read_only(),
/*arg0*/ None,
)
@@ -837,7 +836,6 @@ mod tests {
SandboxType::None,
vec![cwd.clone()],
WindowsSandboxLevel::Disabled,
/*windows_sandbox_private_desktop*/ false,
PermissionProfile::read_only(),
/*arg0*/ None,
),
@@ -931,7 +929,6 @@ mod tests {
SandboxType::None,
vec![cwd],
WindowsSandboxLevel::Disabled,
/*windows_sandbox_private_desktop*/ false,
PermissionProfile::read_only(),
/*arg0*/ None,
),
@@ -1696,7 +1696,7 @@ async fn read_materializes_default_allow_login_shell() {
}
#[tokio::test]
async fn write_value_allows_unmanaged_sibling_of_exact_requirement() {
async fn write_value_allows_unmanaged_setting_with_exact_requirement() {
let tmp = tempdir().expect("tempdir");
let path = tmp.path().join(CONFIG_TOML_FILE);
std::fs::write(&path, "").unwrap();
@@ -1707,8 +1707,7 @@ async fn write_value_allows_unmanaged_sibling_of_exact_requirement() {
LoaderOverrides::without_managed_config_for_tests(),
CloudConfigBundleFixture::loader_with_enterprise_requirement(
r#"
[windows]
sandbox_private_desktop = false
allow_login_shell = false
"#,
),
);
@@ -1722,7 +1721,7 @@ sandbox_private_desktop = false
expected_version: None,
})
.await
.expect("unmanaged sibling should remain writable");
.expect("unmanaged setting should remain writable");
assert!(
std::fs::read_to_string(path)
@@ -299,10 +299,6 @@ impl CommandExecRequestProcessor {
network_environment_id: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level,
windows_sandbox_private_desktop: self
.config
.permissions
.windows_sandbox_private_desktop,
justification: None,
arg0: None,
};
@@ -399,10 +399,6 @@ fn map_requirements_to_api(
}
None => ConfigRequirementsToml::default(),
};
let windows_sandbox_private_desktop = requirements
.windows
.as_ref()
.and_then(|windows| windows.sandbox_private_desktop);
Some(ConfigRequirements {
model_provider: requirements.model_provider,
@@ -539,7 +535,6 @@ fn map_requirements_to_api(
feedback: requirements.feedback.map(|feedback| FeedbackRequirements {
enabled: feedback.enabled,
}),
windows_sandbox_private_desktop,
})
}
@@ -1105,7 +1100,6 @@ mod tests {
codex_config::WindowsSandboxImplementationToml::Elevated,
codex_config::WindowsSandboxImplementationToml::Unelevated,
]),
sandbox_private_desktop: Some(false),
}),
..ConfigRequirementsToml::default()
});
@@ -1117,7 +1111,6 @@ mod tests {
WindowsSandboxImplementation::Unelevated,
])
);
assert_eq!(mapped.windows_sandbox_private_desktop, Some(false));
}
#[test]
-2
View File
@@ -496,7 +496,6 @@ async fn run_command_under_sandbox(
sandbox_exe: Some(codex_self_exe.as_path()),
use_legacy_landlock: false,
windows_sandbox_level: codex_protocol::config_types::WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
})?;
let (program, args) = request
.command
@@ -587,7 +586,6 @@ async fn run_command_under_windows_session(
deny_write_paths_override: empty_paths,
tty: false,
stdin_open: true,
use_private_desktop: config.permissions.windows_sandbox_private_desktop,
})
.await;
+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)]
-4
View File
@@ -6207,10 +6207,6 @@
"properties": {
"sandbox": {
"$ref": "#/definitions/WindowsSandboxModeToml"
},
"sandbox_private_desktop": {
"description": "Defaults to `true` for legacy sandboxes and `false` for MXC. Set to `false` to launch the final sandboxed child process on `Winsta0\\\\Default`.",
"type": "boolean"
}
},
"type": "object"
-1
View File
@@ -376,7 +376,6 @@ fn resolved_local_environments<const N: usize>(
workspace_roots: Vec::new(),
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_type: codex_protocol::sandbox::SandboxType::None,
windows_sandbox_private_desktop: true,
use_legacy_landlock: false,
permission_profile: PermissionProfileSnapshot::legacy(
PermissionProfile::read_only(),
-10
View File
@@ -1901,7 +1901,6 @@ async fn network_proxy_feature_matrix_preserves_sandbox_network_semantics() -> s
}),
windows: Some(WindowsToml {
sandbox: Some(WindowsSandboxModeToml::Elevated),
sandbox_private_desktop: None,
}),
features,
..Default::default()
@@ -3548,7 +3547,6 @@ async fn implicit_builtin_workspace_profile_preserves_sandbox_workspace_write_se
}),
windows: Some(WindowsToml {
sandbox: Some(WindowsSandboxModeToml::Elevated),
sandbox_private_desktop: None,
}),
..Default::default()
},
@@ -3613,7 +3611,6 @@ async fn implicit_builtin_workspace_profile_preserves_add_dir_metadata_carveouts
)])),
windows: Some(WindowsToml {
sandbox: Some(WindowsSandboxModeToml::Elevated),
sandbox_private_desktop: None,
}),
..Default::default()
},
@@ -13024,9 +13021,6 @@ allow_login_shell = true
[feedback]
enabled = true
[windows]
sandbox_private_desktop = true
"#,
)?;
@@ -13042,9 +13036,6 @@ allow_login_shell = false
[feedback]
enabled = false
[windows]
sandbox_private_desktop = false
"#,
required_sqlite_home.display(),
required_log_dir.display(),
@@ -13058,7 +13049,6 @@ sandbox_private_desktop = false
assert!(!config.check_for_update_on_startup);
assert!(!config.permissions.allow_login_shell);
assert!(!config.feedback_enabled);
assert!(!config.permissions.windows_sandbox_private_desktop);
assert!(config.startup_warnings.iter().any(|warning| {
warning.contains("Configured value for `check_for_update_on_startup` is overridden")
}));
-7
View File
@@ -6,7 +6,6 @@ use crate::unified_exec::DEFAULT_MAX_BACKGROUND_TERMINAL_TIMEOUT_MS;
use crate::unified_exec::MIN_EMPTY_YIELD_TIME_MS;
use crate::windows_sandbox::WindowsSandboxLevelExt;
use crate::windows_sandbox::resolve_windows_sandbox_mode;
use crate::windows_sandbox::resolve_windows_sandbox_private_desktop;
use crate::windows_sandbox::windows_sandbox_level_for_legacy_checks;
use codex_agent_roles::load_agent_roles;
use codex_config::CloudConfigBundleLoader;
@@ -349,8 +348,6 @@ pub struct Permissions {
pub windows_sandbox_mode: Option<WindowsSandboxModeToml>,
/// Selected Windows sandbox implementation, separate from the legacy setup level.
pub windows_sandbox_type: SandboxType,
/// Whether the final Windows sandboxed child should run on a private desktop.
pub windows_sandbox_private_desktop: bool,
}
impl Permissions {
@@ -372,7 +369,6 @@ impl Permissions {
shell_environment_policy: ShellEnvironmentPolicy::default(),
windows_sandbox_mode: None,
windows_sandbox_type: SandboxType::None,
windows_sandbox_private_desktop: true,
})
}
@@ -3232,7 +3228,6 @@ impl Config {
auto_review_required_models: _,
permission_profile: mut constrained_permission_profile,
windows_sandbox_mode: mut constrained_windows_sandbox_mode,
windows_sandbox_private_desktop: _,
web_search_mode: mut constrained_web_search_mode,
allow_managed_hooks_only: _,
allow_appshots: _,
@@ -3369,7 +3364,6 @@ impl Config {
windows_sandbox_type,
windows_sandbox_level,
);
let windows_sandbox_private_desktop = resolve_windows_sandbox_private_desktop(&cfg);
let resolved_cwd = AbsolutePathBuf::try_from(normalize_for_native_workdir({
use std::env;
@@ -4200,7 +4194,6 @@ impl Config {
shell_environment_policy,
windows_sandbox_mode,
windows_sandbox_type,
windows_sandbox_private_desktop,
},
explicit_permission_profile_mode,
custom_permission_profiles,
-11
View File
@@ -71,17 +71,6 @@ pub(super) fn apply_to_config(
}
}
}
if let Some(requirement) = requirements.windows_sandbox_private_desktop.as_ref() {
apply_exact_requirement(
"windows.sandbox_private_desktop",
&mut config
.windows
.get_or_insert_default()
.sandbox_private_desktop,
Some(requirement),
startup_warnings,
);
}
}
fn apply_exact_requirement<T>(
@@ -1154,7 +1154,6 @@ mod tests {
workspace_roots: Vec::new(),
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_type: codex_protocol::sandbox::SandboxType::None,
windows_sandbox_private_desktop: true,
use_legacy_landlock: false,
permission_profile: PermissionProfileSnapshot::legacy(PermissionProfile::read_only()),
shell_environment_policy: Default::default(),
@@ -1335,7 +1334,6 @@ url = "ws://127.0.0.1:8765"
workspace_roots: Vec::new(),
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_type: codex_protocol::sandbox::SandboxType::None,
windows_sandbox_private_desktop: true,
use_legacy_landlock: false,
permission_profile: PermissionProfileSnapshot::active_with_profile_workspace_roots(
PermissionProfile::read_only(),
@@ -1600,7 +1598,6 @@ url = "ws://127.0.0.1:8765"
workspace_roots: Vec::new(),
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_type: codex_protocol::sandbox::SandboxType::None,
windows_sandbox_private_desktop: true,
use_legacy_landlock: false,
permission_profile: PermissionProfileSnapshot::active_with_profile_workspace_roots(
PermissionProfile::read_only(),
@@ -1988,7 +1985,6 @@ url = "ws://127.0.0.1:8765"
workspace_roots: Vec::new(),
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_type: codex_protocol::sandbox::SandboxType::None,
windows_sandbox_private_desktop: true,
use_legacy_landlock: false,
permission_profile: PermissionProfileSnapshot::active_with_profile_workspace_roots(
PermissionProfile::read_only(),
@@ -2059,7 +2055,6 @@ url = "ws://127.0.0.1:8765"
workspace_roots: selection.workspace_roots.clone(),
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_type: codex_protocol::sandbox::SandboxType::None,
windows_sandbox_private_desktop: true,
use_legacy_landlock: false,
permission_profile: PermissionProfileSnapshot::legacy(PermissionProfile::read_only()),
shell_environment_policy: Default::default(),
-9
View File
@@ -106,7 +106,6 @@ pub struct ExecParams {
// TODO(anp): Reconcile these launch settings with TurnEnvironment::sandbox_context
// so turn-scoped execution uses the selected environment's backend.
pub windows_sandbox_level: codex_protocol::config_types::WindowsSandboxLevel,
pub windows_sandbox_private_desktop: bool,
pub justification: Option<String>,
pub arg0: Option<String>,
}
@@ -358,7 +357,6 @@ pub fn build_exec_request(
network,
network_environment_id,
windows_sandbox_level,
windows_sandbox_private_desktop,
// TODO: Should arg0 be set on the ExecRequest that is returned?
arg0: _,
@@ -420,7 +418,6 @@ pub fn build_exec_request(
},
use_legacy_landlock,
windows_sandbox_level,
windows_sandbox_private_desktop,
})
.map_err(CodexErr::from)?;
// These hints belong to the native Windows backend. Other backends use
@@ -463,7 +460,6 @@ pub(crate) async fn execute_exec_request(
windows_sandbox_policy_cwd,
windows_sandbox_workspace_roots,
windows_sandbox_level,
windows_sandbox_private_desktop,
permission_profile,
windows_sandbox_filesystem_overrides,
network_environment_id,
@@ -494,7 +490,6 @@ pub(crate) async fn execute_exec_request(
network_environment_id,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level,
windows_sandbox_private_desktop,
justification: None,
arg0,
};
@@ -633,7 +628,6 @@ async fn exec_windows_sandbox(
expiration,
capture_policy,
windows_sandbox_level,
windows_sandbox_private_desktop,
..
} = params;
if let Some(network) = network.as_ref() {
@@ -707,7 +701,6 @@ async fn exec_windows_sandbox(
env_map: env,
timeout_ms,
cancellation,
use_private_desktop: windows_sandbox_private_desktop,
proxy_enforced,
network_proxy_restricting_sid,
read_roots_override: elevated_read_roots_override.as_deref(),
@@ -730,7 +723,6 @@ async fn exec_windows_sandbox(
cancellation,
&additional_deny_read_paths,
&additional_deny_write_paths,
windows_sandbox_private_desktop,
)
}
})
@@ -945,7 +937,6 @@ async fn exec(
// If applicable, these fields should have been honored upstream of
// this exec call.
windows_sandbox_level: _,
windows_sandbox_private_desktop: _,
// These fields are related to approvals, so can be ignored here.
sandbox_permissions: _,
justification: _,
-7
View File
@@ -278,7 +278,6 @@ async fn exec_full_buffer_capture_ignores_expiration() -> Result<()> {
network_environment_id: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
justification: None,
arg0: None,
},
@@ -315,7 +314,6 @@ async fn exec_full_buffer_capture_keeps_io_drain_timeout_when_descendant_holds_p
network_environment_id: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
justification: None,
arg0: None,
},
@@ -507,7 +505,6 @@ async fn process_exec_tool_call_preserves_full_buffer_capture_policy(
network_environment_id: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
justification: None,
arg0: None,
},
@@ -1210,7 +1207,6 @@ fn build_exec_request_projects_workspace_roots_only_for_windows_sandbox() -> Res
network_environment_id: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level: WindowsSandboxLevel::RestrictedToken,
windows_sandbox_private_desktop: false,
justification: None,
arg0: None,
},
@@ -1302,7 +1298,6 @@ async fn kill_child_process_group_kills_grandchildren_on_timeout() -> Result<()>
network_environment_id: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level: codex_protocol::config_types::WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
justification: None,
arg0: None,
};
@@ -1358,7 +1353,6 @@ async fn process_exec_tool_call_respects_cancellation_token() -> Result<()> {
network_environment_id: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level: codex_protocol::config_types::WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
justification: None,
arg0: None,
};
@@ -1443,7 +1437,6 @@ while :; do sleep 1; done"#
network_environment_id: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level: codex_protocol::config_types::WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
justification: None,
arg0: None,
};
-4
View File
@@ -1349,10 +1349,6 @@ async fn mcp_sandbox_cwd_uses_matching_server_environment_uri() -> anyhow::Resul
workspace_roots: Vec::new(),
windows_sandbox_level: turn_context.windows_sandbox_level,
windows_sandbox_type: turn_context.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: turn_context
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: turn_context.config.features.use_legacy_landlock(),
permission_profile: turn_context
.config
-5
View File
@@ -63,7 +63,6 @@ pub struct ExecRequest {
// TODO(anp): Reconcile these backend copies with TurnEnvironment::sandbox_context
// and exec_server_sandbox so local and remote launches use the same settings.
pub windows_sandbox_level: WindowsSandboxLevel,
pub windows_sandbox_private_desktop: bool,
pub permission_profile: PermissionProfile,
pub(crate) windows_sandbox_filesystem_overrides: Option<WindowsSandboxFilesystemOverrides>,
pub arg0: Option<String>,
@@ -86,7 +85,6 @@ impl ExecRequest {
sandbox: SandboxType,
windows_sandbox_workspace_roots: Vec<AbsolutePathBuf>,
windows_sandbox_level: WindowsSandboxLevel,
windows_sandbox_private_desktop: bool,
permission_profile: PermissionProfile,
arg0: Option<String>,
) -> Self {
@@ -106,7 +104,6 @@ impl ExecRequest {
windows_sandbox_policy_cwd,
windows_sandbox_workspace_roots,
windows_sandbox_level,
windows_sandbox_private_desktop,
permission_profile,
windows_sandbox_filesystem_overrides: None,
arg0,
@@ -131,7 +128,6 @@ impl ExecRequest {
network_environment_id,
sandbox,
windows_sandbox_level,
windows_sandbox_private_desktop,
permission_profile,
arg0,
..
@@ -195,7 +191,6 @@ impl ExecRequest {
windows_sandbox_policy_cwd,
windows_sandbox_workspace_roots,
windows_sandbox_level,
windows_sandbox_private_desktop,
permission_profile,
windows_sandbox_filesystem_overrides,
arg0,
-1
View File
@@ -841,7 +841,6 @@ impl Session {
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
windows_sandbox_type: config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: config.features.use_legacy_landlock(),
legacy_fallback_cwd: config.cwd.clone(),
runtime_workspace_roots: config.workspace_roots.clone(),
-2
View File
@@ -125,7 +125,6 @@ pub(crate) struct SessionConfiguration {
// internal sandbox decisions should use the selected environment's configuration.
pub(super) windows_sandbox_level: WindowsSandboxLevel,
pub(super) windows_sandbox_type: SandboxType,
pub(super) windows_sandbox_private_desktop: bool,
pub(super) use_legacy_landlock: bool,
/// Legacy thread cwd used when a turn does not select an environment.
@@ -180,7 +179,6 @@ impl SessionConfiguration {
shell_environment_policy: self.shell_environment_policy.clone(),
windows_sandbox_level: self.windows_sandbox_level,
windows_sandbox_type: self.windows_sandbox_type,
windows_sandbox_private_desktop: self.windows_sandbox_private_desktop,
use_legacy_landlock: self.use_legacy_landlock,
exec_policy: None,
mcp_policy: None,
-11
View File
@@ -4034,7 +4034,6 @@ async fn set_rate_limits_retains_previous_credits() {
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
windows_sandbox_type: config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: config.features.use_legacy_landlock(),
legacy_fallback_cwd: config.cwd.clone(),
runtime_workspace_roots: config.workspace_roots.clone(),
@@ -4157,7 +4156,6 @@ async fn set_rate_limits_updates_plan_type_when_present() {
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
windows_sandbox_type: config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: config.features.use_legacy_landlock(),
legacy_fallback_cwd: config.cwd.clone(),
runtime_workspace_roots: config.workspace_roots.clone(),
@@ -4777,7 +4775,6 @@ pub(crate) async fn make_session_configuration_for_tests() -> SessionConfigurati
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
windows_sandbox_type: config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: config.features.use_legacy_landlock(),
legacy_fallback_cwd: config.cwd.clone(),
runtime_workspace_roots: config.workspace_roots.clone(),
@@ -5864,7 +5861,6 @@ async fn session_new_fails_when_zsh_fork_enabled_without_packaged_zsh() {
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
windows_sandbox_type: config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: config.features.use_legacy_landlock(),
legacy_fallback_cwd: config.cwd.clone(),
runtime_workspace_roots: config.workspace_roots.clone(),
@@ -6046,7 +6042,6 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
windows_sandbox_type: config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: config.features.use_legacy_landlock(),
legacy_fallback_cwd: config.cwd.clone(),
runtime_workspace_roots: config.workspace_roots.clone(),
@@ -6362,7 +6357,6 @@ async fn make_session_with_config_and_rx(
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
windows_sandbox_type: config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: config.features.use_legacy_landlock(),
legacy_fallback_cwd: config.cwd.clone(),
runtime_workspace_roots: config.workspace_roots.clone(),
@@ -6495,7 +6489,6 @@ async fn make_session_with_history_source_and_agent_control_and_rx(
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
windows_sandbox_type: config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: config.features.use_legacy_landlock(),
legacy_fallback_cwd: config.cwd.clone(),
runtime_workspace_roots: config.workspace_roots.clone(),
@@ -8290,7 +8283,6 @@ where
shell_environment_policy: config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
windows_sandbox_type: config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: config.features.use_legacy_landlock(),
legacy_fallback_cwd: config.cwd.clone(),
runtime_workspace_roots: config.workspace_roots.clone(),
@@ -9113,7 +9105,6 @@ async fn capability_discovery_uses_environment_permission_profile() {
.set_permission_profile(PermissionProfile::Disabled)
.expect("unrestricted permission profile should be allowed");
config.permissions.windows_sandbox_mode = Some(WindowsSandboxModeToml::Unelevated);
config.permissions.windows_sandbox_private_desktop = true;
config
.features
.disable(Feature::UseLegacyLandlock)
@@ -9139,7 +9130,6 @@ async fn capability_discovery_uses_environment_permission_profile() {
NetworkSandboxPolicy::Restricted,
));
environment_config.windows_sandbox_level = WindowsSandboxLevel::Elevated;
environment_config.windows_sandbox_private_desktop = false;
environment_config.use_legacy_landlock = true;
let expected_sandbox = FileSystemSandboxContext {
permissions: environment.permission_profile().clone(),
@@ -9152,7 +9142,6 @@ async fn capability_discovery_uses_environment_permission_profile() {
} else {
codex_file_system::WindowsSandboxSelection::Disabled
},
windows_sandbox_private_desktop: false,
windows_sandbox_proxy_settings_mode: None,
use_legacy_landlock: true,
};
@@ -235,7 +235,6 @@ impl TurnEnvironment {
config.windows_sandbox_level,
self.cwd(),
),
windows_sandbox_private_desktop: config.windows_sandbox_private_desktop,
windows_sandbox_proxy_settings_mode: None,
use_legacy_landlock: config.use_legacy_landlock,
}
@@ -42,7 +42,6 @@ pub(crate) struct ShellSnapshotSandbox {
sandbox_exe: Option<PathBuf>,
use_legacy_landlock: bool,
windows_sandbox_level: WindowsSandboxLevel,
windows_sandbox_private_desktop: bool,
network: Option<NetworkProxy>,
environment_id: String,
additional_permissions: Option<AdditionalPermissionProfile>,
@@ -87,7 +86,6 @@ impl ShellSnapshotSandbox {
sandbox_exe: attempt.sandbox_exe.cloned(),
use_legacy_landlock: attempt.use_legacy_landlock,
windows_sandbox_level: attempt.windows_sandbox_level,
windows_sandbox_private_desktop: attempt.windows_sandbox_private_desktop,
network: attempt.network_proxy(network).cloned(),
environment_id: environment_id.to_string(),
additional_permissions: additional_permissions.cloned(),
@@ -106,7 +104,6 @@ impl ShellSnapshotSandbox {
&self.sandbox_exe,
self.use_legacy_landlock,
self.windows_sandbox_level,
self.windows_sandbox_private_desktop,
self.network
.as_ref()
.map(|network| (network.http_addr(), network.socks_addr())),
@@ -175,7 +172,6 @@ impl ShellSnapshotSandbox {
sandbox_exe: self.sandbox_exe.as_deref(),
use_legacy_landlock: self.use_legacy_landlock,
windows_sandbox_level: self.windows_sandbox_level,
windows_sandbox_private_desktop: self.windows_sandbox_private_desktop,
})
.context("failed to prepare shell snapshot sandbox")?;
let workspace_roots = self
@@ -46,7 +46,6 @@ async fn snapshot_failure_omits_credentials_and_stops_descendants(
use_legacy_landlock: false,
windows_sandbox_type: SandboxType::None,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
network_denial_cancellation_token: cancellation.clone(),
network_proxy: None,
};
@@ -301,7 +301,6 @@ async fn inactive_profiles_keep_snapshots_but_active_brokers_require_sandbox() -
workspace_roots: Vec::new(),
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_type: SandboxType::None,
windows_sandbox_private_desktop: true,
use_legacy_landlock: false,
permission_profile: PermissionProfileSnapshot::legacy(permission_profile),
shell_environment_policy: ShellEnvironmentPolicy::default(),
@@ -423,7 +422,6 @@ async fn inactive_profiles_keep_snapshots_but_active_brokers_require_sandbox() -
use_legacy_landlock: false,
windows_sandbox_type: SandboxType::None,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
network_denial_cancellation_token: Some(cancellation.clone()),
network_proxy: None,
};
-4
View File
@@ -226,10 +226,6 @@ pub(crate) async fn execute_user_shell_command(
windows_sandbox_policy_cwd: cwd.clone().into(),
windows_sandbox_workspace_roots: Vec::new(),
windows_sandbox_level: turn_context.windows_sandbox_level,
windows_sandbox_private_desktop: turn_context
.config
.permissions
.windows_sandbox_private_desktop,
permission_profile,
windows_sandbox_filesystem_overrides: None,
arg0: None,
@@ -1350,7 +1350,6 @@ async fn spawn_internal_session_preserves_parent_lineage_without_forking_history
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&config),
windows_sandbox_type: config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: config.features.use_legacy_landlock(),
exec_policy: Some(codex_execpolicy::RequirementsExecPolicy::new(
codex_execpolicy::Policy::empty(),
-3
View File
@@ -92,7 +92,6 @@ impl ToolOrchestrator {
use_legacy_landlock: attempt.use_legacy_landlock,
windows_sandbox_type: attempt.windows_sandbox_type,
windows_sandbox_level: attempt.windows_sandbox_level,
windows_sandbox_private_desktop: attempt.windows_sandbox_private_desktop,
network_denial_cancellation_token: network_approval
.as_ref()
.map(ActiveNetworkApproval::cancellation_token),
@@ -308,7 +307,6 @@ impl ToolOrchestrator {
use_legacy_landlock: sandbox_config.use_legacy_landlock,
windows_sandbox_type,
windows_sandbox_level: sandbox_config.windows_sandbox_level,
windows_sandbox_private_desktop: sandbox_config.windows_sandbox_private_desktop,
network_denial_cancellation_token: None,
network_proxy: None,
};
@@ -483,7 +481,6 @@ impl ToolOrchestrator {
use_legacy_landlock: sandbox_config.use_legacy_landlock,
windows_sandbox_type,
windows_sandbox_level: sandbox_config.windows_sandbox_level,
windows_sandbox_private_desktop: sandbox_config.windows_sandbox_private_desktop,
network_denial_cancellation_token: None,
network_proxy: None,
};
@@ -107,7 +107,6 @@ impl ApplyPatchRuntime {
attempt.windows_sandbox_level,
attempt.sandbox_cwd,
),
windows_sandbox_private_desktop: attempt.windows_sandbox_private_desktop,
windows_sandbox_proxy_settings_mode: None,
use_legacy_landlock: attempt.use_legacy_landlock,
})
@@ -30,7 +30,6 @@ fn test_turn_environment(environment_id: &str) -> crate::session::turn_context::
workspace_roots: Vec::new(),
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_type: SandboxType::None,
windows_sandbox_private_desktop: true,
use_legacy_landlock: false,
permission_profile: PermissionProfileSnapshot::legacy(
PermissionProfile::read_only(),
@@ -251,7 +250,6 @@ async fn file_system_sandbox_context_preserves_executor_workspace_permissions()
use_legacy_landlock: true,
windows_sandbox_type: SandboxType::WindowsRestrictedToken,
windows_sandbox_level: WindowsSandboxLevel::RestrictedToken,
windows_sandbox_private_desktop: true,
network_denial_cancellation_token: None,
network_proxy: None,
};
@@ -280,7 +278,6 @@ async fn file_system_sandbox_context_preserves_executor_workspace_permissions()
codex_file_system::WindowsSandboxSelection::Disabled
}
);
assert_eq!(sandbox.windows_sandbox_private_desktop, true);
assert_eq!(sandbox.use_legacy_landlock, true);
}
@@ -320,7 +317,6 @@ async fn file_system_sandbox_context_respects_sandbox_request() {
use_legacy_landlock: false,
windows_sandbox_type: SandboxType::None,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
network_denial_cancellation_token: None,
network_proxy: None,
};
@@ -352,7 +348,6 @@ async fn file_system_sandbox_context_respects_sandbox_request() {
user_home_dir: Some(user_home_dir),
temporary_directories: None,
windows_sandbox_selection: codex_file_system::WindowsSandboxSelection::RestrictedToken,
windows_sandbox_private_desktop: false,
windows_sandbox_proxy_settings_mode: None,
use_legacy_landlock: false,
})
@@ -131,7 +131,6 @@ async fn explicit_escalation_prepares_exec_without_managed_network() -> anyhow::
use_legacy_landlock: false,
windows_sandbox_type: SandboxType::None,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
network_denial_cancellation_token: None,
network_proxy: None,
};
@@ -764,7 +764,6 @@ mod tests {
workspace_roots: Vec::new(),
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_type: codex_sandboxing::SandboxType::None,
windows_sandbox_private_desktop: true,
use_legacy_landlock: false,
permission_profile: PermissionProfileSnapshot::legacy(
PermissionProfile::read_only(),
@@ -657,7 +657,6 @@ impl CoreShellCommandExecutor {
windows_sandbox_policy_cwd: self.sandbox_policy_cwd.clone().into(),
windows_sandbox_workspace_roots: self.windows_sandbox_workspace_roots.clone(),
windows_sandbox_level: self.windows_sandbox_level,
windows_sandbox_private_desktop: false,
permission_profile: self.permission_profile.clone(),
windows_sandbox_filesystem_overrides: None,
arg0: self.arg0.clone(),
@@ -796,7 +795,6 @@ impl CoreShellCommandExecutor {
sandbox_exe: self.codex_linux_sandbox_exe.as_deref(),
use_legacy_landlock: self.use_legacy_landlock,
windows_sandbox_level: self.windows_sandbox_level,
windows_sandbox_private_desktop: false,
})?;
let mut exec_request = crate::sandboxing::ExecRequest::from_sandbox_exec_request(
exec_request,
-4
View File
@@ -401,7 +401,6 @@ pub(crate) struct SandboxAttempt<'a> {
pub use_legacy_landlock: bool,
pub windows_sandbox_type: SandboxType,
pub windows_sandbox_level: codex_protocol::config_types::WindowsSandboxLevel,
pub windows_sandbox_private_desktop: bool,
pub network_denial_cancellation_token: Option<CancellationToken>,
pub(crate) network_proxy: Option<&'a NetworkProxy>,
}
@@ -494,7 +493,6 @@ impl<'a> SandboxAttempt<'a> {
sandbox_exe: self.sandbox_exe.map(std::path::PathBuf::as_path),
use_legacy_landlock: self.use_legacy_landlock,
windows_sandbox_level: self.windows_sandbox_level,
windows_sandbox_private_desktop: self.windows_sandbox_private_desktop,
})
.map_err(CodexErr::from)?;
let workspace_roots = self
@@ -529,7 +527,6 @@ impl<'a> SandboxAttempt<'a> {
sandbox_exe: None,
use_legacy_landlock: self.use_legacy_landlock,
windows_sandbox_level: self.windows_sandbox_level,
windows_sandbox_private_desktop: self.windows_sandbox_private_desktop,
})
.map_err(CodexErr::from)?;
let mut exec_request = crate::sandboxing::ExecRequest::from_sandbox_exec_request(
@@ -550,7 +547,6 @@ impl<'a> SandboxAttempt<'a> {
self.windows_sandbox_level,
self.sandbox_cwd,
),
windows_sandbox_private_desktop: self.windows_sandbox_private_desktop,
windows_sandbox_proxy_settings_mode: None,
use_legacy_landlock: self.use_legacy_landlock,
});
@@ -296,7 +296,6 @@ fn windows_sandbox_env_preserves_denied_reads_or_rejects_unsupported_backend() {
use_legacy_landlock: false,
windows_sandbox_type: SandboxType::WindowsRestrictedToken,
windows_sandbox_level: codex_protocol::config_types::WindowsSandboxLevel::Elevated,
windows_sandbox_private_desktop: false,
network_denial_cancellation_token: None,
network_proxy: None,
};
@@ -368,7 +367,6 @@ fn exec_server_env_keeps_command_native_and_carries_sandbox_context() {
use_legacy_landlock: false,
windows_sandbox_type: SandboxType::None,
windows_sandbox_level: codex_protocol::config_types::WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
network_denial_cancellation_token: None,
network_proxy: None,
};
@@ -417,7 +415,6 @@ fn exec_server_env_keeps_command_native_and_carries_sandbox_context() {
} else {
codex_file_system::WindowsSandboxSelection::Disabled
},
windows_sandbox_private_desktop: false,
windows_sandbox_proxy_settings_mode: None,
use_legacy_landlock: false,
})
@@ -1257,10 +1257,6 @@ async fn zsh_fork_unified_exec_keeps_shell_parameter_when_remote_environment_ava
workspace_roots: Vec::new(),
windows_sandbox_level: turn.windows_sandbox_level,
windows_sandbox_type: turn.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: turn
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: turn.config.features.use_legacy_landlock(),
permission_profile: turn
.config
@@ -68,7 +68,6 @@ fn test_exec_request(
cwd: AbsolutePathBuf,
env: HashMap<String, String>,
) -> ExecRequest {
let windows_sandbox_private_desktop = false;
let permission_profile = turn.permission_profile();
let network = None;
let arg0 = None;
@@ -88,7 +87,6 @@ fn test_exec_request(
.collect::<std::io::Result<Vec<_>>>()
.expect("test workspace roots are host-native"),
turn.windows_sandbox_level,
windows_sandbox_private_desktop,
permission_profile,
arg0,
)
@@ -1408,7 +1408,6 @@ impl UnifiedExecProcessManager {
network_proxy_restricting_sid: network_proxy_restricting_sid.as_deref(),
proxy_settings_mode: windows_sandbox_proxy_settings_mode,
filesystem_overrides: request.windows_sandbox_filesystem_overrides.as_ref(),
use_private_desktop: request.windows_sandbox_private_desktop,
})
} else {
None
@@ -228,7 +228,6 @@ fn exec_server_params_use_path_uri_and_env_policy_overlay_contract() {
windows_sandbox_policy_cwd: cwd.clone().into(),
windows_sandbox_workspace_roots: vec![cwd],
windows_sandbox_level: codex_protocol::config_types::WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
permission_profile: permission_profile.clone(),
windows_sandbox_filesystem_overrides: None,
arg0: None,
@@ -102,9 +102,6 @@ impl Session {
environment.config().windows_sandbox_level,
environment.cwd(),
),
windows_sandbox_private_desktop: environment
.config()
.windows_sandbox_private_desktop,
windows_sandbox_proxy_settings_mode: Some(
session.windows_sandbox_proxy_settings_mode,
),
-7
View File
@@ -87,13 +87,6 @@ pub fn resolve_windows_sandbox_mode(cfg: &ConfigToml) -> Option<WindowsSandboxMo
.or_else(|| legacy_windows_sandbox_mode(cfg.features.as_ref()))
}
pub fn resolve_windows_sandbox_private_desktop(cfg: &ConfigToml) -> bool {
cfg.windows
.as_ref()
.and_then(|windows| windows.sandbox_private_desktop)
.unwrap_or_else(|| resolve_windows_sandbox_mode(cfg) != Some(WindowsSandboxModeToml::Mxc))
}
pub fn legacy_windows_sandbox_mode(
features: Option<&FeaturesToml>,
) -> Option<WindowsSandboxModeToml> {
@@ -1,5 +1,4 @@
use super::*;
use codex_config::types::WindowsToml;
use codex_features::Features;
use codex_features::FeaturesToml;
use codex_network_proxy::NetworkProxyConfig;
@@ -98,26 +97,6 @@ fn resolve_windows_sandbox_mode_falls_back_to_legacy_keys() {
);
}
#[test]
fn resolve_windows_sandbox_private_desktop_defaults_to_true() {
assert!(resolve_windows_sandbox_private_desktop(
&ConfigToml::default()
));
}
#[test]
fn resolve_windows_sandbox_private_desktop_respects_explicit_cfg_value() {
let cfg = ConfigToml {
windows: Some(WindowsToml {
sandbox_private_desktop: Some(false),
..Default::default()
}),
..Default::default()
};
assert!(!resolve_windows_sandbox_private_desktop(&cfg));
}
#[test]
fn provisioning_settings_omit_the_disabled_socks_proxy() {
let config = NetworkProxyConfig {
@@ -386,10 +386,6 @@ async fn v2_residency_reload_preserves_inherited_environment_and_tools(
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
-1
View File
@@ -44,7 +44,6 @@ where
network_environment_id: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
justification: None,
arg0: None,
};
-12
View File
@@ -721,10 +721,6 @@ async fn environment_command_restrictions_override_saved_prefix_approvals() -> R
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: Some(RequirementsExecPolicy::new(invalid_policy)),
mcp_policy: None,
@@ -752,10 +748,6 @@ async fn environment_command_restrictions_override_saved_prefix_approvals() -> R
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: Some(RequirementsExecPolicy::new(environment_policy)),
mcp_policy: None,
@@ -864,10 +856,6 @@ async fn environment_command_policy_changes_invalidate_session_approvals() -> Re
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: Some(RequirementsExecPolicy::new(policy)),
mcp_policy: None,
@@ -1643,7 +1643,6 @@ async fn guardian_session_is_reused_for_consecutive_tool_reviews_without_prewarm
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test.config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
@@ -866,11 +866,6 @@ impl ExecutorHookFixture {
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&self.test.config),
windows_sandbox_type: self.test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: self
.test
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: self.test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
@@ -367,7 +367,6 @@ async fn skill_mcp_dependency_oauth_uses_configured_http_client() -> Result<()>
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&fixture.config),
windows_sandbox_type: fixture.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: fixture.config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: fixture.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: Some(EnvironmentMcpPolicy {
@@ -498,10 +498,6 @@ async fn root_reconciliation_reuses_pending_apps_startup() -> Result<()> {
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
@@ -2494,10 +2494,6 @@ async fn owner_network_policy_follows_the_selected_remote_command() -> Result<()
shell_environment_policy: test.config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
@@ -2680,7 +2676,6 @@ async fn escalated_owner_network_terminal_requires_stdin_approval(
shell_environment_policy: test.config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test.config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
-27
View File
@@ -599,10 +599,6 @@ async fn environment_permissions_follow_configuration_ownership() -> Result<()>
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
@@ -1464,10 +1460,6 @@ async fn shared_executor_keeps_ready_capability_roots_scoped_to_each_attachment(
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
@@ -1510,10 +1502,6 @@ async fn shared_executor_keeps_ready_capability_roots_scoped_to_each_attachment(
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
@@ -1540,10 +1528,6 @@ async fn shared_executor_keeps_ready_capability_roots_scoped_to_each_attachment(
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
@@ -1605,10 +1589,6 @@ async fn shared_executor_keeps_ready_capability_roots_scoped_to_each_attachment(
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
@@ -1686,7 +1666,6 @@ async fn owner_network_policy_rejects_unsupported_environment_authority() -> Res
shell_environment_policy: test.config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test.config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
@@ -1776,7 +1755,6 @@ async fn pending_attachment_installs_configuration_before_waiting_turn_resumes()
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test.config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
@@ -2022,7 +2000,6 @@ async fn future_pending_environment_can_finish_without_retargeting_the_active_tu
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test.config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
@@ -2585,10 +2562,6 @@ async fn deferred_executor_spawn_agent_inherits_ready_step_environments(
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
-9
View File
@@ -834,10 +834,6 @@ async fn environment_mcp_policy_filters_runtime_config_and_model_tools(
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&fixture.config),
windows_sandbox_type: fixture.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: fixture
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: fixture.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: Some(mcp_policy),
@@ -955,7 +951,6 @@ async fn future_environment_mcp_policy_applies_on_the_next_turn() -> anyhow::Res
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&fixture.config),
windows_sandbox_type: fixture.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: fixture.config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: fixture.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: Some(EnvironmentMcpPolicy {
@@ -2051,10 +2046,6 @@ async fn stdio_mcp_tool_call_includes_sandbox_state_meta(
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&fixture.config),
windows_sandbox_type: fixture.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: fixture
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: fixture.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
@@ -701,7 +701,6 @@ async fn shell_snapshot_v2_guardian_uses_its_resolved_permissions_and_tools(
shell_environment_policy: test.config.permissions.shell_environment_policy.clone(),
windows_sandbox_level: WindowsSandboxLevel::from_config(&test.config),
windows_sandbox_type: test.config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: test.config.permissions.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
@@ -506,11 +506,6 @@ async fn exec_command_uses_installed_environment_shell_policy_with_explicit_over
},
windows_sandbox_level: WindowsSandboxLevel::from_config(&harness.test().config),
windows_sandbox_type: harness.test().config.permissions.windows_sandbox_type,
windows_sandbox_private_desktop: harness
.test()
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: harness.test().config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
@@ -367,7 +367,6 @@ async fn windows_restricted_token_rejects_exact_and_glob_deny_read_policy() -> a
network_environment_id: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level: WindowsSandboxLevel::RestrictedToken,
windows_sandbox_private_desktop: false,
justification: None,
arg0: None,
},
@@ -417,7 +416,6 @@ async fn windows_elevated_does_not_create_missing_workspace_metadata() -> anyhow
network_environment_id: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level: WindowsSandboxLevel::Elevated,
windows_sandbox_private_desktop: false,
justification: None,
arg0: None,
},
@@ -597,7 +595,6 @@ async fn windows_elevated_enforces_deny_read_and_protects_setup_marker() -> anyh
network_environment_id: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level: WindowsSandboxLevel::Elevated,
windows_sandbox_private_desktop: false,
justification: None,
arg0: None,
},
@@ -279,10 +279,6 @@ async fn workspace_roots_allow_file_and_command_writes_in_secondary_root(
shell_environment_policy: Default::default(),
windows_sandbox_level: WindowsSandboxLevel::RestrictedToken,
windows_sandbox_type: SandboxType::WindowsRestrictedToken,
windows_sandbox_private_desktop: test
.config
.permissions
.windows_sandbox_private_desktop,
use_legacy_landlock: test.config.features.use_legacy_landlock(),
exec_policy: None,
mcp_policy: None,
+1 -3
View File
@@ -197,8 +197,6 @@ impl FileSystemSandboxRunner {
use_legacy_landlock: sandbox_context.use_legacy_landlock,
windows_sandbox_level: windows_sandbox_level
.unwrap_or(WindowsSandboxLevel::Disabled),
windows_sandbox_private_desktop: sandbox_context
.windows_sandbox_private_desktop,
},
})
.map_err(|err| invalid_request(format!("failed to prepare fs sandbox: {err}")))
@@ -885,7 +883,7 @@ mod tests {
),
]);
let sandbox_context = crate::FileSystemSandboxContext {
windows_sandbox_selection: codex_file_system::WindowsSandboxSelection::Elevated,
windows_sandbox_selection: codex_file_system::WindowsSandboxSelection::RestrictedToken,
..sandbox_context_with_cwd(&policy, cwd_uri)
};
selected.close().expect("remove selected directory");
@@ -254,7 +254,6 @@ fn powershell_command(script: &str, path: &Path) -> anyhow::Result<SandboxExecRe
network_environment_id: None,
sandbox: SandboxType::None,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
permission_profile: PermissionProfile::Disabled,
arg0: None,
})
+2 -6
View File
@@ -59,7 +59,6 @@ struct PreparedWindowsSandboxRequest {
network_proxy_restricting_sid: Option<String>,
proxy_settings_mode: WindowsSandboxProxySettingsMode,
filesystem_overrides: Option<WindowsSandboxFilesystemOverrides>,
use_private_desktop: bool,
}
impl PreparedExecRequest {
@@ -74,7 +73,6 @@ impl PreparedExecRequest {
network_proxy_restricting_sid: request.network_proxy_restricting_sid.as_deref(),
proxy_settings_mode: request.proxy_settings_mode,
filesystem_overrides: request.filesystem_overrides.as_ref(),
use_private_desktop: request.use_private_desktop,
})
}
}
@@ -90,9 +88,9 @@ pub(crate) async fn prepare_exec_request_with_telemetry(
if let Some(sandbox) = params.sandbox.as_ref()
&& sandbox.windows_sandbox_selection == WindowsSandboxSelection::Mxc
{
if params.arg0.is_some() || sandbox.windows_sandbox_private_desktop {
if params.arg0.is_some() {
return Err(invalid_params(
"MXC custom argv0 and private-desktop launches are not supported".to_owned(),
"MXC custom argv0 is not supported".to_owned(),
));
}
if !codex_sandboxing::windows_mxc_available() {
@@ -271,7 +269,6 @@ pub(crate) async fn prepare_exec_request_with_telemetry(
},
use_legacy_landlock: sandbox_context.use_legacy_landlock,
windows_sandbox_level: windows_sandbox_level.unwrap_or(WindowsSandboxLevel::Disabled),
windows_sandbox_private_desktop: sandbox_context.windows_sandbox_private_desktop,
},
};
let mut request = if sandbox == SandboxType::WindowsRestrictedToken {
@@ -312,7 +309,6 @@ pub(crate) async fn prepare_exec_request_with_telemetry(
network_proxy_restricting_sid,
proxy_settings_mode: windows_sandbox_proxy_settings_mode,
filesystem_overrides,
use_private_desktop: sandbox_context.windows_sandbox_private_desktop,
})
} else {
None
@@ -569,8 +569,7 @@ async fn file_system_private_desktop_survives_helper_exits_and_separates_permiss
let path = tmp.path().join("contents.txt");
std::fs::write(&path, b"initial")?;
let uri = PathUri::from_host_native_path(&path)?;
let mut sandbox = workspace_write_sandbox(tmp.path().to_path_buf());
sandbox.windows_sandbox_private_desktop = true;
let sandbox = workspace_write_sandbox(tmp.path().to_path_buf());
let before = process_private_desktops()?;
let write = file_system
.write_file(
@@ -624,7 +623,6 @@ async fn file_system_private_desktop_survives_helper_exits_and_separates_permiss
let mut readonly = read_only_sandbox_for_cwd(tmp.path().to_path_buf())?;
readonly.windows_sandbox_selection = WindowsSandboxSelection::RestrictedToken;
readonly.windows_sandbox_private_desktop = true;
file_system
.write_file(
&uri,
-1
View File
@@ -45,7 +45,6 @@ pub(super) async fn spawn_command_under_sandbox(
network_environment_id: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
justification: None,
arg0: None,
},
-8
View File
@@ -362,8 +362,6 @@ pub struct FileSystemSandboxContext {
pub temporary_directories: Option<Vec<PathUri>>,
#[serde(rename = "windowsSandboxLevel")]
pub windows_sandbox_selection: WindowsSandboxSelection,
#[serde(default)]
pub windows_sandbox_private_desktop: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub windows_sandbox_proxy_settings_mode: Option<WindowsSandboxProxySettingsMode>,
#[serde(default)]
@@ -399,7 +397,6 @@ impl FileSystemSandboxContext {
user_home_dir: None,
temporary_directories: None,
windows_sandbox_selection: WindowsSandboxSelection::Disabled,
windows_sandbox_private_desktop: false,
windows_sandbox_proxy_settings_mode: None,
use_legacy_landlock: false,
}
@@ -476,8 +473,6 @@ pub struct WireFileSystemSandboxContext {
temporary_directories: Option<Vec<PathUri>>,
#[serde(rename = "windowsSandboxLevel")]
windows_sandbox_selection: WindowsSandboxSelection,
#[serde(default)]
windows_sandbox_private_desktop: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
windows_sandbox_proxy_settings_mode: Option<WindowsSandboxProxySettingsMode>,
#[serde(default)]
@@ -503,7 +498,6 @@ impl From<FileSystemSandboxContext> for WireFileSystemSandboxContext {
user_home_dir,
temporary_directories,
windows_sandbox_selection,
windows_sandbox_private_desktop,
windows_sandbox_proxy_settings_mode,
use_legacy_landlock,
} = sandbox;
@@ -548,7 +542,6 @@ impl From<FileSystemSandboxContext> for WireFileSystemSandboxContext {
user_home_dir,
temporary_directories,
windows_sandbox_selection,
windows_sandbox_private_desktop,
windows_sandbox_proxy_settings_mode,
use_legacy_landlock,
}
@@ -595,7 +588,6 @@ impl WireFileSystemSandboxContext {
user_home_dir: self.user_home_dir,
temporary_directories: self.temporary_directories,
windows_sandbox_selection: self.windows_sandbox_selection,
windows_sandbox_private_desktop: self.windows_sandbox_private_desktop,
windows_sandbox_proxy_settings_mode: self.windows_sandbox_proxy_settings_mode,
use_legacy_landlock: self.use_legacy_landlock,
}
@@ -186,7 +186,6 @@ async fn run_cmd_result_with_permission_profile_for_cwd(
network_environment_id: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
justification: None,
arg0: None,
};
@@ -825,7 +824,6 @@ async fn assert_network_blocked(cmd: &[&str]) {
network_environment_id: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
justification: None,
arg0: None,
};
@@ -452,9 +452,7 @@ fn run_restricted_child_blocking(
/*logs_base_dir*/ None,
/*stdio*/ None,
/*console_mode*/ ConsoleMode::Inherit,
LaunchDesktop::prepare(
/*use_private_desktop*/ false, /*logs_base_dir*/ None,
)?,
LaunchDesktop::prepare(/*logs_base_dir*/ None)?,
)?
};
let process = unsafe {
-6
View File
@@ -69,8 +69,6 @@ pub struct EnvironmentConfig {
pub windows_sandbox_level: WindowsSandboxLevel,
/// Concrete Windows sandbox backend selected for this environment attachment.
pub windows_sandbox_type: SandboxType,
/// Whether Windows sandbox processes use a private desktop.
pub windows_sandbox_private_desktop: bool,
/// Whether Linux sandbox processes use the legacy Landlock backend.
pub use_legacy_landlock: bool,
/// Additional managed command restrictions for this environment attachment.
@@ -93,10 +91,6 @@ impl std::fmt::Debug for EnvironmentConfig {
.field("shell_environment_policy", &"<redacted>")
.field("windows_sandbox_level", &self.windows_sandbox_level)
.field("windows_sandbox_type", &self.windows_sandbox_type)
.field(
"windows_sandbox_private_desktop",
&self.windows_sandbox_private_desktop,
)
.field("use_legacy_landlock", &self.use_legacy_landlock)
.field("exec_policy", &self.exec_policy)
.field("mcp_policy", &self.mcp_policy)
-24
View File
@@ -108,7 +108,6 @@ pub struct SandboxExecRequest {
// TODO(anp): Reconcile these backend copies with the supplied sandbox context
// (TurnEnvironment::sandbox_context for turns), preserving this launch snapshot.
pub windows_sandbox_level: WindowsSandboxLevel,
pub windows_sandbox_private_desktop: bool,
pub permission_profile: PermissionProfile,
pub arg0: Option<String>,
}
@@ -131,7 +130,6 @@ pub struct SandboxTransformRequest<'a> {
// (TurnEnvironment::sandbox_context for turns) so selection shares its authority.
pub use_legacy_landlock: bool,
pub windows_sandbox_level: WindowsSandboxLevel,
pub windows_sandbox_private_desktop: bool,
}
/// Bundled arguments for a sandbox transformation whose result will be spawned
@@ -357,7 +355,6 @@ impl SandboxManager {
sandbox_exe,
use_legacy_landlock,
windows_sandbox_level,
windows_sandbox_private_desktop,
} = request;
#[cfg(target_os = "macos")]
let managed_network = command.managed_network.as_ref();
@@ -379,11 +376,6 @@ impl SandboxManager {
let (argv, arg0_override, pending_sandboxed_request) = match sandbox {
SandboxType::None => (argv, None, None),
SandboxType::WindowsMxc => {
if windows_sandbox_private_desktop {
return Err(SandboxTransformError::WindowsMxcPreparation(
"private desktop isolation is not supported by MXC".to_string(),
));
}
if !codex_mxc_sandbox::is_available() {
return Err(SandboxTransformError::WindowsMxcPreparation(
"native MXC is unavailable on this executor".to_string(),
@@ -527,20 +519,6 @@ impl SandboxManager {
));
}
let pending = pending_sandboxed_request?;
if let Some(metrics) = codex_otel::global() {
let _ = metrics.counter(
"codex.windows_sandbox.private_desktop",
/*inc*/ 1,
&[(
"enabled",
if windows_sandbox_private_desktop {
"true"
} else {
"false"
},
)],
);
}
(argv, None, Some(pending))
}
#[cfg(not(target_os = "windows"))]
@@ -564,7 +542,6 @@ impl SandboxManager {
network_environment_id: environment_id.map(str::to_string),
sandbox,
windows_sandbox_level,
windows_sandbox_private_desktop,
permission_profile,
arg0: arg0_override,
})
@@ -691,7 +668,6 @@ fn wrap_windows_sandbox_exec_request_for_direct_spawn(
&request.env,
&request.permission_profile,
request.windows_sandbox_level,
request.windows_sandbox_private_desktop,
proxy_enforced,
network_proxy_restricting_sid.as_deref(),
proxy_settings_mode,
+3 -10
View File
@@ -123,7 +123,6 @@ fn unsandboxed_transform_preserves_foreign_cwd_and_unrestricted_file_system_poli
sandbox_exe: None,
use_legacy_landlock: false,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
})
.expect("transform");
@@ -180,7 +179,6 @@ fn symlinked_workspace_reports_seatbelt_preparation_error() {
sandbox_exe: None,
use_legacy_landlock: false,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
})
.expect_err("symlinked workspace should be rejected");
@@ -235,7 +233,6 @@ fn transform_additional_permissions_enable_network_for_external_sandbox() {
sandbox_exe: None,
use_legacy_landlock: false,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
})
.expect("transform");
@@ -306,7 +303,6 @@ fn transform_additional_permissions_preserves_denied_entries() {
sandbox_exe: None,
use_legacy_landlock: false,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
})
.expect("transform");
@@ -408,7 +404,6 @@ fn transform_linux_seccomp_request(
sandbox_exe: Some(codex_linux_sandbox_exe),
use_legacy_landlock: false,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
})
.expect("transform")
}
@@ -618,7 +613,6 @@ async fn linux_unix_socket_grant_uses_effective_managed_policy() -> anyhow::Resu
sandbox_exe: Some(std::path::Path::new("/tmp/codex-linux-sandbox")),
use_legacy_landlock: false,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false,
})?;
let transported_context = request
.command
@@ -720,7 +714,7 @@ fn transform_for_direct_spawn_windows_materializes_inner_helper() {
},
FileSystemSandboxEntry {
path: blocked.into(),
access: FileSystemAccessMode::Deny,
access: FileSystemAccessMode::Read,
missing_path_behavior: None,
},
]),
@@ -757,8 +751,7 @@ fn transform_for_direct_spawn_windows_materializes_inner_helper() {
sandbox_policy_cwd: &cwd_uri,
sandbox_exe: None,
use_legacy_landlock: false,
windows_sandbox_level: WindowsSandboxLevel::Elevated,
windows_sandbox_private_desktop: false,
windows_sandbox_level: WindowsSandboxLevel::RestrictedToken,
},
},
codex_home.path(),
@@ -803,7 +796,7 @@ fn transform_for_direct_spawn_windows_materializes_inner_helper() {
exec_request
.command
.iter()
.any(|arg| arg == "--deny-read-paths-json")
.any(|arg| arg == "--deny-write-paths-json")
);
assert_eq!(
exec_request.command[separator_index + 2],
+1 -3
View File
@@ -15,7 +15,7 @@ use crate::WindowsSandboxProxySettingsMode;
use crate::terminal_queries::respond_to_terminal_queries;
/// Windows-specific inputs for an executor-native process spawn.
// TODO(anp): Reconcile Windows backend and desktop copies with the supplied sandbox
// TODO(anp): Reconcile the Windows backend copy with the supplied sandbox
// context (TurnEnvironment::sandbox_context for turns), preserving this launch snapshot.
pub struct WindowsSandboxSpawnRequest<'a> {
pub permission_profile: &'a PermissionProfile,
@@ -25,7 +25,6 @@ pub struct WindowsSandboxSpawnRequest<'a> {
pub network_proxy_restricting_sid: Option<&'a str>,
pub proxy_settings_mode: WindowsSandboxProxySettingsMode,
pub filesystem_overrides: Option<&'a WindowsSandboxFilesystemOverrides>,
pub use_private_desktop: bool,
}
/// Executor-native process launch request shared by local and exec-server execution.
@@ -92,7 +91,6 @@ pub async fn spawn_process(request: SpawnRequest<'_>) -> Result<SpawnedProcess>
}),
tty: request.tty,
stdin_open: request.stdin_open,
use_private_desktop: windows.use_private_desktop,
},
)
.await
-13
View File
@@ -206,14 +206,6 @@ fn render_debug_config_lines(
));
}
if let Some(sandbox_private_desktop) = requirements.windows_sandbox_private_desktop.as_ref() {
requirement_lines.push(requirement_line(
"windows.sandbox_private_desktop",
sandbox_private_desktop.value.to_string(),
Some(&sandbox_private_desktop.source),
));
}
if let Some(policies) = requirements_toml.allowed_approval_policies.as_ref() {
let value = join_or_empty(policies.iter().map(ToString::to_string).collect::<Vec<_>>());
requirement_lines.push(requirement_line(
@@ -865,10 +857,6 @@ interrupt_message = false
},
RequirementSource::LegacyManagedConfigTomlFromMdm,
)),
windows_sandbox_private_desktop: Some(Sourced::new(
/*value*/ false,
RequirementSource::LegacyManagedConfigTomlFromMdm,
)),
approval_policy: ConstrainedWithSource::new(
Constrained::allow_any(AskForApproval::OnRequest.to_core()),
Some(RequirementSource::LegacyManagedConfigTomlFromMdm),
@@ -986,7 +974,6 @@ interrupt_message = false
in_app_browser: None,
windows: Some(WindowsRequirementsToml {
allowed_sandbox_implementations: None,
sandbox_private_desktop: Some(false),
}),
additional_developer_instructions: None,
guardian_policy_config: Some("Use the managed guardian policy.".to_string()),
@@ -14,7 +14,6 @@ Requirements:
- check_for_update_on_startup: false (source: MDM managed_config.toml (legacy))
- allow_login_shell: false (source: MDM managed_config.toml (legacy))
- feedback.enabled: false (source: MDM managed_config.toml (legacy))
- windows.sandbox_private_desktop: false (source: MDM managed_config.toml (legacy))
- allowed_approval_policies: on-request (source: MDM managed_config.toml (legacy))
- allowed_approvals_reviewers: auto_review (source: MDM managed_config.toml (legacy))
- allowed_sandbox_modes: read-only (source: /etc/codex/requirements.toml)
@@ -296,15 +296,11 @@ fn spawn_ipc_process(req: &SpawnRequest) -> Result<IpcSpawnedProcess> {
}
let effective_cwd = effective_cwd(&req.cwd, Some(log_dir.as_path()));
let desktop = if req.use_private_desktop {
LaunchDesktop::open_private(
req.private_desktop_name
.as_deref()
.context("runner: missing parent-owned private desktop")?,
)?
} else {
LaunchDesktop::prepare(/*use_private_desktop*/ false, Some(log_dir.as_path()))?
};
let desktop = LaunchDesktop::open_private(
req.private_desktop_name
.as_deref()
.context("runner: missing parent-owned private desktop")?,
)?;
let mut conpty_owner = None;
let mut hpc_handle: Option<HANDLE> = None;
@@ -135,7 +135,6 @@ fn protected_directory_does_not_discard_accessible_deny_matches() {
env,
/*timeout_ms*/ Some(30_000),
/*cancellation*/ None,
/*use_private_desktop*/ true,
)
.expect("run protected-directory regression without backup privileges");
let stdout = String::from_utf8_lossy(&result.stdout);
+10 -21
View File
@@ -145,13 +145,12 @@ impl DesktopPolicy {
}
pub struct LaunchDesktop {
_private_desktop: Option<PrivateDesktop>,
_private_desktop: PrivateDesktop,
startup_name: Vec<u16>,
}
impl LaunchDesktop {
pub(crate) fn prepare_legacy(
use_private_desktop: bool,
permissions: &ResolvedWindowsSandboxPermissions,
cwd: &Path,
env: &HashMap<String, String>,
@@ -159,9 +158,6 @@ impl LaunchDesktop {
additional_deny_write_paths: &[PathBuf],
logs_base_dir: Option<&Path>,
) -> Result<Self> {
if !use_private_desktop {
return Self::prepare(/*use_private_desktop*/ false, logs_base_dir);
}
Self::open_private(&Self::shared_legacy_name(
permissions,
cwd,
@@ -216,20 +212,13 @@ impl LaunchDesktop {
Ok(desktop.name.clone())
}
pub fn prepare(use_private_desktop: bool, logs_base_dir: Option<&Path>) -> Result<Self> {
if use_private_desktop {
let private_desktop = PrivateDesktop::create(logs_base_dir)?;
let startup_name = to_wide(format!("Winsta0\\{}", private_desktop.name));
Ok(Self {
_private_desktop: Some(private_desktop),
startup_name,
})
} else {
Ok(Self {
_private_desktop: None,
startup_name: to_wide("Winsta0\\Default"),
})
}
pub fn prepare(logs_base_dir: Option<&Path>) -> Result<Self> {
let private_desktop = PrivateDesktop::create(logs_base_dir)?;
let startup_name = to_wide(format!("Winsta0\\{}", private_desktop.name));
Ok(Self {
_private_desktop: private_desktop,
startup_name,
})
}
/// Opens the caller-owned private desktop without creating one or falling back to Default.
@@ -257,10 +246,10 @@ impl LaunchDesktop {
anyhow::bail!("OpenDesktopW failed: {}", unsafe { GetLastError() });
}
Ok(Self {
_private_desktop: Some(PrivateDesktop {
_private_desktop: PrivateDesktop {
handle,
name: name.to_owned(),
}),
},
startup_name: to_wide(format!("Winsta0\\{name}")),
})
}
@@ -198,7 +198,6 @@ fn legacy_desktop_reuses_only_equivalent_permissions() -> Result<()> {
let _token = unsafe { OwnedHandle::from_raw_handle(security.h_token as *mut _) };
let desktop = |deny_write_paths| {
LaunchDesktop::prepare_legacy(
/*use_private_desktop*/ true,
&permissions,
&workspace,
&env,
@@ -66,8 +66,6 @@ pub struct SpawnRequest {
pub tty: bool,
#[serde(default)]
pub stdin_open: bool,
#[serde(default)]
pub use_private_desktop: bool,
/// Private desktop kept alive by the parent across command runners.
pub private_desktop_name: Option<String>,
}
@@ -206,7 +204,6 @@ mod tests {
timeout_ms: Some(1000),
tty: false,
stdin_open: false,
use_private_desktop: true,
private_desktop_name: Some("CodexSandboxDesktop-1234".to_string()),
}),
},
@@ -13,9 +13,6 @@ pub struct ElevatedSandboxProfileCaptureRequest<'a> {
pub env_map: HashMap<String, String>,
pub timeout_ms: Option<u64>,
pub cancellation: Option<crate::WindowsSandboxCancellationToken>,
// TODO(anp): Reconcile this private-desktop copy with the supplied sandbox context
// (TurnEnvironment::sandbox_context for turns), preserving this launch snapshot.
pub use_private_desktop: bool,
pub proxy_enforced: bool,
pub network_proxy_restricting_sid: Option<String>,
pub read_roots_override: Option<&'a [PathBuf]>,
@@ -112,7 +109,6 @@ mod windows_impl {
mut env_map,
timeout_ms,
cancellation,
use_private_desktop,
proxy_enforced,
network_proxy_restricting_sid,
read_roots_override,
@@ -186,28 +182,24 @@ mod windows_impl {
}
(|| -> Result<CaptureResult> {
let desktop_policy = use_private_desktop
.then(|| {
crate::desktop::DesktopPolicy::elevated(
crate::setup::SandboxSetupRequest {
permissions: &permissions,
command_cwd: cwd,
env_map: &env_map,
codex_home,
proxy_enforced,
},
crate::setup::SetupRootOverrides {
read_roots: read_roots_override.map(<[PathBuf]>::to_vec),
read_roots_include_platform_defaults,
write_roots: write_roots_override.map(<[PathBuf]>::to_vec),
deny_read_paths: Some(deny_read_paths_override.clone()),
deny_write_paths: Some(deny_write_paths_override.clone()),
},
&cap_sids,
network_proxy_restricting_sid.as_deref(),
)
})
.transpose()?;
let desktop_policy = crate::desktop::DesktopPolicy::elevated(
crate::setup::SandboxSetupRequest {
permissions: &permissions,
command_cwd: cwd,
env_map: &env_map,
codex_home,
proxy_enforced,
},
crate::setup::SetupRootOverrides {
read_roots: read_roots_override.map(<[PathBuf]>::to_vec),
read_roots_include_platform_defaults,
write_roots: write_roots_override.map(<[PathBuf]>::to_vec),
deny_read_paths: Some(deny_read_paths_override.clone()),
deny_write_paths: Some(deny_write_paths_override.clone()),
},
&cap_sids,
network_proxy_restricting_sid.as_deref(),
)?;
let spawn_request = SpawnRequest {
command: command.clone(),
cwd: cwd.to_path_buf(),
@@ -221,7 +213,6 @@ mod windows_impl {
timeout_ms,
tty: false,
stdin_open: false,
use_private_desktop,
private_desktop_name: None,
};
let transport = retry_runner_spawn_once(
@@ -234,7 +225,7 @@ mod windows_impl {
&sandbox_creds,
logs_base_dir,
spawn_request.clone(),
desktop_policy.as_ref(),
Some(&desktop_policy),
)
},
|| {
-5
View File
@@ -659,7 +659,6 @@ mod windows_impl {
env_map: HashMap<String, String>,
timeout_ms: Option<u64>,
cancellation: Option<WindowsSandboxCancellationToken>,
use_private_desktop: bool,
) -> Result<CaptureResult> {
run_windows_sandbox_capture_with_filesystem_overrides(
permission_profile,
@@ -672,7 +671,6 @@ mod windows_impl {
cancellation,
&[],
&[],
use_private_desktop,
)
}
@@ -688,7 +686,6 @@ mod windows_impl {
cancellation: Option<WindowsSandboxCancellationToken>,
additional_deny_read_paths: &[AbsolutePathBuf],
additional_deny_write_paths: &[AbsolutePathBuf],
use_private_desktop: bool,
) -> Result<CaptureResult> {
let additional_deny_read_paths = additional_deny_read_paths
.iter()
@@ -749,7 +746,6 @@ mod windows_impl {
let (stdin_pair, stdout_pair, stderr_pair) = unsafe { setup_stdio_pipes()? };
let ((in_r, in_w), (out_r, out_w), (err_r, err_w)) = (stdin_pair, stdout_pair, stderr_pair);
let spawn_res = crate::LaunchDesktop::prepare_legacy(
use_private_desktop,
&permissions,
&current_dir,
&env_map,
@@ -1041,7 +1037,6 @@ mod stub {
_env_map: HashMap<String, String>,
_timeout_ms: Option<u64>,
_cancellation: Option<WindowsSandboxCancellationToken>,
_use_private_desktop: bool,
) -> Result<CaptureResult> {
bail!("Windows sandbox is only available on Windows")
}
@@ -97,33 +97,35 @@ async fn spawn_runner_transport_task(
request: RunnerTransportRequest,
) -> Result<RunnerTransport> {
tokio::task::spawn_blocking(move || -> Result<_> {
let desktop_policy = (request.spawn_request.use_private_desktop
&& request.spawn_request.private_desktop_name.is_none())
.then(|| {
DesktopPolicy::elevated(
crate::setup::SandboxSetupRequest {
permissions: &request.permissions,
command_cwd: &request.cwd,
env_map: &request.env_map,
codex_home: &request.codex_home,
proxy_enforced: request.proxy_enforced,
},
crate::setup::SetupRootOverrides {
read_roots: request.read_roots_override.clone(),
read_roots_include_platform_defaults: request
.read_roots_include_platform_defaults,
write_roots: request.write_roots_override.clone(),
deny_read_paths: Some(request.deny_read_paths_override.clone()),
deny_write_paths: Some(request.deny_write_paths_override.clone()),
},
&request.spawn_request.cap_sids,
request
.spawn_request
.network_proxy_restricting_sid
.as_deref(),
)
})
.transpose()?;
let desktop_policy = request
.spawn_request
.private_desktop_name
.is_none()
.then(|| {
DesktopPolicy::elevated(
crate::setup::SandboxSetupRequest {
permissions: &request.permissions,
command_cwd: &request.cwd,
env_map: &request.env_map,
codex_home: &request.codex_home,
proxy_enforced: request.proxy_enforced,
},
crate::setup::SetupRootOverrides {
read_roots: request.read_roots_override.clone(),
read_roots_include_platform_defaults: request
.read_roots_include_platform_defaults,
write_roots: request.write_roots_override.clone(),
deny_read_paths: Some(request.deny_read_paths_override.clone()),
deny_write_paths: Some(request.deny_write_paths_override.clone()),
},
&request.spawn_request.cap_sids,
request
.spawn_request
.network_proxy_restricting_sid
.as_deref(),
)
})
.transpose()?;
spawn_runner_transport_with_retry(
sandbox_creds,
&request,
@@ -163,7 +165,6 @@ pub(crate) async fn spawn_windows_sandbox_session_elevated_for_permission_profil
deny_write_paths_override: &[AbsolutePathBuf],
tty: bool,
stdin_open: bool,
use_private_desktop: bool,
private_desktop_name: Option<String>,
) -> Result<SpawnedProcess> {
let deny_read_paths_override = deny_read_paths_override
@@ -214,7 +215,6 @@ pub(crate) async fn spawn_windows_sandbox_session_elevated_for_permission_profil
timeout_ms,
tty,
stdin_open,
use_private_desktop,
private_desktop_name,
},
read_roots_override: read_roots_override.map(<[PathBuf]>::to_vec),
@@ -80,7 +80,6 @@ fn retry_uses_original_unified_exec_request_and_stops_after_second_failure() {
timeout_ms: Some(5_000),
tty: true,
stdin_open: true,
use_private_desktop: true,
private_desktop_name: None,
},
read_roots_override: Some(vec![PathBuf::from(r"C:\workspace\read")]),
@@ -69,7 +69,6 @@ fn spawn_legacy_process(
command: &[String],
cwd: &Path,
env_map: &HashMap<String, String>,
use_private_desktop: bool,
private_desktop_name: Option<&str>,
tty: bool,
stdin_open: bool,
@@ -82,7 +81,6 @@ fn spawn_legacy_process(
let launch_desktop = match private_desktop_name {
Some(name) => LaunchDesktop::open_private(name)?,
None => LaunchDesktop::prepare_legacy(
use_private_desktop,
permissions,
cwd,
env_map,
@@ -328,7 +326,6 @@ pub(crate) async fn spawn_windows_sandbox_session_legacy(
additional_deny_write_paths: &[AbsolutePathBuf],
tty: bool,
stdin_open: bool,
use_private_desktop: bool,
private_desktop_name: Option<String>,
) -> Result<SpawnedProcess> {
let common = prepare_legacy_spawn_context(
@@ -408,7 +405,6 @@ pub(crate) async fn spawn_windows_sandbox_session_legacy(
&command,
cwd,
&env_map,
use_private_desktop,
private_desktop_name.as_deref(),
tty,
stdin_open,
@@ -23,7 +23,7 @@ use std::path::PathBuf;
///
/// Callers should parse their own input shape first, then use this request to
/// share the elevated-vs-legacy backend selection and session launch path.
// TODO(anp): Reconcile Windows backend and desktop copies with the supplied sandbox
// TODO(anp): Reconcile the Windows backend copy with the supplied sandbox
// context (TurnEnvironment::sandbox_context for turns), preserving this launch snapshot.
pub struct WindowsSandboxSessionRequest<'a> {
pub permission_profile: &'a PermissionProfile,
@@ -44,7 +44,6 @@ pub struct WindowsSandboxSessionRequest<'a> {
pub deny_write_paths_override: &'a [AbsolutePathBuf],
pub tty: bool,
pub stdin_open: bool,
pub use_private_desktop: bool,
}
pub async fn spawn_windows_sandbox_session_for_level(
@@ -76,7 +75,6 @@ pub(crate) async fn spawn_windows_sandbox_session_with_desktop(
request.deny_write_paths_override,
request.tty,
request.stdin_open,
request.use_private_desktop,
private_desktop_name,
)
.await
@@ -99,7 +97,6 @@ pub(crate) async fn spawn_windows_sandbox_session_with_desktop(
request.deny_write_paths_override,
request.tty,
request.stdin_open,
request.use_private_desktop,
private_desktop_name,
)
.await
@@ -119,7 +116,6 @@ pub async fn spawn_windows_sandbox_session_legacy(
additional_deny_write_paths: &[AbsolutePathBuf],
tty: bool,
stdin_open: bool,
use_private_desktop: bool,
) -> Result<SpawnedProcess> {
backends::legacy::spawn_windows_sandbox_session_legacy(
permission_profile,
@@ -133,7 +129,6 @@ pub async fn spawn_windows_sandbox_session_legacy(
additional_deny_write_paths,
tty,
stdin_open,
use_private_desktop,
/*private_desktop_name*/ None,
)
.await
@@ -157,7 +152,6 @@ pub async fn spawn_windows_sandbox_session_elevated_for_permission_profile(
deny_write_paths_override: &[AbsolutePathBuf],
tty: bool,
stdin_open: bool,
use_private_desktop: bool,
) -> Result<SpawnedProcess> {
backends::elevated::spawn_windows_sandbox_session_elevated_for_permission_profile(
permission_profile,
@@ -177,7 +171,6 @@ pub async fn spawn_windows_sandbox_session_elevated_for_permission_profile(
deny_write_paths_override,
tty,
stdin_open,
use_private_desktop,
/*private_desktop_name*/ None,
)
.await
@@ -249,7 +249,6 @@ fn restricted_token_rejects_managed_network_before_spawn() {
deny_write_paths_override: &[],
tty: false,
stdin_open: false,
use_private_desktop: false,
})
.await
.expect_err("managed networking must fail before spawning an unelevated sandbox");
@@ -286,7 +285,6 @@ fn legacy_non_tty_cmd_emits_output() {
&[],
/*tty*/ false,
/*stdin_open*/ false,
/*use_private_desktop*/ true,
)
.await
.expect("spawn legacy non-tty cmd session");
@@ -334,7 +332,6 @@ fn elevated_non_tty_cmd_forwards_env_output_and_exit() {
&[],
/*tty*/ false,
/*stdin_open*/ false,
/*use_private_desktop*/ true,
)
.await
.unwrap_or_else(|err| {
@@ -390,7 +387,6 @@ fn registered_non_tty_cmd_forwards_env_output_and_exit() {
&[],
/*tty*/ false,
/*stdin_open*/ false,
/*use_private_desktop*/ true,
)
.await
.expect("launch through the service-recorded alias and authenticated pipes");
@@ -433,7 +429,6 @@ fn legacy_non_tty_cmd_rejects_deny_read_overrides() {
&[],
/*tty*/ false,
/*stdin_open*/ false,
/*use_private_desktop*/ true,
)
.await
.expect_err("legacy deny-read should require the elevated backend");
@@ -474,8 +469,7 @@ fn legacy_non_tty_powershell_interrupt_terminates_process() {
&[],
/*tty*/ false,
/*stdin_open*/ false,
/*use_private_desktop*/ true,
)
)
.await
.expect("spawn legacy non-tty powershell session");
println!("pwsh spawn returned");
@@ -705,7 +699,6 @@ fn legacy_capture_emits_output_and_preserves_descendant_after_normal_exit() {
HashMap::new(),
Some(10_000),
/*cancellation*/ None,
/*use_private_desktop*/ true,
)
.expect("run legacy capture powershell");
let descendant_pid = fs::read_to_string(&ready_marker)
@@ -820,7 +813,6 @@ fn legacy_workspace_write_delete_is_limited_to_writable_roots() {
&[],
/*tty*/ false,
/*stdin_open*/ false,
/*use_private_desktop*/ true,
)
.await
.expect("spawn legacy delete session");
@@ -902,7 +894,6 @@ fn legacy_capture_cancellation_terminates_descendants_without_timeout() {
HashMap::new(),
Some(30_000),
/*cancellation*/ Some(cancellation),
/*use_private_desktop*/ true,
)
.expect("run legacy capture powershell with cancellation");
@@ -985,7 +976,6 @@ async fn assert_legacy_tty_descendant_lifecycle(
&[],
/*tty*/ true,
/*stdin_open*/ false,
/*use_private_desktop*/ true,
)
.await
.expect("spawn legacy sandbox ConPTY lifecycle test");
@@ -1069,7 +1059,6 @@ fn legacy_tty_powershell_emits_output_and_accepts_input() {
&[],
/*tty*/ true,
/*stdin_open*/ true,
/*use_private_desktop*/ true,
)
.await
.expect("spawn legacy tty powershell session");
@@ -1094,7 +1083,6 @@ fn legacy_tty_powershell_emits_output_and_accepts_input() {
assert!(stdout.contains("second"), "stdout={stdout:?}");
});
}
#[test]
#[ignore = "TODO: legacy ConPTY cmd.exe exits with STATUS_DLL_INIT_FAILED in CI"]
fn legacy_tty_cmd_emits_output_and_accepts_input() {
@@ -1120,7 +1108,6 @@ fn legacy_tty_cmd_emits_output_and_accepts_input() {
&[],
/*tty*/ true,
/*stdin_open*/ true,
/*use_private_desktop*/ true,
)
.await
.expect("spawn legacy tty cmd session");
@@ -1145,57 +1132,3 @@ fn legacy_tty_cmd_emits_output_and_accepts_input() {
assert!(stdout.contains("second"), "stdout={stdout:?}");
});
}
#[test]
#[ignore = "TODO: legacy ConPTY cmd.exe exits with STATUS_DLL_INIT_FAILED in CI"]
fn legacy_tty_cmd_default_desktop_emits_output_and_accepts_input() {
let runtime = current_thread_runtime();
runtime.block_on(async move {
let cwd = sandbox_cwd();
let codex_home = sandbox_home("legacy-tty-cmd-default-desktop");
println!(
"tty cmd default desktop codex_home={}",
codex_home.path().display()
);
let permission_profile = PermissionProfile::workspace_write();
let spawned = spawn_windows_sandbox_session_legacy(
&permission_profile,
workspace_roots_for(cwd.as_path()).as_slice(),
codex_home.path(),
vec![
"C:\\Windows\\System32\\cmd.exe".to_string(),
"/K".to_string(),
"echo ready".to_string(),
],
cwd.as_path(),
HashMap::new(),
Some(10_000),
&[],
&[],
/*tty*/ true,
/*stdin_open*/ true,
/*use_private_desktop*/ false,
)
.await
.expect("spawn legacy tty cmd session");
println!("tty cmd default desktop spawn returned");
let writer = spawned.session.writer_sender();
writer
.send(b"echo second\n".to_vec())
.await
.expect("send second command");
writer
.send(b"exit\n".to_vec())
.await
.expect("send exit command");
spawned.session.close_stdin();
let (stdout, exit_code) =
collect_stdout_and_exit(spawned, codex_home.path(), Duration::from_secs(15)).await;
let stdout = String::from_utf8_lossy(&stdout);
assert_eq!(exit_code, 0, "stdout={stdout:?}");
assert!(stdout.contains("ready"), "stdout={stdout:?}");
assert!(stdout.contains("second"), "stdout={stdout:?}");
});
}
+10 -19
View File
@@ -39,7 +39,6 @@ const DENY_WRITE_PATHS_JSON_FLAG: &str = "--deny-write-paths-json";
const ENV_JSON_FLAG: &str = "--env-json";
const NETWORK_PROXY_RESTRICTING_SID_FLAG: &str = "--network-proxy-restricting-sid";
const PERMISSION_PROFILE_FLAG: &str = "--permission-profile";
const PRIVATE_DESKTOP_FLAG: &str = "--windows-sandbox-private-desktop";
const PRIVATE_DESKTOP_NAME_FLAG: &str = "--windows-sandbox-private-desktop-name";
const PRESERVE_PROXY_SETTINGS_FLAG: &str = "--preserve-proxy-settings";
const PROXY_ENFORCED_FLAG: &str = "--proxy-enforced";
@@ -57,7 +56,6 @@ pub fn create_windows_sandbox_command_args_for_permission_profile(
env_map: &HashMap<String, String>,
permission_profile: &PermissionProfile,
windows_sandbox_level: WindowsSandboxLevel,
windows_sandbox_private_desktop: bool,
proxy_enforced: bool,
network_proxy_restricting_sid: Option<&str>,
proxy_settings_mode: crate::WindowsSandboxProxySettingsMode,
@@ -94,14 +92,14 @@ pub fn create_windows_sandbox_command_args_for_permission_profile(
args.push(WORKSPACE_ROOT_FLAG.to_string());
args.push(root.as_path().to_string_lossy().into_owned());
}
if windows_sandbox_private_desktop {
let desktop_name = {
// The caller owns the cache so the desktop survives this short-lived wrapper.
let mut desktop_env = env_map.clone();
let deny_write_paths = deny_write_paths_override
.iter()
.map(AbsolutePathBuf::to_path_buf)
.collect::<Vec<_>>();
let desktop_name = if windows_sandbox_level == WindowsSandboxLevel::Elevated {
if windows_sandbox_level == WindowsSandboxLevel::Elevated {
let common = prepare_spawn_context_common(
permission_profile,
workspace_roots,
@@ -204,11 +202,10 @@ pub fn create_windows_sandbox_command_args_for_permission_profile(
CloseHandle(security.h_token);
}
desktop_name?
};
args.push(PRIVATE_DESKTOP_FLAG.to_string());
args.push(PRIVATE_DESKTOP_NAME_FLAG.to_string());
args.push(desktop_name);
}
}
};
args.push(PRIVATE_DESKTOP_NAME_FLAG.to_string());
args.push(desktop_name);
if proxy_enforced {
args.push(PROXY_ENFORCED_FLAG.to_string());
}
@@ -289,8 +286,7 @@ struct WindowsSandboxWrapperRequest {
env_map: HashMap<String, String>,
permission_profile: PermissionProfile,
windows_sandbox_level: WindowsSandboxLevel,
windows_sandbox_private_desktop: bool,
private_desktop_name: Option<String>,
private_desktop_name: String,
proxy_enforced: bool,
network_proxy_restricting_sid: Option<String>,
proxy_settings_mode: crate::WindowsSandboxProxySettingsMode,
@@ -326,9 +322,8 @@ async fn run_windows_sandbox_wrapper_request(request: WindowsSandboxWrapperReque
deny_write_paths_override: request.deny_write_paths_override.as_slice(),
tty: false,
stdin_open: true,
use_private_desktop: request.windows_sandbox_private_desktop,
},
request.private_desktop_name,
Some(request.private_desktop_name),
)
.await?;
@@ -343,7 +338,6 @@ fn parse_windows_sandbox_wrapper_args(args: Vec<String>) -> Result<WindowsSandbo
let mut env_map = None;
let mut permission_profile = None;
let mut windows_sandbox_level = None;
let mut windows_sandbox_private_desktop = false;
let mut private_desktop_name = None;
let mut proxy_enforced = false;
let mut network_proxy_restricting_sid = None;
@@ -386,7 +380,6 @@ fn parse_windows_sandbox_wrapper_args(args: Vec<String>) -> Result<WindowsSandbo
let value = next_flag_value(&mut args, &arg)?;
windows_sandbox_level = Some(parse_windows_sandbox_level(&value)?);
}
PRIVATE_DESKTOP_FLAG => windows_sandbox_private_desktop = true,
PRIVATE_DESKTOP_NAME_FLAG => {
private_desktop_name = Some(next_flag_value(&mut args, &arg)?);
}
@@ -424,9 +417,8 @@ fn parse_windows_sandbox_wrapper_args(args: Vec<String>) -> Result<WindowsSandbo
);
}
let command_cwd = command_cwd.ok_or_else(|| anyhow!("missing required {COMMAND_CWD_FLAG}"))?;
if windows_sandbox_private_desktop != private_desktop_name.is_some() {
bail!("{PRIVATE_DESKTOP_FLAG} requires {PRIVATE_DESKTOP_NAME_FLAG}");
}
let private_desktop_name = private_desktop_name
.ok_or_else(|| anyhow!("missing required {PRIVATE_DESKTOP_NAME_FLAG}"))?;
if workspace_roots.is_empty() {
workspace_roots.push(command_cwd.clone());
}
@@ -439,7 +431,6 @@ fn parse_windows_sandbox_wrapper_args(args: Vec<String>) -> Result<WindowsSandbo
.ok_or_else(|| anyhow!("missing required {PERMISSION_PROFILE_FLAG}"))?,
windows_sandbox_level: windows_sandbox_level
.ok_or_else(|| anyhow!("missing required {SANDBOX_LEVEL_FLAG}"))?,
windows_sandbox_private_desktop,
private_desktop_name,
proxy_enforced,
network_proxy_restricting_sid,
@@ -4,7 +4,6 @@ use std::path::PathBuf;
use codex_protocol::config_types::WindowsSandboxLevel;
use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_utils_absolute_path::AbsolutePathBuf;
use pretty_assertions::assert_eq;
@@ -17,7 +16,6 @@ use super::ENV_JSON_FLAG;
use super::NETWORK_PROXY_RESTRICTING_SID_FLAG;
use super::PERMISSION_PROFILE_FLAG;
use super::PRESERVE_PROXY_SETTINGS_FLAG;
use super::PRIVATE_DESKTOP_FLAG;
use super::PRIVATE_DESKTOP_NAME_FLAG;
use super::PROXY_ENFORCED_FLAG;
use super::READ_ROOTS_INCLUDE_PLATFORM_DEFAULTS_FLAG;
@@ -30,17 +28,16 @@ use super::parse_windows_sandbox_wrapper_args;
#[test]
fn windows_wrapper_args_round_trip() {
let command_cwd = AbsolutePathBuf::from_absolute_path(Path::new(r"C:\workspace"))
.expect("absolute command cwd");
let temp = tempfile::tempdir().expect("tempdir");
let command_cwd =
AbsolutePathBuf::from_absolute_path(temp.path()).expect("absolute command cwd");
let workspace_roots = vec![
command_cwd.clone(),
AbsolutePathBuf::from_absolute_path(Path::new(r"D:\other-workspace"))
.expect("absolute workspace root"),
];
let env = HashMap::from([("Path".to_string(), r"C:\Windows\System32".to_string())]);
let permission_profile = PermissionProfile::External {
network: NetworkSandboxPolicy::Restricted,
};
let permission_profile = PermissionProfile::read_only();
let read_roots_override = vec![PathBuf::from(r"C:\read")];
let write_roots_override = vec![PathBuf::from(r"C:\write")];
let deny_read_paths_override = vec![
@@ -61,8 +58,7 @@ fn windows_wrapper_args_round_trip() {
workspace_roots.as_slice(),
&env,
&permission_profile,
WindowsSandboxLevel::Elevated,
/*windows_sandbox_private_desktop*/ false,
WindowsSandboxLevel::RestrictedToken,
/*proxy_enforced*/ true,
/*network_proxy_restricting_sid*/ Some("S-1-5-21-100-200-300-400"),
crate::WindowsSandboxProxySettingsMode::Preserve,
@@ -71,7 +67,7 @@ fn windows_wrapper_args_round_trip() {
Some(write_roots_override.as_slice()),
deny_read_paths_override.as_slice(),
deny_write_paths_override.as_slice(),
Path::new(r"C:\Users\me\.codex"),
temp.path(),
)
.expect("build wrapper args");
@@ -102,9 +98,13 @@ fn windows_wrapper_args_round_trip() {
assert_eq!(parsed.workspace_roots, workspace_roots);
assert_eq!(parsed.env_map, env);
assert_eq!(parsed.permission_profile, permission_profile);
assert_eq!(parsed.windows_sandbox_level, WindowsSandboxLevel::Elevated);
assert_eq!(parsed.windows_sandbox_private_desktop, false);
assert_eq!(parsed.private_desktop_name, None);
assert_eq!(
parsed.windows_sandbox_level,
WindowsSandboxLevel::RestrictedToken
);
let desktop = crate::desktop::LaunchDesktop::open_private(&parsed.private_desktop_name)
.expect("wrapper must receive a live private desktop");
drop(desktop);
assert_eq!(parsed.proxy_enforced, true);
assert_eq!(
parsed.network_proxy_restricting_sid.as_deref(),
@@ -120,14 +120,11 @@ fn windows_wrapper_args_round_trip() {
assert_eq!(parsed.deny_read_paths_override, deny_read_paths_override);
assert_eq!(parsed.deny_write_paths_override, deny_write_paths_override);
let mut private_args = args[1..].to_vec();
private_args.insert(/*index*/ 0, PRIVATE_DESKTOP_FLAG.to_string());
assert!(parse_windows_sandbox_wrapper_args(private_args.clone()).is_err());
let name = "CodexSandboxDesktop-0123456789abcdef";
private_args.splice(
1..1,
[PRIVATE_DESKTOP_NAME_FLAG.to_string(), name.to_string()],
);
let parsed = parse_windows_sandbox_wrapper_args(private_args).expect("parse named desktop");
assert_eq!(parsed.private_desktop_name.as_deref(), Some(name));
let mut missing_desktop_args = args[1..].to_vec();
let name_index = missing_desktop_args
.iter()
.position(|arg| arg == PRIVATE_DESKTOP_NAME_FLAG)
.expect("private desktop name argument");
missing_desktop_args.drain(name_index..name_index + 2);
assert!(parse_windows_sandbox_wrapper_args(missing_desktop_args).is_err());
}
@@ -11452,9 +11452,6 @@ class ConfigRequirements(BaseModel):
] = None
models: ModelsRequirements | None = None
sqlite_home: Annotated[str | None, Field(alias="sqliteHome")] = None
windows_sandbox_private_desktop: Annotated[
bool | None, Field(alias="windowsSandboxPrivateDesktop")
] = None
class ConfigRequirementsReadResponse(BaseModel):