Use PathUri in filesystem permission paths for exec-server (#28165)

## Why

Progress towards letting app-server and exec-server run on different
platforms, specifically for sandbox configuration.

## What

- Make the filesystem path containment hierarchy generic, defaulting to
`AbsolutePathBuf` for now.
- Have clients specify `AbsolutePathBuf` or `PathUri` directly where
needed.
- Use `PathUri` throughout exec-server filesystem protocol and trait
boundaries.
- Implement `From` for conversion to path URIs and `TryFrom` for
fallible conversion to absolute paths through the generic type
hierarchy.
This commit is contained in:
Adam Perry @ OpenAI authored and GitHub committed 2026-06-15 23:55:23 +00:00
1 parent 428cd44154
commit 46f17930b6
17 files changed
+320 -97

No files matched your search

+51 -4
View File
@@ -6,6 +6,7 @@ use std::path::PathBuf;
use codex_utils_absolute_path::AbsolutePathBuf;
use codex_utils_absolute_path::canonicalize_preserving_symlinks;
use codex_utils_path_uri::PathUri;
use globset::GlobBuilder;
use globset::GlobMatcher;
use schemars::JsonSchema;
@@ -176,11 +177,31 @@ impl FileSystemSpecialPath {
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema, TS)]
pub struct FileSystemSandboxEntry {
pub path: FileSystemPath,
pub struct FileSystemSandboxEntry<PathType = AbsolutePathBuf> {
pub path: FileSystemPath<PathType>,
pub access: FileSystemAccessMode,
}
impl From<FileSystemSandboxEntry<AbsolutePathBuf>> for FileSystemSandboxEntry<PathUri> {
fn from(value: FileSystemSandboxEntry<AbsolutePathBuf>) -> Self {
FileSystemSandboxEntry {
path: value.path.into(),
access: value.access,
}
}
}
impl TryFrom<FileSystemSandboxEntry<PathUri>> for FileSystemSandboxEntry<AbsolutePathBuf> {
type Error = io::Error;
fn try_from(value: FileSystemSandboxEntry<PathUri>) -> Result<Self, Self::Error> {
Ok(FileSystemSandboxEntry {
path: value.path.try_into()?,
access: value.access,
})
}
}
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Display, Default, JsonSchema, TS,
)]
@@ -338,9 +359,9 @@ enum InvalidDenyReadGlobBehavior {
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema, TS)]
#[serde(tag = "type", rename_all = "snake_case")]
#[ts(tag = "type")]
pub enum FileSystemPath {
pub enum FileSystemPath<PathType = AbsolutePathBuf> {
Path {
path: AbsolutePathBuf,
path: PathType,
},
/// A git-style glob pattern. Pattern entries currently support
/// FileSystemAccessMode::Deny only.
@@ -352,6 +373,32 @@ pub enum FileSystemPath {
},
}
impl From<FileSystemPath<AbsolutePathBuf>> for FileSystemPath<PathUri> {
fn from(value: FileSystemPath<AbsolutePathBuf>) -> Self {
match value {
FileSystemPath::Path { path } => FileSystemPath::Path {
path: PathUri::from_abs_path(&path),
},
FileSystemPath::GlobPattern { pattern } => FileSystemPath::GlobPattern { pattern },
FileSystemPath::Special { value } => FileSystemPath::Special { value },
}
}
}
impl TryFrom<FileSystemPath<PathUri>> for FileSystemPath<AbsolutePathBuf> {
type Error = io::Error;
fn try_from(value: FileSystemPath<PathUri>) -> Result<Self, Self::Error> {
Ok(match value {
FileSystemPath::Path { path } => FileSystemPath::Path {
path: path.to_abs_path()?,
},
FileSystemPath::GlobPattern { pattern } => FileSystemPath::GlobPattern { pattern },
FileSystemPath::Special { value } => FileSystemPath::Special { value },
})
}
}
const PROJECT_ROOTS_GLOB_PATTERN_PREFIX: &str = "codex-project-roots://";
pub fn project_roots_glob_pattern(subpath: &Path) -> String {