mirror of
https://github.com/openai/codex.git
synced 2026-11-12 22:42:36 +00:00
windows-sandbox: drive write roots from resolved permissions (#22923)
## Why This is the third PR in the Windows sandbox `SandboxPolicy` -> `PermissionProfile` migration stack. #22896 introduced `ResolvedWindowsSandboxPermissions`, and #22918 moved elevated runner IPC to carry `PermissionProfile`. This PR starts moving the remaining setup/spawn helpers away from asking legacy enum questions like “is this `WorkspaceWrite`?” and toward resolved runtime permission questions like “does this profile require write capability roots?” ## What changed - Added resolved-permissions helpers for network identity and write-capability detection. - Moved setup write-root gathering to operate on `ResolvedWindowsSandboxPermissions`, with the legacy `SandboxPolicy` wrapper left in place for existing call sites. - Updated identity setup, elevated capture setup, and world-writable audit denies to use resolved write roots. - Updated spawn preparation to carry resolved permissions in `SpawnContext` and use them for network blocking, setup write roots, elevated capability SID selection, and legacy capability roots. - Removed a now-unused legacy write-root helper. ## Verification - `cargo test -p codex-windows-sandbox` - `just fix -p codex-windows-sandbox` - Existing stack checks are green on #22896 and #22918; CI has started for this PR. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/22923). * #23715 * #23714 * #23167 * __->__ #22923
This commit is contained in:
1 parent
f48be015d6
commit
e1ec0eee5f
10 files changed
+361
-134
No files matched your search
@@ -18,6 +18,7 @@ use serial_test::serial;
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsString;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use tempfile::TempDir;
|
||||
|
||||
struct EnvVarGuard {
|
||||
@@ -46,13 +47,49 @@ impl Drop for EnvVarGuard {
|
||||
}
|
||||
}
|
||||
|
||||
enum TestCodexHome {
|
||||
Persistent(PathBuf),
|
||||
Temporary(TempDir),
|
||||
}
|
||||
|
||||
impl TestCodexHome {
|
||||
fn path(&self) -> &Path {
|
||||
match self {
|
||||
Self::Persistent(path) => path.as_path(),
|
||||
Self::Temporary(temp_dir) => temp_dir.path(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn codex_home_for_windows_sandbox_test(name: &str) -> anyhow::Result<TestCodexHome> {
|
||||
if let Some(test_tmpdir) = std::env::var_os("TEST_TMPDIR") {
|
||||
// The elevated backend provisions machine-local sandbox users. Bazel
|
||||
// retries run in the same Windows VM, so keep CODEX_HOME stable within
|
||||
// the test temp root and let setup reconcile its persisted ACL state.
|
||||
let codex_home = PathBuf::from(test_tmpdir).join(name);
|
||||
std::fs::create_dir_all(&codex_home)
|
||||
.with_context(|| format!("create stable test CODEX_HOME {}", codex_home.display()))?;
|
||||
return Ok(TestCodexHome::Persistent(codex_home));
|
||||
}
|
||||
|
||||
Ok(TestCodexHome::Temporary(TempDir::new()?))
|
||||
}
|
||||
|
||||
fn stage_windows_sandbox_helpers() -> anyhow::Result<()> {
|
||||
let test_exe = std::env::current_exe().context("resolve current Windows test executable")?;
|
||||
let test_exe_dir = test_exe
|
||||
.parent()
|
||||
.context("Windows test executable should have a parent directory")?;
|
||||
let resources_dir = test_exe_dir.join("codex-resources");
|
||||
std::fs::create_dir_all(&resources_dir)?;
|
||||
match std::fs::create_dir_all(&resources_dir) {
|
||||
Ok(()) => {}
|
||||
Err(err)
|
||||
if err.kind() == std::io::ErrorKind::PermissionDenied && resources_dir.is_dir() => {}
|
||||
Err(err) => {
|
||||
return Err(err)
|
||||
.with_context(|| format!("create resources dir {}", resources_dir.display()));
|
||||
}
|
||||
}
|
||||
for helper_name in ["codex-windows-sandbox-setup", "codex-command-runner"] {
|
||||
let helper = codex_utils_cargo_bin::cargo_bin(helper_name)?;
|
||||
let file_name = Path::new(helper_name).with_extension("exe");
|
||||
@@ -64,8 +101,9 @@ fn stage_windows_sandbox_helpers() -> anyhow::Result<()> {
|
||||
#[tokio::test]
|
||||
#[serial(codex_home)]
|
||||
async fn windows_restricted_token_rejects_exact_and_glob_deny_read_policy() -> anyhow::Result<()> {
|
||||
let temp_home = TempDir::new()?;
|
||||
let _codex_home_guard = EnvVarGuard::set("CODEX_HOME", temp_home.path().as_os_str());
|
||||
let codex_home =
|
||||
codex_home_for_windows_sandbox_test("windows-restricted-token-deny-read-codex-home")?;
|
||||
let _codex_home_guard = EnvVarGuard::set("CODEX_HOME", codex_home.path().as_os_str());
|
||||
let workspace = TempDir::new()?;
|
||||
let cwd = dunce::canonicalize(workspace.path())?.abs();
|
||||
let secret = cwd.join("secret.env");
|
||||
@@ -144,8 +182,8 @@ async fn windows_restricted_token_rejects_exact_and_glob_deny_read_policy() -> a
|
||||
#[tokio::test]
|
||||
#[serial(codex_home)]
|
||||
async fn windows_elevated_enforces_exact_and_glob_deny_read_policy() -> anyhow::Result<()> {
|
||||
let temp_home = TempDir::new()?;
|
||||
let _codex_home_guard = EnvVarGuard::set("CODEX_HOME", temp_home.path().as_os_str());
|
||||
let codex_home = codex_home_for_windows_sandbox_test("windows-elevated-deny-read-codex-home")?;
|
||||
let _codex_home_guard = EnvVarGuard::set("CODEX_HOME", codex_home.path().as_os_str());
|
||||
stage_windows_sandbox_helpers()?;
|
||||
let workspace = TempDir::new()?;
|
||||
let cwd = dunce::canonicalize(workspace.path())?.abs();
|
||||
|
||||
Reference in new issue
Block a user