fix(windows): revalidate elevated sandbox before skipping setup

This commit is contained in:
David Wiesen
2026-06-18 10:29:14 -07:00
parent 47ab51470b
commit 9e34990ffc
4 changed files with 93 additions and 5 deletions

View File

@@ -169,6 +169,41 @@ pub fn run_elevated_setup(
)
}
#[cfg(target_os = "windows")]
pub fn elevated_setup_is_ready(
permission_profile: &PermissionProfile,
workspace_roots: &[AbsolutePathBuf],
command_cwd: &Path,
env_map: &HashMap<String, String>,
codex_home: &Path,
) -> bool {
if !sandbox_setup_is_complete(codex_home) {
return false;
}
codex_windows_sandbox::run_setup_refresh_with_extra_read_roots(
permission_profile,
workspace_roots,
command_cwd,
env_map,
codex_home,
Vec::new(),
/*proxy_enforced*/ false,
)
.is_ok()
}
#[cfg(not(target_os = "windows"))]
pub fn elevated_setup_is_ready(
_permission_profile: &PermissionProfile,
_workspace_roots: &[AbsolutePathBuf],
_command_cwd: &Path,
_env_map: &HashMap<String, String>,
_codex_home: &Path,
) -> bool {
false
}
#[cfg(target_os = "windows")]
pub fn run_elevated_provisioning_setup(codex_home: &Path, real_user: &str) -> anyhow::Result<()> {
codex_windows_sandbox::run_elevated_provisioning_setup(codex_home, real_user)
@@ -307,7 +342,13 @@ async fn run_windows_sandbox_setup_and_persist(
let setup_result = tokio::task::spawn_blocking(move || -> anyhow::Result<()> {
match mode {
WindowsSandboxSetupMode::Elevated => {
if !sandbox_setup_is_complete(setup_codex_home.as_path()) {
if !elevated_setup_is_ready(
&permission_profile,
workspace_roots.as_slice(),
command_cwd.as_path(),
&env_map,
setup_codex_home.as_path(),
) {
run_elevated_setup(
&permission_profile,
workspace_roots.as_slice(),

View File

@@ -1029,9 +1029,15 @@ impl App {
let codex_home = self.config.codex_home.clone();
let tx = self.app_event_tx.clone();
// If the elevated setup already ran on this machine, don't prompt for
// elevation again - just flip the config to use the elevated path.
if crate::windows_sandbox::sandbox_setup_is_complete(codex_home.as_path()) {
// Skip the UAC path only when the existing setup still refreshes cleanly
// for the current workspace roots and permission profile.
if crate::windows_sandbox::elevated_setup_is_ready(
&permission_profile,
workspace_roots.as_slice(),
command_cwd.as_path(),
&env_map,
codex_home.as_path(),
) {
tx.send(AppEvent::EnableWindowsSandboxForAgentMode {
preset,
mode: WindowsSandboxEnableMode::Elevated,

View File

@@ -328,7 +328,13 @@ impl ChatWidget {
== WindowsSandboxLevel::Disabled
{
let preset = preset.clone();
if crate::windows_sandbox::sandbox_setup_is_complete(
let env_map: std::collections::HashMap<String, String> =
std::env::vars().collect();
if crate::windows_sandbox::elevated_setup_is_ready(
&self.config.permissions.effective_permission_profile(),
self.config.effective_workspace_roots().as_slice(),
self.config.cwd.as_path(),
&env_map,
self.config.codex_home.as_path(),
) {
return vec![Box::new(move |tx| {

View File

@@ -42,6 +42,41 @@ pub(crate) fn sandbox_setup_is_complete(_codex_home: &Path) -> bool {
false
}
#[cfg(target_os = "windows")]
pub(crate) fn elevated_setup_is_ready(
permission_profile: &PermissionProfile,
workspace_roots: &[AbsolutePathBuf],
command_cwd: &Path,
env_map: &HashMap<String, String>,
codex_home: &Path,
) -> bool {
if !sandbox_setup_is_complete(codex_home) {
return false;
}
codex_windows_sandbox::run_setup_refresh_with_extra_read_roots(
permission_profile,
workspace_roots,
command_cwd,
env_map,
codex_home,
Vec::new(),
/*proxy_enforced*/ false,
)
.is_ok()
}
#[cfg(not(target_os = "windows"))]
pub(crate) fn elevated_setup_is_ready(
_permission_profile: &PermissionProfile,
_workspace_roots: &[AbsolutePathBuf],
_command_cwd: &Path,
_env_map: &HashMap<String, String>,
_codex_home: &Path,
) -> bool {
false
}
#[cfg(target_os = "windows")]
pub(crate) fn run_elevated_setup(
permission_profile: &PermissionProfile,