mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
windows-sandbox: remove SandboxPolicy runner plumbing (#23813)
## Why The Windows sandbox runner still carried the old `SandboxPolicy` compatibility path even though core now computes `PermissionProfile`. That meant Windows command-runner execution could only see the legacy projection, so profile-only filesystem rules such as deny globs were not part of the runner input. ## What Changed - Removed the Windows-local `SandboxPolicy` parser/export and deleted `windows-sandbox-rs/src/policy.rs`. - Changed restricted-token capture/session setup, elevated setup, world-writable audit, read-root grant, and command-runner session APIs to accept `PermissionProfile` plus the profile cwd. - Bumped the elevated command-runner IPC protocol to version 2 because `SpawnRequest` now carries `permission_profile` / `permission_profile_cwd` instead of the legacy `policy_json_or_preset` / `sandbox_policy_cwd` fields. - Updated core exec, unified exec, debug-sandbox, TUI setup/grant flows, and app-server setup to pass the actual effective `PermissionProfile`. - Left regression coverage asserting the old IPC policy fields are absent and the runner serializes tagged `PermissionProfile` JSON. ## Verification - `cargo test -p codex-windows-sandbox` - `cargo test -p codex-core windows_sandbox` - `cargo test -p codex-app-server request_processors::windows_sandbox_processor` - `just fix -p codex-windows-sandbox -p codex-core -p codex-app-server -p codex-cli -p codex-tui` - `just fix -p codex-cli -p codex-tui` - `just fix -p codex-windows-sandbox -p codex-tui` - `rg "\\bSandboxPolicy\\b" codex-rs/windows-sandbox-rs` returned no matches. Note: `cargo test -p codex-cli` was attempted but did not reach crate tests because local disk filled while compiling dependencies (`No space left on device`). The targeted clippy pass compiled the affected CLI/TUI surfaces afterward. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/23813). * #24108 * __->__ #23813
This commit is contained in:
@@ -423,7 +423,6 @@ pub(crate) async fn execute_exec_request(
|
||||
stdout_stream: Option<StdoutStream>,
|
||||
after_spawn: Option<Box<dyn FnOnce() + Send>>,
|
||||
) -> Result<ExecToolCallOutput> {
|
||||
let sandbox_policy = exec_request.compatibility_sandbox_policy();
|
||||
let ExecRequest {
|
||||
command,
|
||||
cwd,
|
||||
@@ -464,7 +463,6 @@ pub(crate) async fn execute_exec_request(
|
||||
stdout_stream,
|
||||
after_spawn,
|
||||
sandbox,
|
||||
&sandbox_policy,
|
||||
&permission_profile,
|
||||
&windows_sandbox_policy_cwd,
|
||||
windows_sandbox_filesystem_overrides.as_ref(),
|
||||
@@ -481,7 +479,6 @@ async fn get_raw_output_result(
|
||||
stdout_stream: Option<StdoutStream>,
|
||||
after_spawn: Option<Box<dyn FnOnce() + Send>>,
|
||||
#[cfg_attr(not(windows), allow(unused_variables))] sandbox: SandboxType,
|
||||
#[cfg_attr(not(windows), allow(unused_variables))] sandbox_policy: &SandboxPolicy,
|
||||
#[cfg_attr(not(windows), allow(unused_variables))] permission_profile: &PermissionProfile,
|
||||
#[cfg_attr(not(windows), allow(unused_variables))] windows_sandbox_policy_cwd: &AbsolutePathBuf,
|
||||
#[cfg_attr(not(windows), allow(unused_variables))] windows_sandbox_filesystem_overrides: Option<
|
||||
@@ -492,7 +489,6 @@ async fn get_raw_output_result(
|
||||
if sandbox == SandboxType::WindowsRestrictedToken {
|
||||
return exec_windows_sandbox(
|
||||
params,
|
||||
sandbox_policy,
|
||||
permission_profile,
|
||||
windows_sandbox_policy_cwd,
|
||||
windows_sandbox_filesystem_overrides,
|
||||
@@ -572,7 +568,6 @@ fn record_windows_sandbox_spawn_failure(
|
||||
#[cfg(target_os = "windows")]
|
||||
async fn exec_windows_sandbox(
|
||||
params: ExecParams,
|
||||
sandbox_policy: &SandboxPolicy,
|
||||
permission_profile: &PermissionProfile,
|
||||
windows_sandbox_policy_cwd: &AbsolutePathBuf,
|
||||
windows_sandbox_filesystem_overrides: Option<&WindowsSandboxFilesystemOverrides>,
|
||||
@@ -604,11 +599,6 @@ async fn exec_windows_sandbox(
|
||||
None
|
||||
};
|
||||
|
||||
let policy_str = serde_json::to_string(sandbox_policy).map_err(|err| {
|
||||
CodexErr::Io(io::Error::other(format!(
|
||||
"failed to serialize Windows sandbox policy: {err}"
|
||||
)))
|
||||
})?;
|
||||
let sandbox_cwd = windows_sandbox_policy_cwd.clone();
|
||||
let permission_profile = permission_profile.clone();
|
||||
let codex_home = find_codex_home().map_err(|err| {
|
||||
@@ -655,7 +645,7 @@ async fn exec_windows_sandbox(
|
||||
)
|
||||
} else {
|
||||
run_windows_sandbox_capture_with_filesystem_overrides(
|
||||
policy_str.as_str(),
|
||||
&permission_profile,
|
||||
&sandbox_cwd,
|
||||
codex_home.as_ref(),
|
||||
command,
|
||||
|
||||
@@ -866,12 +866,6 @@ impl UnifiedExecProcessManager {
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
if request.sandbox == codex_sandboxing::SandboxType::WindowsRestrictedToken {
|
||||
let sandbox_policy = request.compatibility_sandbox_policy();
|
||||
let policy_json = serde_json::to_string(&sandbox_policy).map_err(|err| {
|
||||
UnifiedExecError::create_process(format!(
|
||||
"failed to serialize Windows sandbox policy: {err}"
|
||||
))
|
||||
})?;
|
||||
let codex_home = crate::config::find_codex_home().map_err(|err| {
|
||||
UnifiedExecError::create_process(format!(
|
||||
"windows sandbox: failed to resolve codex_home: {err}"
|
||||
@@ -923,7 +917,7 @@ impl UnifiedExecProcessManager {
|
||||
codex_protocol::config_types::WindowsSandboxLevel::RestrictedToken
|
||||
| codex_protocol::config_types::WindowsSandboxLevel::Disabled => {
|
||||
codex_windows_sandbox::spawn_windows_sandbox_session_legacy(
|
||||
policy_json.as_str(),
|
||||
&request.permission_profile,
|
||||
request.windows_sandbox_policy_cwd.as_path(),
|
||||
codex_home.as_ref(),
|
||||
request.command.clone(),
|
||||
|
||||
@@ -8,7 +8,7 @@ use codex_features::FeaturesToml;
|
||||
use codex_login::default_client::originator;
|
||||
use codex_otel::sanitize_metric_tag_value;
|
||||
use codex_protocol::config_types::WindowsSandboxLevel;
|
||||
use codex_protocol::protocol::SandboxPolicy;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
@@ -145,16 +145,17 @@ pub fn elevated_setup_failure_metric_name(_err: &anyhow::Error) -> &'static str
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn run_elevated_setup(
|
||||
policy: &SandboxPolicy,
|
||||
policy_cwd: &Path,
|
||||
permission_profile: &PermissionProfile,
|
||||
permission_profile_cwd: &Path,
|
||||
command_cwd: &Path,
|
||||
env_map: &HashMap<String, String>,
|
||||
codex_home: &Path,
|
||||
) -> anyhow::Result<()> {
|
||||
let permissions =
|
||||
codex_windows_sandbox::ResolvedWindowsSandboxPermissions::from_legacy_policy_for_cwd(
|
||||
policy, policy_cwd,
|
||||
);
|
||||
codex_windows_sandbox::ResolvedWindowsSandboxPermissions::try_from_permission_profile_for_cwd(
|
||||
permission_profile,
|
||||
permission_profile_cwd,
|
||||
)?;
|
||||
codex_windows_sandbox::run_elevated_setup(
|
||||
codex_windows_sandbox::SandboxSetupRequest {
|
||||
permissions: &permissions,
|
||||
@@ -169,8 +170,8 @@ pub fn run_elevated_setup(
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub fn run_elevated_setup(
|
||||
_policy: &SandboxPolicy,
|
||||
_policy_cwd: &Path,
|
||||
_permission_profile: &PermissionProfile,
|
||||
_permission_profile_cwd: &Path,
|
||||
_command_cwd: &Path,
|
||||
_env_map: &HashMap<String, String>,
|
||||
_codex_home: &Path,
|
||||
@@ -180,15 +181,15 @@ pub fn run_elevated_setup(
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn run_legacy_setup_preflight(
|
||||
policy: &SandboxPolicy,
|
||||
policy_cwd: &Path,
|
||||
permission_profile: &PermissionProfile,
|
||||
permission_profile_cwd: &Path,
|
||||
command_cwd: &Path,
|
||||
env_map: &HashMap<String, String>,
|
||||
codex_home: &Path,
|
||||
) -> anyhow::Result<()> {
|
||||
codex_windows_sandbox::run_windows_sandbox_legacy_preflight(
|
||||
policy,
|
||||
policy_cwd,
|
||||
permission_profile,
|
||||
permission_profile_cwd,
|
||||
codex_home,
|
||||
command_cwd,
|
||||
env_map,
|
||||
@@ -197,16 +198,16 @@ pub fn run_legacy_setup_preflight(
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn run_setup_refresh_with_extra_read_roots(
|
||||
policy: &SandboxPolicy,
|
||||
policy_cwd: &Path,
|
||||
permission_profile: &PermissionProfile,
|
||||
permission_profile_cwd: &Path,
|
||||
command_cwd: &Path,
|
||||
env_map: &HashMap<String, String>,
|
||||
codex_home: &Path,
|
||||
extra_read_roots: Vec<PathBuf>,
|
||||
) -> anyhow::Result<()> {
|
||||
codex_windows_sandbox::run_setup_refresh_with_extra_read_roots(
|
||||
policy,
|
||||
policy_cwd,
|
||||
permission_profile,
|
||||
permission_profile_cwd,
|
||||
command_cwd,
|
||||
env_map,
|
||||
codex_home,
|
||||
@@ -217,8 +218,8 @@ pub fn run_setup_refresh_with_extra_read_roots(
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub fn run_legacy_setup_preflight(
|
||||
_policy: &SandboxPolicy,
|
||||
_policy_cwd: &Path,
|
||||
_permission_profile: &PermissionProfile,
|
||||
_permission_profile_cwd: &Path,
|
||||
_command_cwd: &Path,
|
||||
_env_map: &HashMap<String, String>,
|
||||
_codex_home: &Path,
|
||||
@@ -228,8 +229,8 @@ pub fn run_legacy_setup_preflight(
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub fn run_setup_refresh_with_extra_read_roots(
|
||||
_policy: &SandboxPolicy,
|
||||
_policy_cwd: &Path,
|
||||
_permission_profile: &PermissionProfile,
|
||||
_permission_profile_cwd: &Path,
|
||||
_command_cwd: &Path,
|
||||
_env_map: &HashMap<String, String>,
|
||||
_codex_home: &Path,
|
||||
@@ -247,8 +248,8 @@ pub enum WindowsSandboxSetupMode {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct WindowsSandboxSetupRequest {
|
||||
pub mode: WindowsSandboxSetupMode,
|
||||
pub policy: SandboxPolicy,
|
||||
pub policy_cwd: PathBuf,
|
||||
pub permission_profile: PermissionProfile,
|
||||
pub permission_profile_cwd: PathBuf,
|
||||
pub command_cwd: PathBuf,
|
||||
pub env_map: HashMap<String, String>,
|
||||
pub codex_home: PathBuf,
|
||||
@@ -285,8 +286,8 @@ async fn run_windows_sandbox_setup_and_persist(
|
||||
request: WindowsSandboxSetupRequest,
|
||||
) -> anyhow::Result<()> {
|
||||
let mode = request.mode;
|
||||
let policy = request.policy;
|
||||
let policy_cwd = request.policy_cwd;
|
||||
let permission_profile = request.permission_profile;
|
||||
let permission_profile_cwd = request.permission_profile_cwd;
|
||||
let command_cwd = request.command_cwd;
|
||||
let env_map = request.env_map;
|
||||
let codex_home = request.codex_home;
|
||||
@@ -297,8 +298,8 @@ async fn run_windows_sandbox_setup_and_persist(
|
||||
WindowsSandboxSetupMode::Elevated => {
|
||||
if !sandbox_setup_is_complete(setup_codex_home.as_path()) {
|
||||
run_elevated_setup(
|
||||
&policy,
|
||||
policy_cwd.as_path(),
|
||||
&permission_profile,
|
||||
permission_profile_cwd.as_path(),
|
||||
command_cwd.as_path(),
|
||||
&env_map,
|
||||
setup_codex_home.as_path(),
|
||||
@@ -307,8 +308,8 @@ async fn run_windows_sandbox_setup_and_persist(
|
||||
}
|
||||
WindowsSandboxSetupMode::Unelevated => {
|
||||
run_legacy_setup_preflight(
|
||||
&policy,
|
||||
policy_cwd.as_path(),
|
||||
&permission_profile,
|
||||
permission_profile_cwd.as_path(),
|
||||
command_cwd.as_path(),
|
||||
&env_map,
|
||||
setup_codex_home.as_path(),
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use crate::windows_sandbox::run_setup_refresh_with_extra_read_roots;
|
||||
use anyhow::Result;
|
||||
use codex_protocol::protocol::SandboxPolicy;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn grant_read_root_non_elevated(
|
||||
policy: &SandboxPolicy,
|
||||
policy_cwd: &Path,
|
||||
permission_profile: &PermissionProfile,
|
||||
permission_profile_cwd: &Path,
|
||||
command_cwd: &Path,
|
||||
env_map: &HashMap<String, String>,
|
||||
codex_home: &Path,
|
||||
@@ -25,8 +25,8 @@ pub fn grant_read_root_non_elevated(
|
||||
|
||||
let canonical_root = dunce::canonicalize(read_root)?;
|
||||
run_setup_refresh_with_extra_read_roots(
|
||||
policy,
|
||||
policy_cwd,
|
||||
permission_profile,
|
||||
permission_profile_cwd,
|
||||
command_cwd,
|
||||
env_map,
|
||||
codex_home,
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
use super::grant_read_root_non_elevated;
|
||||
use codex_protocol::protocol::SandboxPolicy;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn policy() -> SandboxPolicy {
|
||||
SandboxPolicy::new_workspace_write_policy()
|
||||
fn permission_profile() -> PermissionProfile {
|
||||
PermissionProfile::workspace_write()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_relative_path() {
|
||||
let tmp = TempDir::new().expect("tempdir");
|
||||
let err = grant_read_root_non_elevated(
|
||||
&policy(),
|
||||
&permission_profile(),
|
||||
tmp.path(),
|
||||
tmp.path(),
|
||||
&HashMap::new(),
|
||||
@@ -28,7 +28,7 @@ fn rejects_missing_path() {
|
||||
let tmp = TempDir::new().expect("tempdir");
|
||||
let missing = tmp.path().join("does-not-exist");
|
||||
let err = grant_read_root_non_elevated(
|
||||
&policy(),
|
||||
&permission_profile(),
|
||||
tmp.path(),
|
||||
tmp.path(),
|
||||
&HashMap::new(),
|
||||
@@ -45,7 +45,7 @@ fn rejects_file_path() {
|
||||
let file_path = tmp.path().join("file.txt");
|
||||
std::fs::write(&file_path, "hello").expect("write file");
|
||||
let err = grant_read_root_non_elevated(
|
||||
&policy(),
|
||||
&permission_profile(),
|
||||
tmp.path(),
|
||||
tmp.path(),
|
||||
&HashMap::new(),
|
||||
|
||||
Reference in New Issue
Block a user