mirror of
https://github.com/openai/codex.git
synced 2026-05-04 13:21:54 +03:00
Promote Windows Sandbox (#11341)
1. Move Windows Sandbox NUX to right after trust directory screen 2. Don't offer read-only as an option in Sandbox NUX. Elevated/Legacy/Quit 3. Don't allow new untrusted directories. It's trust or quit 4. move experimental sandbox features to `[windows] sandbox="elevated|unelevatd"` 5. Copy tweaks = elevated -> default, non-elevated -> non-admin
This commit is contained in:
@@ -944,6 +944,7 @@ impl App {
|
||||
session_selection: SessionSelection,
|
||||
feedback: codex_feedback::CodexFeedback,
|
||||
is_first_run: bool,
|
||||
should_prompt_windows_sandbox_nux_at_startup: bool,
|
||||
) -> Result<AppExitInfo> {
|
||||
use tokio_stream::StreamExt;
|
||||
let (app_event_tx, mut app_event_rx) = unbounded_channel();
|
||||
@@ -1107,7 +1108,8 @@ impl App {
|
||||
}
|
||||
};
|
||||
|
||||
chat_widget.maybe_prompt_windows_sandbox_enable();
|
||||
chat_widget
|
||||
.maybe_prompt_windows_sandbox_enable(should_prompt_windows_sandbox_nux_at_startup);
|
||||
|
||||
let file_search = FileSearchManager::new(config.cwd.clone(), app_event_tx.clone());
|
||||
#[cfg(not(debug_assertions))]
|
||||
@@ -1788,6 +1790,42 @@ impl App {
|
||||
let _ = preset;
|
||||
}
|
||||
}
|
||||
AppEvent::BeginWindowsSandboxLegacySetup { preset } => {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let policy = preset.sandbox.clone();
|
||||
let policy_cwd = self.config.cwd.clone();
|
||||
let command_cwd = policy_cwd.clone();
|
||||
let env_map: std::collections::HashMap<String, String> =
|
||||
std::env::vars().collect();
|
||||
let codex_home = self.config.codex_home.clone();
|
||||
let tx = self.app_event_tx.clone();
|
||||
|
||||
self.chat_widget.show_windows_sandbox_setup_status();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
if let Err(err) = codex_core::windows_sandbox::run_legacy_setup_preflight(
|
||||
&policy,
|
||||
policy_cwd.as_path(),
|
||||
command_cwd.as_path(),
|
||||
&env_map,
|
||||
codex_home.as_path(),
|
||||
) {
|
||||
tracing::warn!(
|
||||
error = %err,
|
||||
"failed to preflight non-admin Windows sandbox setup"
|
||||
);
|
||||
}
|
||||
tx.send(AppEvent::EnableWindowsSandboxForAgentMode {
|
||||
preset,
|
||||
mode: WindowsSandboxEnableMode::Legacy,
|
||||
});
|
||||
});
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
let _ = preset;
|
||||
}
|
||||
}
|
||||
AppEvent::EnableWindowsSandboxForAgentMode { preset, mode } => {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
@@ -1800,33 +1838,26 @@ impl App {
|
||||
);
|
||||
}
|
||||
let profile = self.active_profile.as_deref();
|
||||
let feature_key = Feature::WindowsSandbox.key();
|
||||
let elevated_key = Feature::WindowsSandboxElevated.key();
|
||||
let elevated_enabled = matches!(mode, WindowsSandboxEnableMode::Elevated);
|
||||
let mut builder =
|
||||
ConfigEditsBuilder::new(&self.config.codex_home).with_profile(profile);
|
||||
if elevated_enabled {
|
||||
builder = builder.set_feature_enabled(elevated_key, true);
|
||||
} else {
|
||||
builder = builder
|
||||
.set_feature_enabled(feature_key, true)
|
||||
.set_feature_enabled(elevated_key, false);
|
||||
}
|
||||
let builder = ConfigEditsBuilder::new(&self.config.codex_home)
|
||||
.with_profile(profile)
|
||||
.set_windows_sandbox_mode(if elevated_enabled {
|
||||
"elevated"
|
||||
} else {
|
||||
"unelevated"
|
||||
})
|
||||
.clear_legacy_windows_sandbox_keys();
|
||||
match builder.apply().await {
|
||||
Ok(()) => {
|
||||
if elevated_enabled {
|
||||
self.config.set_windows_sandbox_enabled(false);
|
||||
self.config.set_windows_elevated_sandbox_enabled(true);
|
||||
self.chat_widget
|
||||
.set_feature_enabled(Feature::WindowsSandboxElevated, true);
|
||||
} else {
|
||||
self.config.set_windows_sandbox_enabled(true);
|
||||
self.config.set_windows_elevated_sandbox_enabled(false);
|
||||
self.chat_widget
|
||||
.set_feature_enabled(Feature::WindowsSandbox, true);
|
||||
self.chat_widget
|
||||
.set_feature_enabled(Feature::WindowsSandboxElevated, false);
|
||||
}
|
||||
self.chat_widget.clear_forced_auto_mode_downgrade();
|
||||
self.chat_widget
|
||||
.set_windows_sandbox_mode(self.config.windows_sandbox_mode);
|
||||
let windows_sandbox_level =
|
||||
WindowsSandboxLevel::from_config(&self.config);
|
||||
if let Some((sample_paths, extra_count, failed_scan)) =
|
||||
@@ -1871,17 +1902,15 @@ impl App {
|
||||
.send(AppEvent::UpdateAskForApprovalPolicy(preset.approval));
|
||||
self.app_event_tx
|
||||
.send(AppEvent::UpdateSandboxPolicy(preset.sandbox.clone()));
|
||||
self.chat_widget.add_info_message(
|
||||
match mode {
|
||||
WindowsSandboxEnableMode::Elevated => {
|
||||
"Enabled elevated agent sandbox.".to_string()
|
||||
}
|
||||
WindowsSandboxEnableMode::Legacy => {
|
||||
"Enabled non-elevated agent sandbox.".to_string()
|
||||
}
|
||||
},
|
||||
None,
|
||||
);
|
||||
let _ = mode;
|
||||
self.chat_widget.add_plain_history_lines(vec![
|
||||
Line::from(vec!["• ".dim(), "Sandbox ready".into()]),
|
||||
Line::from(vec![
|
||||
" ".into(),
|
||||
"Codex can now safely edit files and execute commands in your computer"
|
||||
.dark_gray(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
@@ -1989,21 +2018,17 @@ impl App {
|
||||
codex_core::protocol::SandboxPolicy::WorkspaceWrite { .. }
|
||||
| codex_core::protocol::SandboxPolicy::ReadOnly
|
||||
);
|
||||
#[cfg(target_os = "windows")]
|
||||
let policy_for_chat = policy.clone();
|
||||
|
||||
if let Err(err) = self.config.sandbox_policy.set(policy.clone()) {
|
||||
if let Err(err) = self.config.sandbox_policy.set(policy) {
|
||||
tracing::warn!(%err, "failed to set sandbox policy on app config");
|
||||
self.chat_widget
|
||||
.add_error_message(format!("Failed to set sandbox policy: {err}"));
|
||||
return Ok(AppRunControl::Continue);
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
if !matches!(&policy, codex_core::protocol::SandboxPolicy::ReadOnly)
|
||||
|| WindowsSandboxLevel::from_config(&self.config)
|
||||
!= WindowsSandboxLevel::Disabled
|
||||
{
|
||||
self.config.forced_auto_mode_downgraded_on_windows = false;
|
||||
}
|
||||
if let Err(err) = self.chat_widget.set_sandbox_policy(policy) {
|
||||
if let Err(err) = self.chat_widget.set_sandbox_policy(policy_for_chat) {
|
||||
tracing::warn!(%err, "failed to set sandbox policy on chat config");
|
||||
self.chat_widget
|
||||
.add_error_message(format!("Failed to set sandbox policy: {err}"));
|
||||
|
||||
Reference in New Issue
Block a user