6.0 KiB
PR #1785: chore: introduce SandboxPolicy::WorkspaceWrite::include_default_writable_roots
- URL: https://github.com/openai/codex/pull/1785
- Author: bolinfest
- Created: 2025-08-01 18:31:32 UTC
- Updated: 2025-08-01 21:16:04 UTC
- Changes: +27/-1, Files changed: 4, Commits: 1
Description
Without this change, it is challenging to create integration tests to
verify that the folders not included in writable_roots in
SandboxPolicy::WorkspaceWrite are read-only because, by default,
get_writable_roots_with_cwd() includes TMPDIR, which is where most integration
tests do their work.
This introduces a include_default_writable_roots option to disable the default
includes returned by get_writable_roots_with_cwd().
Stack created with Sapling. Best reviewed with ReviewStack.
- #1765
- -> #1785
Full Diff
diff --git a/codex-rs/common/src/sandbox_summary.rs b/codex-rs/common/src/sandbox_summary.rs
index 3d33d92836..e0e309a9d9 100644
--- a/codex-rs/common/src/sandbox_summary.rs
+++ b/codex-rs/common/src/sandbox_summary.rs
@@ -7,6 +7,7 @@ pub fn summarize_sandbox_policy(sandbox_policy: &SandboxPolicy) -> String {
SandboxPolicy::WorkspaceWrite {
writable_roots,
network_access,
+ include_default_writable_roots,
} => {
let mut summary = "workspace-write".to_string();
if !writable_roots.is_empty() {
@@ -19,6 +20,9 @@ pub fn summarize_sandbox_policy(sandbox_policy: &SandboxPolicy) -> String {
.join(", ")
));
}
+ if !*include_default_writable_roots {
+ summary.push_str(" (exact writable roots)");
+ }
if *network_access {
summary.push_str(" (network access enabled)");
}
diff --git a/codex-rs/core/src/config.rs b/codex-rs/core/src/config.rs
index a65ec09674..20bdebe789 100644
--- a/codex-rs/core/src/config.rs
+++ b/codex-rs/core/src/config.rs
@@ -350,6 +350,7 @@ impl ConfigToml {
Some(s) => SandboxPolicy::WorkspaceWrite {
writable_roots: s.writable_roots.clone(),
network_access: s.network_access,
+ include_default_writable_roots: true,
},
None => SandboxPolicy::new_workspace_write_policy(),
},
@@ -720,6 +721,7 @@ writable_roots = [
SandboxPolicy::WorkspaceWrite {
writable_roots: vec![PathBuf::from("/tmp")],
network_access: false,
+ include_default_writable_roots: true,
},
sandbox_workspace_write_cfg.derive_sandbox_policy(sandbox_mode_override)
);
diff --git a/codex-rs/core/src/protocol.rs b/codex-rs/core/src/protocol.rs
index bc922eb0e2..e333373c7b 100644
--- a/codex-rs/core/src/protocol.rs
+++ b/codex-rs/core/src/protocol.rs
@@ -175,9 +175,19 @@ pub enum SandboxPolicy {
/// default.
#[serde(default)]
network_access: bool,
+
+ /// When set to `true`, will include defaults like the current working
+ /// directory and TMPDIR (on macOS). When `false`, only `writable_roots`
+ /// are used. (Mainly used for testing.)
+ #[serde(default = "default_true")]
+ include_default_writable_roots: bool,
},
}
+fn default_true() -> bool {
+ true
+}
+
impl FromStr for SandboxPolicy {
type Err = serde_json::Error;
@@ -199,6 +209,7 @@ impl SandboxPolicy {
SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
+ include_default_writable_roots: true,
}
}
@@ -230,7 +241,15 @@ impl SandboxPolicy {
match self {
SandboxPolicy::DangerFullAccess => Vec::new(),
SandboxPolicy::ReadOnly => Vec::new(),
- SandboxPolicy::WorkspaceWrite { writable_roots, .. } => {
+ SandboxPolicy::WorkspaceWrite {
+ writable_roots,
+ include_default_writable_roots,
+ ..
+ } => {
+ if !*include_default_writable_roots {
+ return writable_roots.clone();
+ }
+
let mut roots = writable_roots.clone();
roots.push(cwd.to_path_buf());
diff --git a/codex-rs/linux-sandbox/tests/landlock.rs b/codex-rs/linux-sandbox/tests/landlock.rs
index 7eacda46c1..472a54e604 100644
--- a/codex-rs/linux-sandbox/tests/landlock.rs
+++ b/codex-rs/linux-sandbox/tests/landlock.rs
@@ -49,6 +49,7 @@ async fn run_cmd(cmd: &[&str], writable_roots: &[PathBuf], timeout_ms: u64) {
let sandbox_policy = SandboxPolicy::WorkspaceWrite {
writable_roots: writable_roots.to_vec(),
network_access: false,
+ include_default_writable_roots: true,
};
let sandbox_program = env!("CARGO_BIN_EXE_codex-linux-sandbox");
let codex_linux_sandbox_exe = Some(PathBuf::from(sandbox_program));
Review Comments
codex-rs/core/src/protocol.rs
- Created: 2025-08-01 20:48:47 UTC | Link: https://github.com/openai/codex/pull/1785#discussion_r2248846220
@@ -199,6 +203,7 @@ impl SandboxPolicy {
SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
+ use_exact_writable_roots: false,
I usually try to name things so that it makes sense for the default value to be
false, but I agree it reads in a strange way in this case, so I'll flip it.I think an appropriate name would be
include_default_writable_rootsbecause it affects bothTMPDIRandcwd.
- Created: 2025-08-01 21:09:45 UTC | Link: https://github.com/openai/codex/pull/1785#discussion_r2248873827
@@ -199,6 +203,7 @@ impl SandboxPolicy {
SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
+ use_exact_writable_roots: false,
Flipped, though I had to add
#[serde(default = "default_true")].