mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
core: stop threading SandboxPolicy through exec (#25700)
## Why #25450 attempts a broad `SandboxPolicy` removal across several unrelated surfaces, which makes it hard to review and still leaves new helper code moving legacy policies around. This PR is a narrower alternative: migrate only the exec-side Windows sandbox plumbing so the review can focus on one production path and one compatibility boundary. The goal is to stop threading `SandboxPolicy` through exec code without expanding the migration into app-server, protocol, telemetry, config, or session behavior. ## What changed - Removed `ExecRequest::compatibility_sandbox_policy()`. - Changed the Windows restricted-token and elevated filesystem override helpers to accept `PermissionProfile` plus the split filesystem/network policies instead of a `SandboxPolicy`. - Kept the remaining legacy projection local to the writable-root comparison that still needs to compare split policy behavior against the legacy Windows backend model. - Rejected restricted split filesystem policies that still grant full-disk writes before using the Windows restricted-token backend, preserving the previous clear-failure behavior for profiles that project to `ExternalSandbox`. - Updated the Windows sandbox override tests to exercise the new call shape and cover the full-write split-profile regression. ## Verification - `just test -p codex-core windows_restricted_token` - `just test -p codex-core windows_elevated`
This commit is contained in:
1 parent
a2a9e767f7
commit
52b359b249
10 files changed
+167
-233
No files matched your search
@@ -179,11 +179,8 @@ pub(crate) fn thread_response_sandbox_policy(
|
|||||||
permission_profile: &codex_protocol::models::PermissionProfile,
|
permission_profile: &codex_protocol::models::PermissionProfile,
|
||||||
cwd: &Path,
|
cwd: &Path,
|
||||||
) -> codex_app_server_protocol::SandboxPolicy {
|
) -> codex_app_server_protocol::SandboxPolicy {
|
||||||
let file_system_policy = permission_profile.file_system_sandbox_policy();
|
|
||||||
let sandbox_policy = codex_sandboxing::compatibility_sandbox_policy_for_permission_profile(
|
let sandbox_policy = codex_sandboxing::compatibility_sandbox_policy_for_permission_profile(
|
||||||
permission_profile,
|
permission_profile,
|
||||||
&file_system_policy,
|
|
||||||
permission_profile.network_sandbox_policy(),
|
|
||||||
cwd,
|
cwd,
|
||||||
);
|
);
|
||||||
sandbox_policy.into()
|
sandbox_policy.into()
|
||||||
|
|||||||
@@ -76,11 +76,8 @@ pub struct ThreadConfigSnapshot {
|
|||||||
|
|
||||||
impl ThreadConfigSnapshot {
|
impl ThreadConfigSnapshot {
|
||||||
pub fn sandbox_policy(&self) -> SandboxPolicy {
|
pub fn sandbox_policy(&self) -> SandboxPolicy {
|
||||||
let file_system_sandbox_policy = self.permission_profile.file_system_sandbox_policy();
|
|
||||||
codex_sandboxing::compatibility_sandbox_policy_for_permission_profile(
|
codex_sandboxing::compatibility_sandbox_policy_for_permission_profile(
|
||||||
&self.permission_profile,
|
&self.permission_profile,
|
||||||
&file_system_sandbox_policy,
|
|
||||||
self.permission_profile.network_sandbox_policy(),
|
|
||||||
self.cwd.as_path(),
|
self.cwd.as_path(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -444,13 +444,7 @@ impl Permissions {
|
|||||||
/// Legacy compatibility projection derived from the canonical profile.
|
/// Legacy compatibility projection derived from the canonical profile.
|
||||||
pub fn legacy_sandbox_policy(&self, cwd: &Path) -> SandboxPolicy {
|
pub fn legacy_sandbox_policy(&self, cwd: &Path) -> SandboxPolicy {
|
||||||
let permission_profile = self.materialized_permission_profile();
|
let permission_profile = self.materialized_permission_profile();
|
||||||
let file_system_sandbox_policy = permission_profile.file_system_sandbox_policy();
|
compatibility_sandbox_policy_for_permission_profile(&permission_profile, cwd)
|
||||||
compatibility_sandbox_policy_for_permission_profile(
|
|
||||||
&permission_profile,
|
|
||||||
&file_system_sandbox_policy,
|
|
||||||
permission_profile.network_sandbox_policy(),
|
|
||||||
cwd,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check whether a legacy sandbox policy can be applied to this permission
|
/// Check whether a legacy sandbox policy can be applied to this permission
|
||||||
|
|||||||
+52
-57
@@ -31,19 +31,18 @@ use codex_protocol::error::SandboxErr;
|
|||||||
use codex_protocol::exec_output::ExecToolCallOutput;
|
use codex_protocol::exec_output::ExecToolCallOutput;
|
||||||
use codex_protocol::exec_output::StreamOutput;
|
use codex_protocol::exec_output::StreamOutput;
|
||||||
use codex_protocol::models::PermissionProfile;
|
use codex_protocol::models::PermissionProfile;
|
||||||
use codex_protocol::permissions::FileSystemSandboxKind;
|
|
||||||
use codex_protocol::permissions::FileSystemSandboxPolicy;
|
use codex_protocol::permissions::FileSystemSandboxPolicy;
|
||||||
use codex_protocol::permissions::NetworkSandboxPolicy;
|
use codex_protocol::permissions::NetworkSandboxPolicy;
|
||||||
use codex_protocol::protocol::Event;
|
use codex_protocol::protocol::Event;
|
||||||
use codex_protocol::protocol::EventMsg;
|
use codex_protocol::protocol::EventMsg;
|
||||||
use codex_protocol::protocol::ExecCommandOutputDeltaEvent;
|
use codex_protocol::protocol::ExecCommandOutputDeltaEvent;
|
||||||
use codex_protocol::protocol::ExecOutputStream;
|
use codex_protocol::protocol::ExecOutputStream;
|
||||||
use codex_protocol::protocol::SandboxPolicy;
|
|
||||||
use codex_sandboxing::SandboxCommand;
|
use codex_sandboxing::SandboxCommand;
|
||||||
use codex_sandboxing::SandboxManager;
|
use codex_sandboxing::SandboxManager;
|
||||||
use codex_sandboxing::SandboxTransformRequest;
|
use codex_sandboxing::SandboxTransformRequest;
|
||||||
use codex_sandboxing::SandboxType;
|
use codex_sandboxing::SandboxType;
|
||||||
use codex_sandboxing::SandboxablePreference;
|
use codex_sandboxing::SandboxablePreference;
|
||||||
|
use codex_sandboxing::compatibility_sandbox_policy_for_permission_profile;
|
||||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||||
use codex_utils_pty::DEFAULT_OUTPUT_BYTES_CAP;
|
use codex_utils_pty::DEFAULT_OUTPUT_BYTES_CAP;
|
||||||
use codex_utils_pty::process_group::kill_child_process_group;
|
use codex_utils_pty::process_group::kill_child_process_group;
|
||||||
@@ -419,22 +418,17 @@ pub fn build_exec_request(
|
|||||||
exec_req.windows_sandbox_level,
|
exec_req.windows_sandbox_level,
|
||||||
exec_req.network.is_some(),
|
exec_req.network.is_some(),
|
||||||
);
|
);
|
||||||
let sandbox_policy = exec_req.compatibility_sandbox_policy();
|
|
||||||
exec_req.windows_sandbox_filesystem_overrides = if use_windows_elevated_backend {
|
exec_req.windows_sandbox_filesystem_overrides = if use_windows_elevated_backend {
|
||||||
resolve_windows_elevated_filesystem_overrides(
|
resolve_windows_elevated_filesystem_overrides(
|
||||||
exec_req.sandbox,
|
exec_req.sandbox,
|
||||||
&sandbox_policy,
|
&exec_req.permission_profile,
|
||||||
&exec_req.file_system_sandbox_policy,
|
|
||||||
exec_req.network_sandbox_policy,
|
|
||||||
sandbox_cwd,
|
sandbox_cwd,
|
||||||
use_windows_elevated_backend,
|
use_windows_elevated_backend,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
resolve_windows_restricted_token_filesystem_overrides(
|
resolve_windows_restricted_token_filesystem_overrides(
|
||||||
exec_req.sandbox,
|
exec_req.sandbox,
|
||||||
&sandbox_policy,
|
&exec_req.permission_profile,
|
||||||
&exec_req.file_system_sandbox_policy,
|
|
||||||
exec_req.network_sandbox_policy,
|
|
||||||
sandbox_cwd,
|
sandbox_cwd,
|
||||||
exec_req.windows_sandbox_level,
|
exec_req.windows_sandbox_level,
|
||||||
)
|
)
|
||||||
@@ -1004,34 +998,28 @@ async fn exec(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
|
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
|
||||||
fn should_use_windows_restricted_token_sandbox(
|
fn permission_profile_supports_windows_restricted_token_sandbox(
|
||||||
sandbox: SandboxType,
|
permission_profile: &PermissionProfile,
|
||||||
sandbox_policy: &SandboxPolicy,
|
|
||||||
file_system_sandbox_policy: &FileSystemSandboxPolicy,
|
|
||||||
) -> bool {
|
) -> bool {
|
||||||
sandbox == SandboxType::WindowsRestrictedToken
|
match permission_profile {
|
||||||
&& file_system_sandbox_policy.kind == FileSystemSandboxKind::Restricted
|
PermissionProfile::Managed { file_system, .. } => {
|
||||||
&& !matches!(
|
!file_system.to_sandbox_policy().has_full_disk_write_access()
|
||||||
sandbox_policy,
|
}
|
||||||
SandboxPolicy::DangerFullAccess | SandboxPolicy::ExternalSandbox { .. }
|
PermissionProfile::Disabled | PermissionProfile::External { .. } => false,
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(test), allow(dead_code))]
|
#[cfg_attr(not(test), allow(dead_code))]
|
||||||
pub(crate) fn unsupported_windows_restricted_token_sandbox_reason(
|
pub(crate) fn unsupported_windows_restricted_token_sandbox_reason(
|
||||||
sandbox: SandboxType,
|
sandbox: SandboxType,
|
||||||
sandbox_policy: &SandboxPolicy,
|
permission_profile: &PermissionProfile,
|
||||||
file_system_sandbox_policy: &FileSystemSandboxPolicy,
|
|
||||||
network_sandbox_policy: NetworkSandboxPolicy,
|
|
||||||
sandbox_policy_cwd: &AbsolutePathBuf,
|
sandbox_policy_cwd: &AbsolutePathBuf,
|
||||||
windows_sandbox_level: WindowsSandboxLevel,
|
windows_sandbox_level: WindowsSandboxLevel,
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
if windows_sandbox_level == WindowsSandboxLevel::Elevated {
|
if windows_sandbox_level == WindowsSandboxLevel::Elevated {
|
||||||
resolve_windows_elevated_filesystem_overrides(
|
resolve_windows_elevated_filesystem_overrides(
|
||||||
sandbox,
|
sandbox,
|
||||||
sandbox_policy,
|
permission_profile,
|
||||||
file_system_sandbox_policy,
|
|
||||||
network_sandbox_policy,
|
|
||||||
sandbox_policy_cwd,
|
sandbox_policy_cwd,
|
||||||
windows_sandbox_level == WindowsSandboxLevel::Elevated,
|
windows_sandbox_level == WindowsSandboxLevel::Elevated,
|
||||||
)
|
)
|
||||||
@@ -1039,9 +1027,7 @@ pub(crate) fn unsupported_windows_restricted_token_sandbox_reason(
|
|||||||
} else {
|
} else {
|
||||||
resolve_windows_restricted_token_filesystem_overrides(
|
resolve_windows_restricted_token_filesystem_overrides(
|
||||||
sandbox,
|
sandbox,
|
||||||
sandbox_policy,
|
permission_profile,
|
||||||
file_system_sandbox_policy,
|
|
||||||
network_sandbox_policy,
|
|
||||||
sandbox_policy_cwd,
|
sandbox_policy_cwd,
|
||||||
windows_sandbox_level,
|
windows_sandbox_level,
|
||||||
)
|
)
|
||||||
@@ -1051,9 +1037,7 @@ pub(crate) fn unsupported_windows_restricted_token_sandbox_reason(
|
|||||||
|
|
||||||
pub(crate) fn resolve_windows_restricted_token_filesystem_overrides(
|
pub(crate) fn resolve_windows_restricted_token_filesystem_overrides(
|
||||||
sandbox: SandboxType,
|
sandbox: SandboxType,
|
||||||
sandbox_policy: &SandboxPolicy,
|
permission_profile: &PermissionProfile,
|
||||||
file_system_sandbox_policy: &FileSystemSandboxPolicy,
|
|
||||||
network_sandbox_policy: NetworkSandboxPolicy,
|
|
||||||
sandbox_policy_cwd: &AbsolutePathBuf,
|
sandbox_policy_cwd: &AbsolutePathBuf,
|
||||||
windows_sandbox_level: WindowsSandboxLevel,
|
windows_sandbox_level: WindowsSandboxLevel,
|
||||||
) -> std::result::Result<Option<WindowsSandboxFilesystemOverrides>, String> {
|
) -> std::result::Result<Option<WindowsSandboxFilesystemOverrides>, String> {
|
||||||
@@ -1063,25 +1047,22 @@ pub(crate) fn resolve_windows_restricted_token_filesystem_overrides(
|
|||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (file_system_sandbox_policy, network_sandbox_policy) =
|
||||||
|
permission_profile.to_runtime_permissions();
|
||||||
|
|
||||||
let needs_direct_runtime_enforcement = file_system_sandbox_policy
|
let needs_direct_runtime_enforcement = file_system_sandbox_policy
|
||||||
.needs_direct_runtime_enforcement(network_sandbox_policy, sandbox_policy_cwd);
|
.needs_direct_runtime_enforcement(network_sandbox_policy, sandbox_policy_cwd);
|
||||||
|
|
||||||
if should_use_windows_restricted_token_sandbox(
|
if permission_profile_supports_windows_restricted_token_sandbox(permission_profile)
|
||||||
sandbox,
|
&& !needs_direct_runtime_enforcement
|
||||||
sandbox_policy,
|
|
||||||
file_system_sandbox_policy,
|
|
||||||
) && !needs_direct_runtime_enforcement
|
|
||||||
{
|
{
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !should_use_windows_restricted_token_sandbox(
|
if !permission_profile_supports_windows_restricted_token_sandbox(permission_profile) {
|
||||||
sandbox,
|
let permission_profile_name = permission_profile_display_name(permission_profile);
|
||||||
sandbox_policy,
|
|
||||||
file_system_sandbox_policy,
|
|
||||||
) {
|
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"windows sandbox backend cannot enforce file_system={:?}, network={network_sandbox_policy:?}, legacy_policy={sandbox_policy:?}; refusing to run unsandboxed",
|
"windows sandbox backend cannot enforce file_system={:?}, network={network_sandbox_policy:?}, permission_profile={permission_profile_name}; refusing to run unsandboxed",
|
||||||
file_system_sandbox_policy.kind,
|
file_system_sandbox_policy.kind,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -1090,7 +1071,7 @@ pub(crate) fn resolve_windows_restricted_token_filesystem_overrides(
|
|||||||
// but its WRITE_RESTRICTED token does not make capability SID deny-read ACEs
|
// but its WRITE_RESTRICTED token does not make capability SID deny-read ACEs
|
||||||
// participate in read access checks. Read restrictions therefore require the
|
// participate in read access checks. Read restrictions therefore require the
|
||||||
// elevated backend, even when the filesystem root remains readable.
|
// elevated backend, even when the filesystem root remains readable.
|
||||||
if !windows_policy_has_root_read_access(file_system_sandbox_policy, sandbox_policy_cwd) {
|
if !windows_policy_has_root_read_access(&file_system_sandbox_policy, sandbox_policy_cwd) {
|
||||||
return Err(
|
return Err(
|
||||||
"windows unelevated restricted-token sandbox cannot enforce split filesystem read restrictions directly; refusing to run unsandboxed"
|
"windows unelevated restricted-token sandbox cannot enforce split filesystem read restrictions directly; refusing to run unsandboxed"
|
||||||
.to_string(),
|
.to_string(),
|
||||||
@@ -1098,7 +1079,7 @@ pub(crate) fn resolve_windows_restricted_token_filesystem_overrides(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let additional_deny_read_paths = codex_windows_sandbox::resolve_windows_deny_read_paths(
|
let additional_deny_read_paths = codex_windows_sandbox::resolve_windows_deny_read_paths(
|
||||||
file_system_sandbox_policy,
|
&file_system_sandbox_policy,
|
||||||
sandbox_policy_cwd,
|
sandbox_policy_cwd,
|
||||||
)?;
|
)?;
|
||||||
if !additional_deny_read_paths.is_empty() {
|
if !additional_deny_read_paths.is_empty() {
|
||||||
@@ -1108,7 +1089,11 @@ pub(crate) fn resolve_windows_restricted_token_filesystem_overrides(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let legacy_writable_roots = sandbox_policy.get_writable_roots_with_cwd(sandbox_policy_cwd);
|
let legacy_projection = compatibility_sandbox_policy_for_permission_profile(
|
||||||
|
permission_profile,
|
||||||
|
sandbox_policy_cwd.as_path(),
|
||||||
|
);
|
||||||
|
let legacy_writable_roots = legacy_projection.get_writable_roots_with_cwd(sandbox_policy_cwd);
|
||||||
let split_writable_roots =
|
let split_writable_roots =
|
||||||
file_system_sandbox_policy.get_writable_roots_with_cwd(sandbox_policy_cwd);
|
file_system_sandbox_policy.get_writable_roots_with_cwd(sandbox_policy_cwd);
|
||||||
let legacy_root_paths: BTreeSet<PathBuf> = legacy_writable_roots
|
let legacy_root_paths: BTreeSet<PathBuf> = legacy_writable_roots
|
||||||
@@ -1204,9 +1189,7 @@ fn windows_policy_has_root_read_access(
|
|||||||
|
|
||||||
pub(crate) fn resolve_windows_elevated_filesystem_overrides(
|
pub(crate) fn resolve_windows_elevated_filesystem_overrides(
|
||||||
sandbox: SandboxType,
|
sandbox: SandboxType,
|
||||||
sandbox_policy: &SandboxPolicy,
|
permission_profile: &PermissionProfile,
|
||||||
file_system_sandbox_policy: &FileSystemSandboxPolicy,
|
|
||||||
network_sandbox_policy: NetworkSandboxPolicy,
|
|
||||||
sandbox_policy_cwd: &AbsolutePathBuf,
|
sandbox_policy_cwd: &AbsolutePathBuf,
|
||||||
use_windows_elevated_backend: bool,
|
use_windows_elevated_backend: bool,
|
||||||
) -> std::result::Result<Option<WindowsSandboxFilesystemOverrides>, String> {
|
) -> std::result::Result<Option<WindowsSandboxFilesystemOverrides>, String> {
|
||||||
@@ -1214,19 +1197,19 @@ pub(crate) fn resolve_windows_elevated_filesystem_overrides(
|
|||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !should_use_windows_restricted_token_sandbox(
|
let (file_system_sandbox_policy, network_sandbox_policy) =
|
||||||
sandbox,
|
permission_profile.to_runtime_permissions();
|
||||||
sandbox_policy,
|
|
||||||
file_system_sandbox_policy,
|
if !permission_profile_supports_windows_restricted_token_sandbox(permission_profile) {
|
||||||
) {
|
let permission_profile_name = permission_profile_display_name(permission_profile);
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"windows sandbox backend cannot enforce file_system={:?}, network={network_sandbox_policy:?}, legacy_policy={sandbox_policy:?}; refusing to run unsandboxed",
|
"windows sandbox backend cannot enforce file_system={:?}, network={network_sandbox_policy:?}, permission_profile={permission_profile_name}; refusing to run unsandboxed",
|
||||||
file_system_sandbox_policy.kind,
|
file_system_sandbox_policy.kind,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let additional_deny_read_paths = codex_windows_sandbox::resolve_windows_deny_read_paths(
|
let additional_deny_read_paths = codex_windows_sandbox::resolve_windows_deny_read_paths(
|
||||||
file_system_sandbox_policy,
|
&file_system_sandbox_policy,
|
||||||
sandbox_policy_cwd,
|
sandbox_policy_cwd,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@@ -1242,7 +1225,11 @@ pub(crate) fn resolve_windows_elevated_filesystem_overrides(
|
|||||||
let needs_direct_runtime_enforcement = file_system_sandbox_policy
|
let needs_direct_runtime_enforcement = file_system_sandbox_policy
|
||||||
.needs_direct_runtime_enforcement(network_sandbox_policy, sandbox_policy_cwd);
|
.needs_direct_runtime_enforcement(network_sandbox_policy, sandbox_policy_cwd);
|
||||||
let normalize_path = |path: PathBuf| dunce::canonicalize(&path).unwrap_or(path);
|
let normalize_path = |path: PathBuf| dunce::canonicalize(&path).unwrap_or(path);
|
||||||
let legacy_writable_roots = sandbox_policy.get_writable_roots_with_cwd(sandbox_policy_cwd);
|
let legacy_projection = compatibility_sandbox_policy_for_permission_profile(
|
||||||
|
permission_profile,
|
||||||
|
sandbox_policy_cwd.as_path(),
|
||||||
|
);
|
||||||
|
let legacy_writable_roots = legacy_projection.get_writable_roots_with_cwd(sandbox_policy_cwd);
|
||||||
let legacy_root_paths: BTreeSet<PathBuf> = legacy_writable_roots
|
let legacy_root_paths: BTreeSet<PathBuf> = legacy_writable_roots
|
||||||
.iter()
|
.iter()
|
||||||
.map(|root| normalize_path(root.root.to_path_buf()))
|
.map(|root| normalize_path(root.root.to_path_buf()))
|
||||||
@@ -1264,7 +1251,7 @@ pub(crate) fn resolve_windows_elevated_filesystem_overrides(
|
|||||||
// whether the baseline still reads from the filesystem root and only needs
|
// whether the baseline still reads from the filesystem root and only needs
|
||||||
// additional deny ACLs layered on top.
|
// additional deny ACLs layered on top.
|
||||||
let split_has_root_read_access =
|
let split_has_root_read_access =
|
||||||
windows_policy_has_root_read_access(file_system_sandbox_policy, sandbox_policy_cwd);
|
windows_policy_has_root_read_access(&file_system_sandbox_policy, sandbox_policy_cwd);
|
||||||
let read_roots_override = if split_has_root_read_access {
|
let read_roots_override = if split_has_root_read_access {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
@@ -1329,6 +1316,14 @@ pub(crate) fn resolve_windows_elevated_filesystem_overrides(
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn permission_profile_display_name(permission_profile: &PermissionProfile) -> &'static str {
|
||||||
|
match permission_profile {
|
||||||
|
PermissionProfile::Managed { .. } => "Managed",
|
||||||
|
PermissionProfile::Disabled => "Disabled",
|
||||||
|
PermissionProfile::External { .. } => "External",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn has_reopened_writable_descendant(
|
fn has_reopened_writable_descendant(
|
||||||
writable_roots: &[codex_protocol::protocol::WritableRoot],
|
writable_roots: &[codex_protocol::protocol::WritableRoot],
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
|||||||
+106
-133
@@ -379,34 +379,18 @@ async fn process_exec_tool_call_preserves_full_buffer_capture_policy() -> Result
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn windows_restricted_token_skips_external_sandbox_policies() {
|
fn windows_restricted_token_skips_external_sandbox_policies() {
|
||||||
let policy = SandboxPolicy::ExternalSandbox {
|
let permission_profile = PermissionProfile::External {
|
||||||
network_access: codex_protocol::protocol::NetworkAccess::Restricted,
|
network: NetworkSandboxPolicy::Restricted,
|
||||||
};
|
};
|
||||||
let file_system_policy = FileSystemSandboxPolicy::from(&policy);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert!(!permission_profile_supports_windows_restricted_token_sandbox(&permission_profile));
|
||||||
should_use_windows_restricted_token_sandbox(
|
|
||||||
SandboxType::WindowsRestrictedToken,
|
|
||||||
&policy,
|
|
||||||
&file_system_policy,
|
|
||||||
),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn windows_restricted_token_runs_for_legacy_restricted_policies() {
|
fn windows_restricted_token_supports_read_only_profiles() {
|
||||||
let policy = SandboxPolicy::new_read_only_policy();
|
let permission_profile = PermissionProfile::read_only();
|
||||||
let file_system_policy = FileSystemSandboxPolicy::from(&policy);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert!(permission_profile_supports_windows_restricted_token_sandbox(&permission_profile));
|
||||||
should_use_windows_restricted_token_sandbox(
|
|
||||||
SandboxType::WindowsRestrictedToken,
|
|
||||||
&policy,
|
|
||||||
&file_system_policy,
|
|
||||||
),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -427,39 +411,64 @@ fn windows_proxy_enforcement_uses_elevated_backend() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn windows_restricted_token_rejects_network_only_restrictions() {
|
fn windows_restricted_token_rejects_network_only_restrictions() {
|
||||||
let policy = SandboxPolicy::ExternalSandbox {
|
let permission_profile = PermissionProfile::from_runtime_permissions(
|
||||||
network_access: codex_protocol::protocol::NetworkAccess::Restricted,
|
&FileSystemSandboxPolicy::unrestricted(),
|
||||||
};
|
NetworkSandboxPolicy::Restricted,
|
||||||
let file_system_policy = FileSystemSandboxPolicy::unrestricted();
|
);
|
||||||
let sandbox_policy_cwd = AbsolutePathBuf::current_dir().expect("cwd");
|
let sandbox_policy_cwd = AbsolutePathBuf::current_dir().expect("cwd");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unsupported_windows_restricted_token_sandbox_reason(
|
unsupported_windows_restricted_token_sandbox_reason(
|
||||||
SandboxType::WindowsRestrictedToken,
|
SandboxType::WindowsRestrictedToken,
|
||||||
&policy,
|
&permission_profile,
|
||||||
&file_system_policy,
|
|
||||||
NetworkSandboxPolicy::Restricted,
|
|
||||||
&sandbox_policy_cwd,
|
&sandbox_policy_cwd,
|
||||||
WindowsSandboxLevel::RestrictedToken,
|
WindowsSandboxLevel::RestrictedToken,
|
||||||
),
|
),
|
||||||
Some(
|
Some(
|
||||||
"windows sandbox backend cannot enforce file_system=Unrestricted, network=Restricted, legacy_policy=ExternalSandbox { network_access: Restricted }; refusing to run unsandboxed".to_string()
|
"windows sandbox backend cannot enforce file_system=Unrestricted, network=Restricted, permission_profile=Managed; refusing to run unsandboxed".to_string()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn windows_restricted_token_allows_legacy_restricted_policies() {
|
fn windows_restricted_token_rejects_managed_root_write_profiles() {
|
||||||
let policy = SandboxPolicy::new_read_only_policy();
|
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
||||||
let file_system_policy = FileSystemSandboxPolicy::from(&policy);
|
codex_protocol::permissions::FileSystemSandboxEntry {
|
||||||
|
path: codex_protocol::permissions::FileSystemPath::Special {
|
||||||
|
value: codex_protocol::permissions::FileSystemSpecialPath::Root,
|
||||||
|
},
|
||||||
|
access: codex_protocol::permissions::FileSystemAccessMode::Write,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
let permission_profile = PermissionProfile::from_runtime_permissions(
|
||||||
|
&file_system_policy,
|
||||||
|
NetworkSandboxPolicy::Restricted,
|
||||||
|
);
|
||||||
let sandbox_policy_cwd = AbsolutePathBuf::current_dir().expect("cwd");
|
let sandbox_policy_cwd = AbsolutePathBuf::current_dir().expect("cwd");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unsupported_windows_restricted_token_sandbox_reason(
|
unsupported_windows_restricted_token_sandbox_reason(
|
||||||
SandboxType::WindowsRestrictedToken,
|
SandboxType::WindowsRestrictedToken,
|
||||||
&policy,
|
&permission_profile,
|
||||||
&file_system_policy,
|
&sandbox_policy_cwd,
|
||||||
NetworkSandboxPolicy::Restricted,
|
WindowsSandboxLevel::RestrictedToken,
|
||||||
|
),
|
||||||
|
Some(
|
||||||
|
"windows sandbox backend cannot enforce file_system=Restricted, network=Restricted, permission_profile=Managed; refusing to run unsandboxed"
|
||||||
|
.to_string()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn windows_restricted_token_allows_read_only_profiles() {
|
||||||
|
let permission_profile = PermissionProfile::read_only();
|
||||||
|
let sandbox_policy_cwd = AbsolutePathBuf::current_dir().expect("cwd");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
unsupported_windows_restricted_token_sandbox_reason(
|
||||||
|
SandboxType::WindowsRestrictedToken,
|
||||||
|
&permission_profile,
|
||||||
&sandbox_policy_cwd,
|
&sandbox_policy_cwd,
|
||||||
WindowsSandboxLevel::RestrictedToken,
|
WindowsSandboxLevel::RestrictedToken,
|
||||||
),
|
),
|
||||||
@@ -468,22 +477,19 @@ fn windows_restricted_token_allows_legacy_restricted_policies() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn windows_restricted_token_allows_legacy_workspace_write_policies() {
|
fn windows_restricted_token_allows_workspace_write_profiles() {
|
||||||
let policy = SandboxPolicy::WorkspaceWrite {
|
let permission_profile = PermissionProfile::workspace_write_with(
|
||||||
writable_roots: vec![],
|
&[],
|
||||||
network_access: false,
|
NetworkSandboxPolicy::Restricted,
|
||||||
exclude_tmpdir_env_var: true,
|
/*exclude_tmpdir_env_var*/ true,
|
||||||
exclude_slash_tmp: true,
|
/*exclude_slash_tmp*/ true,
|
||||||
};
|
);
|
||||||
let file_system_policy = FileSystemSandboxPolicy::from(&policy);
|
|
||||||
let sandbox_policy_cwd = AbsolutePathBuf::current_dir().expect("cwd");
|
let sandbox_policy_cwd = AbsolutePathBuf::current_dir().expect("cwd");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unsupported_windows_restricted_token_sandbox_reason(
|
unsupported_windows_restricted_token_sandbox_reason(
|
||||||
SandboxType::WindowsRestrictedToken,
|
SandboxType::WindowsRestrictedToken,
|
||||||
&policy,
|
&permission_profile,
|
||||||
&file_system_policy,
|
|
||||||
NetworkSandboxPolicy::Restricted,
|
|
||||||
&sandbox_policy_cwd,
|
&sandbox_policy_cwd,
|
||||||
WindowsSandboxLevel::RestrictedToken,
|
WindowsSandboxLevel::RestrictedToken,
|
||||||
),
|
),
|
||||||
@@ -499,22 +505,21 @@ fn windows_elevated_allows_split_restricted_read_policies() {
|
|||||||
)
|
)
|
||||||
.expect("absolute docs");
|
.expect("absolute docs");
|
||||||
std::fs::create_dir_all(docs.as_path()).expect("create docs");
|
std::fs::create_dir_all(docs.as_path()).expect("create docs");
|
||||||
let policy = SandboxPolicy::ReadOnly {
|
|
||||||
network_access: false,
|
|
||||||
};
|
|
||||||
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
||||||
codex_protocol::permissions::FileSystemSandboxEntry {
|
codex_protocol::permissions::FileSystemSandboxEntry {
|
||||||
path: codex_protocol::permissions::FileSystemPath::Path { path: docs },
|
path: codex_protocol::permissions::FileSystemPath::Path { path: docs },
|
||||||
access: codex_protocol::permissions::FileSystemAccessMode::Read,
|
access: codex_protocol::permissions::FileSystemAccessMode::Read,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
let permission_profile = PermissionProfile::from_runtime_permissions(
|
||||||
|
&file_system_policy,
|
||||||
|
NetworkSandboxPolicy::Restricted,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unsupported_windows_restricted_token_sandbox_reason(
|
unsupported_windows_restricted_token_sandbox_reason(
|
||||||
SandboxType::WindowsRestrictedToken,
|
SandboxType::WindowsRestrictedToken,
|
||||||
&policy,
|
&permission_profile,
|
||||||
&file_system_policy,
|
|
||||||
NetworkSandboxPolicy::Restricted,
|
|
||||||
&temp_dir.path().abs(),
|
&temp_dir.path().abs(),
|
||||||
WindowsSandboxLevel::Elevated,
|
WindowsSandboxLevel::Elevated,
|
||||||
),
|
),
|
||||||
@@ -527,12 +532,6 @@ fn windows_restricted_token_rejects_split_only_filesystem_policies() {
|
|||||||
let temp_dir = tempfile::TempDir::new().expect("tempdir");
|
let temp_dir = tempfile::TempDir::new().expect("tempdir");
|
||||||
let docs = temp_dir.path().join("docs");
|
let docs = temp_dir.path().join("docs");
|
||||||
std::fs::create_dir_all(&docs).expect("create 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,
|
|
||||||
};
|
|
||||||
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
||||||
codex_protocol::permissions::FileSystemSandboxEntry {
|
codex_protocol::permissions::FileSystemSandboxEntry {
|
||||||
path: codex_protocol::permissions::FileSystemPath::Special {
|
path: codex_protocol::permissions::FileSystemPath::Special {
|
||||||
@@ -550,13 +549,15 @@ fn windows_restricted_token_rejects_split_only_filesystem_policies() {
|
|||||||
access: codex_protocol::permissions::FileSystemAccessMode::Read,
|
access: codex_protocol::permissions::FileSystemAccessMode::Read,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
let permission_profile = PermissionProfile::from_runtime_permissions(
|
||||||
|
&file_system_policy,
|
||||||
|
NetworkSandboxPolicy::Restricted,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unsupported_windows_restricted_token_sandbox_reason(
|
unsupported_windows_restricted_token_sandbox_reason(
|
||||||
SandboxType::WindowsRestrictedToken,
|
SandboxType::WindowsRestrictedToken,
|
||||||
&policy,
|
&permission_profile,
|
||||||
&file_system_policy,
|
|
||||||
NetworkSandboxPolicy::Restricted,
|
|
||||||
&temp_dir.path().abs(),
|
&temp_dir.path().abs(),
|
||||||
WindowsSandboxLevel::RestrictedToken,
|
WindowsSandboxLevel::RestrictedToken,
|
||||||
),
|
),
|
||||||
@@ -572,12 +573,6 @@ fn windows_restricted_token_rejects_root_write_read_only_carveouts() {
|
|||||||
let temp_dir = tempfile::TempDir::new().expect("tempdir");
|
let temp_dir = tempfile::TempDir::new().expect("tempdir");
|
||||||
let docs = temp_dir.path().join("docs");
|
let docs = temp_dir.path().join("docs");
|
||||||
std::fs::create_dir_all(&docs).expect("create 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,
|
|
||||||
};
|
|
||||||
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
||||||
codex_protocol::permissions::FileSystemSandboxEntry {
|
codex_protocol::permissions::FileSystemSandboxEntry {
|
||||||
path: codex_protocol::permissions::FileSystemPath::Special {
|
path: codex_protocol::permissions::FileSystemPath::Special {
|
||||||
@@ -593,13 +588,15 @@ fn windows_restricted_token_rejects_root_write_read_only_carveouts() {
|
|||||||
access: codex_protocol::permissions::FileSystemAccessMode::Read,
|
access: codex_protocol::permissions::FileSystemAccessMode::Read,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
let permission_profile = PermissionProfile::from_runtime_permissions(
|
||||||
|
&file_system_policy,
|
||||||
|
NetworkSandboxPolicy::Restricted,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unsupported_windows_restricted_token_sandbox_reason(
|
unsupported_windows_restricted_token_sandbox_reason(
|
||||||
SandboxType::WindowsRestrictedToken,
|
SandboxType::WindowsRestrictedToken,
|
||||||
&policy,
|
&permission_profile,
|
||||||
&file_system_policy,
|
|
||||||
NetworkSandboxPolicy::Restricted,
|
|
||||||
&temp_dir.path().abs(),
|
&temp_dir.path().abs(),
|
||||||
WindowsSandboxLevel::RestrictedToken,
|
WindowsSandboxLevel::RestrictedToken,
|
||||||
),
|
),
|
||||||
@@ -618,12 +615,6 @@ fn windows_restricted_token_supports_full_read_split_write_read_carveouts() {
|
|||||||
.abs();
|
.abs();
|
||||||
let docs = cwd.join("docs");
|
let docs = cwd.join("docs");
|
||||||
std::fs::create_dir_all(docs.as_path()).expect("create 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,
|
|
||||||
};
|
|
||||||
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
||||||
codex_protocol::permissions::FileSystemSandboxEntry {
|
codex_protocol::permissions::FileSystemSandboxEntry {
|
||||||
path: codex_protocol::permissions::FileSystemPath::Special {
|
path: codex_protocol::permissions::FileSystemPath::Special {
|
||||||
@@ -644,17 +635,20 @@ fn windows_restricted_token_supports_full_read_split_write_read_carveouts() {
|
|||||||
access: codex_protocol::permissions::FileSystemAccessMode::Read,
|
access: codex_protocol::permissions::FileSystemAccessMode::Read,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
let permission_profile = PermissionProfile::from_runtime_permissions(
|
||||||
|
&file_system_policy,
|
||||||
|
NetworkSandboxPolicy::Restricted,
|
||||||
|
);
|
||||||
|
|
||||||
// The legacy workspace-write root already protects top-level `.codex`, so
|
// The workspace-write compatibility projection already protects top-level
|
||||||
// the restricted-token overlay only needs the extra read-only docs carveout.
|
// `.codex`, so the restricted-token overlay only needs the extra read-only
|
||||||
|
// docs carveout.
|
||||||
let expected_deny_write_paths = vec![docs];
|
let expected_deny_write_paths = vec![docs];
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resolve_windows_restricted_token_filesystem_overrides(
|
resolve_windows_restricted_token_filesystem_overrides(
|
||||||
SandboxType::WindowsRestrictedToken,
|
SandboxType::WindowsRestrictedToken,
|
||||||
&policy,
|
&permission_profile,
|
||||||
&file_system_policy,
|
|
||||||
NetworkSandboxPolicy::Restricted,
|
|
||||||
&cwd,
|
&cwd,
|
||||||
WindowsSandboxLevel::RestrictedToken,
|
WindowsSandboxLevel::RestrictedToken,
|
||||||
),
|
),
|
||||||
@@ -676,12 +670,6 @@ fn windows_restricted_token_rejects_unreadable_split_carveouts() {
|
|||||||
.abs();
|
.abs();
|
||||||
let blocked = cwd.join("blocked");
|
let blocked = cwd.join("blocked");
|
||||||
std::fs::create_dir_all(blocked.as_path()).expect("create blocked");
|
std::fs::create_dir_all(blocked.as_path()).expect("create blocked");
|
||||||
let policy = SandboxPolicy::WorkspaceWrite {
|
|
||||||
writable_roots: vec![],
|
|
||||||
network_access: false,
|
|
||||||
exclude_tmpdir_env_var: true,
|
|
||||||
exclude_slash_tmp: true,
|
|
||||||
};
|
|
||||||
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
||||||
codex_protocol::permissions::FileSystemSandboxEntry {
|
codex_protocol::permissions::FileSystemSandboxEntry {
|
||||||
path: codex_protocol::permissions::FileSystemPath::Special {
|
path: codex_protocol::permissions::FileSystemPath::Special {
|
||||||
@@ -702,13 +690,15 @@ fn windows_restricted_token_rejects_unreadable_split_carveouts() {
|
|||||||
access: codex_protocol::permissions::FileSystemAccessMode::Deny,
|
access: codex_protocol::permissions::FileSystemAccessMode::Deny,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
let permission_profile = PermissionProfile::from_runtime_permissions(
|
||||||
|
&file_system_policy,
|
||||||
|
NetworkSandboxPolicy::Restricted,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resolve_windows_restricted_token_filesystem_overrides(
|
resolve_windows_restricted_token_filesystem_overrides(
|
||||||
SandboxType::WindowsRestrictedToken,
|
SandboxType::WindowsRestrictedToken,
|
||||||
&policy,
|
&permission_profile,
|
||||||
&file_system_policy,
|
|
||||||
NetworkSandboxPolicy::Restricted,
|
|
||||||
&cwd,
|
&cwd,
|
||||||
WindowsSandboxLevel::RestrictedToken,
|
WindowsSandboxLevel::RestrictedToken,
|
||||||
),
|
),
|
||||||
@@ -725,9 +715,6 @@ fn windows_elevated_supports_split_restricted_read_roots() {
|
|||||||
let docs = temp_dir.path().join("docs");
|
let docs = temp_dir.path().join("docs");
|
||||||
std::fs::create_dir_all(&docs).expect("create docs");
|
std::fs::create_dir_all(&docs).expect("create docs");
|
||||||
let expected_docs = dunce::canonicalize(&docs).expect("canonical docs");
|
let expected_docs = dunce::canonicalize(&docs).expect("canonical docs");
|
||||||
let policy = SandboxPolicy::ReadOnly {
|
|
||||||
network_access: false,
|
|
||||||
};
|
|
||||||
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
||||||
codex_protocol::permissions::FileSystemSandboxEntry {
|
codex_protocol::permissions::FileSystemSandboxEntry {
|
||||||
path: codex_protocol::permissions::FileSystemPath::Path {
|
path: codex_protocol::permissions::FileSystemPath::Path {
|
||||||
@@ -737,13 +724,15 @@ fn windows_elevated_supports_split_restricted_read_roots() {
|
|||||||
access: codex_protocol::permissions::FileSystemAccessMode::Read,
|
access: codex_protocol::permissions::FileSystemAccessMode::Read,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
let permission_profile = PermissionProfile::from_runtime_permissions(
|
||||||
|
&file_system_policy,
|
||||||
|
NetworkSandboxPolicy::Restricted,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resolve_windows_elevated_filesystem_overrides(
|
resolve_windows_elevated_filesystem_overrides(
|
||||||
SandboxType::WindowsRestrictedToken,
|
SandboxType::WindowsRestrictedToken,
|
||||||
&policy,
|
&permission_profile,
|
||||||
&file_system_policy,
|
|
||||||
NetworkSandboxPolicy::Restricted,
|
|
||||||
&temp_dir.path().abs(),
|
&temp_dir.path().abs(),
|
||||||
/*use_windows_elevated_backend*/ true,
|
/*use_windows_elevated_backend*/ true,
|
||||||
),
|
),
|
||||||
@@ -763,12 +752,6 @@ fn windows_elevated_supports_split_write_read_carveouts() {
|
|||||||
let docs = temp_dir.path().join("docs");
|
let docs = temp_dir.path().join("docs");
|
||||||
std::fs::create_dir_all(&docs).expect("create docs");
|
std::fs::create_dir_all(&docs).expect("create docs");
|
||||||
let expected_docs = dunce::canonicalize(&docs).expect("canonical 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,
|
|
||||||
};
|
|
||||||
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
||||||
codex_protocol::permissions::FileSystemSandboxEntry {
|
codex_protocol::permissions::FileSystemSandboxEntry {
|
||||||
path: codex_protocol::permissions::FileSystemPath::Special {
|
path: codex_protocol::permissions::FileSystemPath::Special {
|
||||||
@@ -792,13 +775,15 @@ fn windows_elevated_supports_split_write_read_carveouts() {
|
|||||||
access: codex_protocol::permissions::FileSystemAccessMode::Read,
|
access: codex_protocol::permissions::FileSystemAccessMode::Read,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
let permission_profile = PermissionProfile::from_runtime_permissions(
|
||||||
|
&file_system_policy,
|
||||||
|
NetworkSandboxPolicy::Restricted,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resolve_windows_elevated_filesystem_overrides(
|
resolve_windows_elevated_filesystem_overrides(
|
||||||
SandboxType::WindowsRestrictedToken,
|
SandboxType::WindowsRestrictedToken,
|
||||||
&policy,
|
&permission_profile,
|
||||||
&file_system_policy,
|
|
||||||
NetworkSandboxPolicy::Restricted,
|
|
||||||
&temp_dir.path().abs(),
|
&temp_dir.path().abs(),
|
||||||
/*use_windows_elevated_backend*/ true,
|
/*use_windows_elevated_backend*/ true,
|
||||||
),
|
),
|
||||||
@@ -821,12 +806,6 @@ fn windows_elevated_supports_unreadable_split_carveouts() {
|
|||||||
let blocked = temp_dir.path().join("blocked");
|
let blocked = temp_dir.path().join("blocked");
|
||||||
std::fs::create_dir_all(&blocked).expect("create blocked");
|
std::fs::create_dir_all(&blocked).expect("create blocked");
|
||||||
let expected_blocked = dunce::canonicalize(&blocked).expect("canonical blocked");
|
let expected_blocked = dunce::canonicalize(&blocked).expect("canonical blocked");
|
||||||
let policy = SandboxPolicy::WorkspaceWrite {
|
|
||||||
writable_roots: vec![],
|
|
||||||
network_access: false,
|
|
||||||
exclude_tmpdir_env_var: true,
|
|
||||||
exclude_slash_tmp: true,
|
|
||||||
};
|
|
||||||
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
||||||
codex_protocol::permissions::FileSystemSandboxEntry {
|
codex_protocol::permissions::FileSystemSandboxEntry {
|
||||||
path: codex_protocol::permissions::FileSystemPath::Special {
|
path: codex_protocol::permissions::FileSystemPath::Special {
|
||||||
@@ -850,13 +829,15 @@ fn windows_elevated_supports_unreadable_split_carveouts() {
|
|||||||
access: codex_protocol::permissions::FileSystemAccessMode::Deny,
|
access: codex_protocol::permissions::FileSystemAccessMode::Deny,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
let permission_profile = PermissionProfile::from_runtime_permissions(
|
||||||
|
&file_system_policy,
|
||||||
|
NetworkSandboxPolicy::Restricted,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resolve_windows_elevated_filesystem_overrides(
|
resolve_windows_elevated_filesystem_overrides(
|
||||||
SandboxType::WindowsRestrictedToken,
|
SandboxType::WindowsRestrictedToken,
|
||||||
&policy,
|
&permission_profile,
|
||||||
&file_system_policy,
|
|
||||||
NetworkSandboxPolicy::Restricted,
|
|
||||||
&temp_dir.path().abs(),
|
&temp_dir.path().abs(),
|
||||||
/*use_windows_elevated_backend*/ true,
|
/*use_windows_elevated_backend*/ true,
|
||||||
),
|
),
|
||||||
@@ -884,12 +865,6 @@ fn windows_elevated_supports_unreadable_globs() {
|
|||||||
let secret = temp_dir.path().join("app").join(".env");
|
let secret = temp_dir.path().join("app").join(".env");
|
||||||
std::fs::create_dir_all(secret.parent().expect("parent")).expect("create parent");
|
std::fs::create_dir_all(secret.parent().expect("parent")).expect("create parent");
|
||||||
std::fs::write(&secret, "secret").expect("write secret");
|
std::fs::write(&secret, "secret").expect("write secret");
|
||||||
let policy = SandboxPolicy::WorkspaceWrite {
|
|
||||||
writable_roots: vec![],
|
|
||||||
network_access: false,
|
|
||||||
exclude_tmpdir_env_var: true,
|
|
||||||
exclude_slash_tmp: true,
|
|
||||||
};
|
|
||||||
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
||||||
codex_protocol::permissions::FileSystemSandboxEntry {
|
codex_protocol::permissions::FileSystemSandboxEntry {
|
||||||
path: codex_protocol::permissions::FileSystemPath::Special {
|
path: codex_protocol::permissions::FileSystemPath::Special {
|
||||||
@@ -912,13 +887,15 @@ fn windows_elevated_supports_unreadable_globs() {
|
|||||||
access: codex_protocol::permissions::FileSystemAccessMode::Deny,
|
access: codex_protocol::permissions::FileSystemAccessMode::Deny,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
let permission_profile = PermissionProfile::from_runtime_permissions(
|
||||||
|
&file_system_policy,
|
||||||
|
NetworkSandboxPolicy::Restricted,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resolve_windows_elevated_filesystem_overrides(
|
resolve_windows_elevated_filesystem_overrides(
|
||||||
SandboxType::WindowsRestrictedToken,
|
SandboxType::WindowsRestrictedToken,
|
||||||
&policy,
|
&permission_profile,
|
||||||
&file_system_policy,
|
|
||||||
NetworkSandboxPolicy::Restricted,
|
|
||||||
&temp_dir.path().abs(),
|
&temp_dir.path().abs(),
|
||||||
/*use_windows_elevated_backend*/ true,
|
/*use_windows_elevated_backend*/ true,
|
||||||
),
|
),
|
||||||
@@ -941,12 +918,6 @@ fn windows_elevated_rejects_reopened_writable_descendants() {
|
|||||||
let docs = temp_dir.path().join("docs");
|
let docs = temp_dir.path().join("docs");
|
||||||
let nested = docs.join("nested");
|
let nested = docs.join("nested");
|
||||||
std::fs::create_dir_all(&nested).expect("create 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,
|
|
||||||
};
|
|
||||||
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
||||||
codex_protocol::permissions::FileSystemSandboxEntry {
|
codex_protocol::permissions::FileSystemSandboxEntry {
|
||||||
path: codex_protocol::permissions::FileSystemPath::Special {
|
path: codex_protocol::permissions::FileSystemPath::Special {
|
||||||
@@ -977,13 +948,15 @@ fn windows_elevated_rejects_reopened_writable_descendants() {
|
|||||||
access: codex_protocol::permissions::FileSystemAccessMode::Write,
|
access: codex_protocol::permissions::FileSystemAccessMode::Write,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
let permission_profile = PermissionProfile::from_runtime_permissions(
|
||||||
|
&file_system_policy,
|
||||||
|
NetworkSandboxPolicy::Restricted,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unsupported_windows_restricted_token_sandbox_reason(
|
unsupported_windows_restricted_token_sandbox_reason(
|
||||||
SandboxType::WindowsRestrictedToken,
|
SandboxType::WindowsRestrictedToken,
|
||||||
&policy,
|
&permission_profile,
|
||||||
&file_system_policy,
|
|
||||||
NetworkSandboxPolicy::Restricted,
|
|
||||||
&temp_dir.path().abs(),
|
&temp_dir.path().abs(),
|
||||||
WindowsSandboxLevel::Elevated,
|
WindowsSandboxLevel::Elevated,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -22,10 +22,8 @@ use codex_protocol::models::PermissionProfile;
|
|||||||
pub use codex_protocol::models::SandboxPermissions;
|
pub use codex_protocol::models::SandboxPermissions;
|
||||||
use codex_protocol::permissions::FileSystemSandboxPolicy;
|
use codex_protocol::permissions::FileSystemSandboxPolicy;
|
||||||
use codex_protocol::permissions::NetworkSandboxPolicy;
|
use codex_protocol::permissions::NetworkSandboxPolicy;
|
||||||
use codex_protocol::protocol::SandboxPolicy;
|
|
||||||
use codex_sandboxing::SandboxExecRequest;
|
use codex_sandboxing::SandboxExecRequest;
|
||||||
use codex_sandboxing::SandboxType;
|
use codex_sandboxing::SandboxType;
|
||||||
use codex_sandboxing::compatibility_sandbox_policy_for_permission_profile;
|
|
||||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@@ -102,15 +100,6 @@ impl ExecRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn compatibility_sandbox_policy(&self) -> SandboxPolicy {
|
|
||||||
compatibility_sandbox_policy_for_permission_profile(
|
|
||||||
&self.permission_profile,
|
|
||||||
&self.file_system_sandbox_policy,
|
|
||||||
self.network_sandbox_policy,
|
|
||||||
self.windows_sandbox_policy_cwd.as_path(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn from_sandbox_exec_request(
|
pub(crate) fn from_sandbox_exec_request(
|
||||||
request: SandboxExecRequest,
|
request: SandboxExecRequest,
|
||||||
options: ExecOptions,
|
options: ExecOptions,
|
||||||
|
|||||||
@@ -150,17 +150,11 @@ impl SessionConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn sandbox_policy(&self) -> SandboxPolicy {
|
pub(super) fn sandbox_policy(&self) -> SandboxPolicy {
|
||||||
self.permission_profile()
|
let permission_profile = self.permission_profile();
|
||||||
.to_legacy_sandbox_policy(&self.cwd)
|
codex_sandboxing::compatibility_sandbox_policy_for_permission_profile(
|
||||||
.unwrap_or_else(|_| {
|
&permission_profile,
|
||||||
let file_system_sandbox_policy = self.file_system_sandbox_policy();
|
&self.cwd,
|
||||||
codex_sandboxing::compatibility_sandbox_policy_for_permission_profile(
|
)
|
||||||
self.permission_profile_state.permission_profile(),
|
|
||||||
&file_system_sandbox_policy,
|
|
||||||
self.network_sandbox_policy(),
|
|
||||||
&self.cwd,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn file_system_sandbox_policy(&self) -> FileSystemSandboxPolicy {
|
pub(super) fn file_system_sandbox_policy(&self) -> FileSystemSandboxPolicy {
|
||||||
|
|||||||
@@ -124,12 +124,8 @@ impl TurnContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn sandbox_policy(&self) -> SandboxPolicy {
|
pub(crate) fn sandbox_policy(&self) -> SandboxPolicy {
|
||||||
let file_system_sandbox_policy = self.file_system_sandbox_policy();
|
|
||||||
let network_sandbox_policy = self.network_sandbox_policy();
|
|
||||||
compatibility_sandbox_policy_for_permission_profile(
|
compatibility_sandbox_policy_for_permission_profile(
|
||||||
&self.permission_profile,
|
&self.permission_profile,
|
||||||
&file_system_sandbox_policy,
|
|
||||||
network_sandbox_policy,
|
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
&self.cwd,
|
&self.cwd,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ pub enum StdioPolicy {
|
|||||||
Inherit,
|
Inherit,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spawns the appropriate child process for the ExecParams and SandboxPolicy,
|
/// Spawns the appropriate child process for the exec params and sandbox settings,
|
||||||
/// ensuring the args and environment variables used to create the `Command`
|
/// ensuring the args and environment variables used to create the `Command`
|
||||||
/// (and `Child`) honor the configuration.
|
/// (and `Child`) honor the configuration.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -290,19 +290,18 @@ impl SandboxManager {
|
|||||||
|
|
||||||
pub fn compatibility_sandbox_policy_for_permission_profile(
|
pub fn compatibility_sandbox_policy_for_permission_profile(
|
||||||
permissions: &PermissionProfile,
|
permissions: &PermissionProfile,
|
||||||
file_system_policy: &FileSystemSandboxPolicy,
|
|
||||||
network_policy: NetworkSandboxPolicy,
|
|
||||||
cwd: &Path,
|
cwd: &Path,
|
||||||
) -> SandboxPolicy {
|
) -> SandboxPolicy {
|
||||||
permissions
|
permissions
|
||||||
.to_legacy_sandbox_policy(cwd)
|
.to_legacy_sandbox_policy(cwd)
|
||||||
.unwrap_or_else(|_| {
|
.unwrap_or_else(|_| {
|
||||||
|
let (file_system_policy, network_policy) = permissions.to_runtime_permissions();
|
||||||
compatibility_workspace_write_policy(file_system_policy, network_policy, cwd)
|
compatibility_workspace_write_policy(file_system_policy, network_policy, cwd)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compatibility_workspace_write_policy(
|
fn compatibility_workspace_write_policy(
|
||||||
file_system_policy: &FileSystemSandboxPolicy,
|
file_system_policy: FileSystemSandboxPolicy,
|
||||||
network_policy: NetworkSandboxPolicy,
|
network_policy: NetworkSandboxPolicy,
|
||||||
cwd: &Path,
|
cwd: &Path,
|
||||||
) -> SandboxPolicy {
|
) -> SandboxPolicy {
|
||||||
|
|||||||
Reference in new issue
Block a user