sandboxing: migrate cwd inputs to PathUri (#27816)

## Why

Sandbox cwd values can cross app-server and exec-server host boundaries.
They should retain URI semantics until the receiving host validates them
instead of being interpreted early as native paths.

## What

- Carry `PathUri` through filesystem sandbox contexts, sandbox commands,
and transform inputs.
- Convert command and policy cwd once in `SandboxManager::transform`,
then keep launch requests native.
- Preserve sandbox cwd over remote filesystem transport and reject
non-native URIs without fallback.
- Cache paired native/URI turn-environment cwd values during migration,
with immutable access to keep them synchronized.
- Extend existing protocol, forwarding, transform, and core runtime
tests.
This commit is contained in:
Adam Perry @ OpenAI
2026-06-12 11:38:01 -07:00
committed by GitHub
Unverified
parent 84520225b9
commit 52a50aec70
40 changed files with 546 additions and 228 deletions
@@ -189,7 +189,6 @@ fn map_fs_error(err: io::Error) -> JSONRPCErrorError {
mod tests {
use codex_protocol::protocol::NetworkAccess;
use codex_protocol::protocol::SandboxPolicy;
use codex_utils_absolute_path::AbsolutePathBuf;
use codex_utils_path_uri::PathUri;
use pretty_assertions::assert_eq;
@@ -207,8 +206,14 @@ mod tests {
)
.expect("runtime paths");
let handler = FileSystemHandler::new(runtime_paths);
let sandbox_cwd =
AbsolutePathBuf::from_absolute_path(temp_dir.path()).expect("absolute tempdir");
let sandbox_cwd = PathUri::from_path(temp_dir.path()).expect("tempdir URI");
let sandbox_context = |sandbox_policy| {
FileSystemSandboxContext::from_legacy_sandbox_policy(
sandbox_policy,
sandbox_cwd.clone(),
)
.expect("sandbox context")
};
for (file_name, sandbox_policy) in [
("danger.txt", SandboxPolicy::DangerFullAccess),
@@ -225,10 +230,7 @@ mod tests {
.write_file(FsWriteFileParams {
path: path.clone(),
data_base64: STANDARD.encode("ok"),
sandbox: Some(FileSystemSandboxContext::from_legacy_sandbox_policy(
sandbox_policy.clone(),
sandbox_cwd.clone(),
)),
sandbox: Some(sandbox_context(sandbox_policy.clone())),
})
.await
.expect("write file");
@@ -236,10 +238,7 @@ mod tests {
let canonicalized = handler
.canonicalize(FsCanonicalizeParams {
path: path.clone(),
sandbox: Some(FileSystemSandboxContext::from_legacy_sandbox_policy(
sandbox_policy.clone(),
sandbox_cwd.clone(),
)),
sandbox: Some(sandbox_context(sandbox_policy.clone())),
})
.await
.expect("canonicalize file");
@@ -254,10 +253,7 @@ mod tests {
let response = handler
.read_file(FsReadFileParams {
path,
sandbox: Some(FileSystemSandboxContext::from_legacy_sandbox_policy(
sandbox_policy,
sandbox_cwd.clone(),
)),
sandbox: Some(sandbox_context(sandbox_policy)),
})
.await
.expect("read file");