mirror of
https://github.com/openai/codex.git
synced 2026-11-12 21:20:34 +00:00
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:
@@ -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));
|
||||
|
||||
@@ -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`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user