Use permission profiles in sandbox tests and documentation (#61133)

## What changed

- Build and assert `PermissionProfile` values directly in memory consolidation tests using filesystem and network permissions.
- Remove the `SandboxPolicy` dependency from rollout trace test fixtures while preserving their `DangerFullAccess` value.
- Update sandbox documentation to describe legacy `sandbox_mode` conversion to `PermissionProfile` and nested filesystem rules, and reference `SandboxMode` in the CLI documentation.

GitOrigin-RevId: ac1be62625b1bfd98dde5f762b379eb840f9186b
This commit is contained in:
ioanbudea-OAI
2026-11-12 14:22:20 +00:00
committed by copyberry
parent 1d529e0266
commit a7aab624ab
5 changed files with 30 additions and 29 deletions
+4 -4
View File
@@ -29,7 +29,8 @@ commands that would enter the bubblewrap path.
**Current Behavior**
- Legacy `SandboxPolicy` / `sandbox_mode` configs remain supported.
- Legacy `sandbox_mode` configs remain supported and are converted to
`PermissionProfile` before sandbox execution.
- Bubblewrap is the default filesystem sandbox.
- If `bwrap` is present on `PATH` outside the current working directory, the
helper uses it.
@@ -47,9 +48,8 @@ commands that would enter the bubblewrap path.
- Filesystem-restricted execution requires bubblewrap. The legacy Landlock
option is rejected for these policies because it cannot isolate app-server
Unix sockets. Disable `features.use_legacy_landlock` when upgrading.
- Split-only filesystem policies that do not round-trip through the legacy
`SandboxPolicy` model stay on bubblewrap so nested read-only or denied
carveouts are preserved.
- Bubblewrap preserves nested read-only and denied filesystem rules from
`PermissionProfile`.
- When bubblewrap is active, the helper applies `PR_SET_NO_NEW_PRIVS` and a
seccomp filter in-process after establishing the filesystem view. Restricted
network policies block network syscalls; filesystem-restricted policies with
@@ -5,9 +5,9 @@ use codex_model_provider::create_model_provider;
use codex_protocol::models::ManagedFileSystemPermissions;
use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::FileSystemPolicyProjection;
use codex_protocol::permissions::FileSystemSandboxPolicy;
use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_protocol::protocol::AskForApproval;
use codex_protocol::protocol::SandboxPolicy;
use core_test_support::responses::start_mock_server;
use core_test_support::test_codex::test_codex;
use pretty_assertions::assert_eq;
@@ -28,12 +28,14 @@ async fn consolidation_uses_canonical_parent_enforcement() -> anyhow::Result<()>
);
let root = crate::memory_root(&test.config.codex_home);
let managed_worker_policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![root.clone()],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
};
let managed_worker_profile = PermissionProfile::from_runtime_permissions(
&FileSystemSandboxPolicy::workspace_write(
std::slice::from_ref(&root),
/*exclude_tmpdir_env_var*/ true,
/*exclude_slash_tmp*/ true,
),
NetworkSandboxPolicy::Restricted,
);
for (parent_permission_profile, expected_permission_profile) in [
(PermissionProfile::Disabled, PermissionProfile::Disabled),
@@ -58,10 +60,7 @@ async fn consolidation_uses_canonical_parent_enforcement() -> anyhow::Result<()>
file_system: ManagedFileSystemPermissions::Unrestricted,
network: NetworkSandboxPolicy::Enabled,
},
PermissionProfile::from_legacy_sandbox_policy_for_cwd(
&managed_worker_policy,
root.as_path(),
),
managed_worker_profile,
),
] {
let agent_config =
@@ -1,8 +1,10 @@
use super::agent;
use crate::memory_root;
use codex_model_provider::create_model_provider;
use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::FileSystemSandboxPolicy;
use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_protocol::permissions::PROTECTED_METADATA_PATH_NAMES;
use codex_protocol::protocol::SandboxPolicy;
use core_test_support::responses::start_mock_server;
use core_test_support::test_codex::test_codex;
use pretty_assertions::assert_eq;
@@ -60,13 +62,15 @@ async fn consolidation_rebinds_workspace_roots_to_memory_root() -> anyhow::Resul
(&root, &vec![root.clone()], [root.clone()].as_slice(), true),
);
assert_eq!(
agent_config.legacy_sandbox_policy(),
SandboxPolicy::WorkspaceWrite {
writable_roots: Vec::new(),
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
}
agent_config.permissions.permission_profile(),
&PermissionProfile::from_runtime_permissions(
&FileSystemSandboxPolicy::workspace_write(
std::slice::from_ref(&root),
/*exclude_tmpdir_env_var*/ true,
/*exclude_slash_tmp*/ true,
),
NetworkSandboxPolicy::Restricted,
)
);
let filesystem = agent_config.permissions.file_system_sandbox_policy();
assert!(filesystem.can_write_local_path_with_cwd(root.join("memory.md").as_path(), &root));
+2 -3
View File
@@ -14,7 +14,6 @@ use codex_protocol::protocol::FileChange;
use codex_protocol::protocol::PatchApplyBeginEvent;
use codex_protocol::protocol::PatchApplyEndEvent;
use codex_protocol::protocol::PatchApplyStatus;
use codex_protocol::protocol::SandboxPolicy;
use codex_protocol::protocol::SessionSource;
use codex_protocol::protocol::SubAgentSource;
use pretty_assertions::assert_eq;
@@ -50,7 +49,7 @@ fn create_in_root_writes_replayable_lifecycle_events() -> anyhow::Result<()> {
model: "gpt-test".to_string(),
provider_name: "test-provider".to_string(),
approval_policy: "never".to_string(),
sandbox_policy: format!("{:?}", SandboxPolicy::DangerFullAccess),
sandbox_policy: "DangerFullAccess".to_string(),
},
)?;
@@ -134,7 +133,7 @@ fn spawned_thread_start_appends_to_root_bundle() -> anyhow::Result<()> {
model: "gpt-test".to_string(),
provider_name: "test-provider".to_string(),
approval_policy: "never".to_string(),
sandbox_policy: format!("{:?}", SandboxPolicy::DangerFullAccess),
sandbox_policy: "DangerFullAccess".to_string(),
})?;
child_trace.record_ended(RolloutStatus::Completed);
let bundle_dir = single_bundle_dir(temp.path())?;
@@ -1,8 +1,7 @@
//! Standard type to use with the `--sandbox` (`-s`) CLI option.
//!
//! This mirrors the variants of [`codex_protocol::protocol::SandboxPolicy`], but
//! without any of the associated data so it can be expressed as a simple flag
//! on the command-line. Users that need to tweak the advanced options for
//! This mirrors [`codex_protocol::config_types::SandboxMode`] so built-in modes
//! can be expressed as a simple flag on the command line. Users that need to tweak the advanced options for
//! `workspace-write` can continue to do so via `-c` overrides or their
//! `config.toml`.