Move workspace roots onto thread/session state and stop using active permission profile modifications as an overlay for writable roots. Existing app-server threads no longer accept arbitrary PermissionProfile or SandboxPolicy replacements; permissions requests select a server-known profile id and apply the resolved server-owned profile together with active profile metadata. Workspace roots can be updated independently, and SandboxPolicy::WorkspaceWrite no longer stores its own writable_roots.

This commit is contained in:
Michael Bolin
2026-05-11 23:00:07 -07:00
parent 9ab7f4e6ac
commit f6eacf7452
152 changed files with 4228 additions and 2683 deletions
+52 -8
View File
@@ -365,6 +365,7 @@ async fn process_exec_tool_call_preserves_full_buffer_capture_policy() -> Result
},
&permission_profile,
&cwd,
&[],
&None,
/*use_legacy_landlock*/ false,
/*stdout_stream*/ None,
@@ -470,7 +471,6 @@ fn windows_restricted_token_allows_legacy_restricted_policies() {
#[test]
fn windows_restricted_token_allows_legacy_workspace_write_policies() {
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
@@ -528,7 +528,6 @@ fn windows_restricted_token_rejects_split_only_filesystem_policies() {
let docs = temp_dir.path().join("docs");
std::fs::create_dir_all(&docs).expect("create docs");
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
@@ -573,7 +572,6 @@ fn windows_restricted_token_rejects_root_write_read_only_carveouts() {
let docs = temp_dir.path().join("docs");
std::fs::create_dir_all(&docs).expect("create docs");
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
@@ -619,7 +617,6 @@ fn windows_restricted_token_supports_full_read_split_write_read_carveouts() {
let docs = cwd.join("docs");
std::fs::create_dir_all(docs.as_path()).expect("create docs");
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
@@ -667,6 +664,56 @@ fn windows_restricted_token_supports_full_read_split_write_read_carveouts() {
);
}
#[test]
fn windows_restricted_token_supports_extra_split_writable_root_override() {
let temp_dir = tempfile::TempDir::new().expect("tempdir");
let cwd = dunce::canonicalize(temp_dir.path())
.expect("canonicalize temp dir")
.abs();
let extra_root = cwd.join("extra-root");
std::fs::create_dir_all(extra_root.as_path()).expect("create extra root");
let policy = SandboxPolicy::WorkspaceWrite {
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
};
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
codex_protocol::permissions::FileSystemSandboxEntry {
path: codex_protocol::permissions::FileSystemPath::Special {
value: codex_protocol::permissions::FileSystemSpecialPath::Root,
},
access: codex_protocol::permissions::FileSystemAccessMode::Read,
},
codex_protocol::permissions::FileSystemSandboxEntry {
path: codex_protocol::permissions::FileSystemPath::Path { path: cwd.clone() },
access: codex_protocol::permissions::FileSystemAccessMode::Write,
},
codex_protocol::permissions::FileSystemSandboxEntry {
path: codex_protocol::permissions::FileSystemPath::Path {
path: extra_root.clone(),
},
access: codex_protocol::permissions::FileSystemAccessMode::Write,
},
]);
assert_eq!(
resolve_windows_restricted_token_filesystem_overrides(
SandboxType::WindowsRestrictedToken,
&policy,
&file_system_policy,
NetworkSandboxPolicy::Restricted,
&cwd,
WindowsSandboxLevel::RestrictedToken,
),
Ok(Some(WindowsSandboxFilesystemOverrides {
read_roots_override: None,
read_roots_include_platform_defaults: false,
write_roots_override: Some(vec![cwd.to_path_buf(), extra_root.to_path_buf()]),
additional_deny_write_paths: vec![],
}))
);
}
#[test]
fn windows_elevated_supports_split_restricted_read_roots() {
let temp_dir = tempfile::TempDir::new().expect("tempdir");
@@ -711,7 +758,6 @@ fn windows_elevated_supports_split_write_read_carveouts() {
std::fs::create_dir_all(&docs).expect("create docs");
let expected_docs = dunce::canonicalize(&docs).expect("canonical docs");
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
@@ -767,7 +813,6 @@ fn windows_elevated_rejects_unreadable_split_carveouts() {
let blocked = temp_dir.path().join("blocked");
std::fs::create_dir_all(&blocked).expect("create blocked");
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
@@ -816,7 +861,6 @@ fn windows_elevated_rejects_unreadable_split_carveouts() {
fn windows_elevated_rejects_unreadable_globs() {
let temp_dir = tempfile::TempDir::new().expect("tempdir");
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
@@ -867,7 +911,6 @@ fn windows_elevated_rejects_reopened_writable_descendants() {
let nested = docs.join("nested");
std::fs::create_dir_all(&nested).expect("create nested");
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
@@ -1040,6 +1083,7 @@ async fn process_exec_tool_call_respects_cancellation_token() -> Result<()> {
params,
&PermissionProfile::Disabled,
&cwd,
&[],
&None,
/*use_legacy_landlock*/ false,
/*stdout_stream*/ None,