Skip missing paths in filesystem sandbox entries (#34598)

## Why

Default read-only protections for project metadata should apply when paths such
as `.git`, `.agents`, and `.codex` exist, without causing sandbox setup to
materialize missing paths as ACL targets.

## What changed

- Add an optional `missing_path_behavior` to filesystem sandbox entries and
  mark default project-metadata protections with `skip`.
- Preserve the behavior through permission transforms and exec/MCP protocol
  serialization while keeping existing path wire variants stable.
- Ignore skip-missing entries when projecting configuration or Windows sandbox
  overrides, while retaining explicit metadata carveouts.

## Testing

- Cover protocol round trips for path and special-path entries.
- Verify default metadata protections and Windows explicit carveout handling.

GitOrigin-RevId: 6df13dadacdd131c44aab9f15a967c81051355c1
This commit is contained in:
iceweasel-oai authored and copyberry committed 2026-07-21 19:17:18 +00:00
1 parent ee71c4a90f
commit 87f71e35b8
63 files changed
+825 -132

No files matched your search

@@ -44,6 +44,7 @@ pub fn resolve_windows_deny_read_paths(
pattern: pattern.clone(),
},
access: FileSystemAccessMode::Deny,
missing_path_behavior: None,
})
.collect(),
);
@@ -206,6 +207,7 @@ mod tests {
FileSystemSandboxEntry {
path: FileSystemPath::GlobPattern { pattern },
access: FileSystemAccessMode::Deny,
missing_path_behavior: None,
}
}
@@ -215,6 +217,7 @@ mod tests {
path: AbsolutePathBuf::from_absolute_path(path).expect("absolute path"),
},
access: FileSystemAccessMode::Deny,
missing_path_behavior: None,
}
}
@@ -173,7 +173,7 @@ impl ResolvedWindowsSandboxPermissions {
self.file_system
.entries
.iter()
.any(|FileSystemSandboxEntry { path, access }| {
.any(|FileSystemSandboxEntry { path, access, .. }| {
matches!(
path,
FileSystemPath::Special {
@@ -258,6 +258,7 @@ mod tests {
value: FileSystemSpecialPath::project_roots(/*subpath*/ None),
},
access: FileSystemAccessMode::Write,
missing_path_behavior: None,
}],
glob_scan_max_depth: None,
},
@@ -298,18 +299,21 @@ mod tests {
value: FileSystemSpecialPath::project_roots(/*subpath*/ None),
},
access: FileSystemAccessMode::Write,
missing_path_behavior: None,
},
FileSystemSandboxEntry {
path: FileSystemPath::Special {
value: FileSystemSpecialPath::project_roots(Some(".git".into())),
},
access: FileSystemAccessMode::Deny,
missing_path_behavior: None,
},
FileSystemSandboxEntry {
path: FileSystemPath::GlobPattern {
pattern: project_roots_glob_pattern(Path::new("**/*.env")),
},
access: FileSystemAccessMode::Deny,
missing_path_behavior: None,
},
],
glob_scan_max_depth: None,
@@ -332,24 +336,28 @@ mod tests {
path: first.clone(),
},
access: FileSystemAccessMode::Write,
missing_path_behavior: None,
},
FileSystemSandboxEntry {
path: FileSystemPath::Path {
path: second.clone(),
},
access: FileSystemAccessMode::Write,
missing_path_behavior: None,
},
FileSystemSandboxEntry {
path: FileSystemPath::Path {
path: first.join(".git"),
},
access: FileSystemAccessMode::Deny,
missing_path_behavior: None,
},
FileSystemSandboxEntry {
path: FileSystemPath::Path {
path: second.join(".git"),
},
access: FileSystemAccessMode::Deny,
missing_path_behavior: None,
},
FileSystemSandboxEntry {
path: FileSystemPath::GlobPattern {
@@ -361,6 +369,7 @@ mod tests {
.into_owned(),
},
access: FileSystemAccessMode::Deny,
missing_path_behavior: None,
},
FileSystemSandboxEntry {
path: FileSystemPath::GlobPattern {
@@ -372,6 +381,7 @@ mod tests {
.into_owned(),
},
access: FileSystemAccessMode::Deny,
missing_path_behavior: None,
},
])
);
@@ -455,6 +465,7 @@ mod tests {
value: FileSystemSpecialPath::Root,
},
access: FileSystemAccessMode::Write,
missing_path_behavior: None,
}],
glob_scan_max_depth: None,
},