feat(sandbox): add Windows deny-read parity#18202
Conversation
There was a problem hiding this comment.
💡 Codex Review
codex/codex-rs/windows-sandbox-rs/src/lib.rs
Lines 420 to 423 in 954e7c2
The restricted-token path only adds additional_deny_write_paths when the path already exists. New deny-read logic later materializes missing deny paths (apply_deny_read_acls), so a FileSystemAccessMode::None path that starts missing gets read-denied but not write-denied. A sandboxed process can still create/write descendants under that directory, violating None semantics.
codex/codex-rs/windows-sandbox-rs/src/lib.rs
Lines 420 to 423 in 954e7c2
The restricted-token path only adds additional_deny_write_paths when the path already exists. New deny-read logic then materializes missing deny paths (apply_deny_read_acls), so a missing FileSystemAccessMode::None path becomes read-denied but not write-denied. A sandboxed command can still create/write under that directory, violating None semantics.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| .map(|path| { | ||
| if path.exists() { | ||
| dunce::canonicalize(&path).unwrap_or(path) | ||
| } else { |
There was a problem hiding this comment.
Keep lexical deny-read paths in elevated payloads
build_payload_deny_read_paths canonicalizes every existing deny-read path before sending it to the helper. This strips the lexical path variant that plan_deny_read_acl_paths is designed to preserve (lexical + canonical) for reparse-point alias coverage, so elevated setup no longer matches the stated alias-hardening intent.
Useful? React with 👍 / 👎.
| )?; | ||
| } else { | ||
| match read_acl_mutex_exists() { | ||
| Ok(true) => { |
There was a problem hiding this comment.
Apply current deny-read payload even when helper is busy
When the read-ACL helper mutex exists, setup logs and skips spawning a helper, but deny-read ACL updates are now performed by that helper path. If policy changes while another helper run is active, the new deny-read payload is dropped for this command, so execution can proceed with stale deny rules.
Useful? React with 👍 / 👎.
| let scan_key = dunce::canonicalize(path).unwrap_or_else(|_| path.to_path_buf()); | ||
| if !seen_scan_dirs.insert(scan_key) { | ||
| return Ok(()); |
There was a problem hiding this comment.
Avoid cross-pattern scan dedupe by canonical directory only
Global seen_scan_dirs keys scans by canonical path. If two unreadable globs use different lexical roots that resolve to the same target (junction/symlink aliases), the second root is skipped entirely. Alias-specific matches from later patterns are then never added to deny ACL targets.
Useful? React with 👍 / 👎.
4db0235 to
e665898
Compare
Add Windows deny-read enforcement for split filesystem policies by resolving exact and glob unreadable entries into ACL targets, threading those paths through the restricted-token and elevated Windows sandbox backends, and applying deny-read ACE overlays with stale cleanup records. Exact missing paths are materialized before ACE application so sandboxed subprocesses cannot create and read them during the same run. Existing paths are planned with both lexical and canonical targets to cover reparse-point aliases. Co-authored-by: Codex <noreply@openai.com>
Move Windows deny-read path resolution into the Windows sandbox crate, bound non-recursive glob expansion, and avoid unnecessary deny-read setup work when no read roots or persistent records are present. Co-authored-by: Codex <noreply@openai.com>
ec765ef to
1013499
Compare
Summary
Adds Windows subprocess enforcement for split filesystem
access = noneread restrictions, now that the exact/glob deny-read policy stack has landed onmain.This PR keeps the scope to Windows parity:
Landed Prerequisites
These base stack PRs are already on
main:feat(permissions): add glob deny-read policy supportfeat(sandbox): add glob deny-read platform enforcementfeat(config): support managed deny-read requirementsThis PR now targets
maindirectly and contains only the Windows deny-read parity layer.Implementation Notes