Skip to content

feat(sandbox): add Windows deny-read parity#18202

Merged
viyatb-oai merged 15 commits into
mainfrom
codex/viyatb/windows-deny-read-parity
May 12, 2026
Merged

feat(sandbox): add Windows deny-read parity#18202
viyatb-oai merged 15 commits into
mainfrom
codex/viyatb/windows-deny-read-parity

Conversation

@viyatb-oai
Copy link
Copy Markdown
Collaborator

@viyatb-oai viyatb-oai commented Apr 16, 2026

Why

The split filesystem policy stack already supports exact and glob access = none read restrictions on macOS and Linux. Windows still needed subprocess handling for those deny-read policies without claiming enforcement from a backend that cannot provide it.

Key finding

The unelevated restricted-token backend cannot safely enforce deny-read overlays. Its WRITE_RESTRICTED token model is authoritative for write checks, not read denials, so this PR intentionally fails that backend closed when deny-read overrides are present instead of claiming unsupported enforcement.

What changed

This PR adds the Windows deny-read enforcement layer and makes the backend split explicit:

  • Resolves Windows deny-read filesystem policy entries into concrete ACL targets.
  • Preserves exact missing paths so they can be materialized and denied before an enforceable sandboxed process starts.
  • Snapshot-expands existing glob matches into ACL targets for Windows subprocess enforcement.
  • Honors glob_scan_max_depth when expanding Windows deny-read globs.
  • Plans both the configured lexical path and the canonical target for existing paths so reparse-point aliases are covered.
  • Threads deny-read overrides through the elevated/logon-user Windows sandbox backend and unified exec.
  • Applies elevated deny-read ACLs synchronously before command launch rather than delegating them to the background read-grant helper.
  • Reconciles persistent deny-read ACEs per sandbox principal so policy changes do not leave stale deny-read ACLs behind.
  • Fails closed on the unelevated restricted-token backend when deny-read overrides are present, because its WRITE_RESTRICTED token model is not authoritative for read denials.

Landed prerequisites

These prerequisite PRs are already on main:

  1. feat(permissions): add glob deny-read policy support #15979 feat(permissions): add glob deny-read policy support
  2. feat(sandbox): add glob deny-read platform enforcement #18096 feat(sandbox): add glob deny-read platform enforcement
  3. feat(config): support managed deny-read requirements #17740 feat(config): support managed deny-read requirements

This PR targets main directly and contains only the Windows deny-read enforcement layer.

Implementation notes

  • Exact deny-read paths remain enforceable on the elevated path even when they do not exist yet: Windows materializes the missing path before applying the deny ACE, so the sandboxed command cannot create and read it during the same run.
  • Existing exact deny paths are preserved lexically until the ACL planner, which then adds the canonical target as a second ACL target when needed. That keeps both the configured alias and the resolved object covered.
  • Windows ACLs do not consume Codex glob syntax directly, so glob deny-read entries are expanded to the concrete matches that exist before process launch.
  • Glob traversal deduplicates directory visits within each pattern walk to avoid cycles, without collapsing distinct lexical roots that happen to resolve to the same target.
  • Persistent deny-read ACL state is keyed by sandbox principal SID, so cleanup only removes ACEs owned by the same backend principal.
  • Deny-read ACEs are fail-closed on the elevated path: setup aborts if mandatory deny-read ACL application fails.
  • Unelevated restricted-token sessions reject deny-read overrides early instead of running with a silently unenforceable read policy.

Verification

  • cargo test -p codex-core windows_restricted_token_rejects_unreadable_split_carveouts
  • just fmt
  • just fix -p codex-core
  • just fix -p codex-windows-sandbox
  • GitHub Actions rerun is in progress on the pushed head.

Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

for path in additional_deny_write_paths {
if path.exists() {
deny.insert(path.clone());
}

P1 Badge Apply deny-write ACLs to missing None carveouts

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.


for path in additional_deny_write_paths {
if path.exists() {
deny.insert(path.clone());
}

P1 Badge Apply deny-write ACLs to missing None carveouts

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".

Comment thread codex-rs/windows-sandbox-rs/src/setup_orchestrator.rs Outdated
Comment thread codex-rs/windows-sandbox-rs/src/setup_orchestrator.rs Outdated
Comment thread codex-rs/windows-sandbox-rs/src/bin/setup_main/win.rs
Comment thread codex-rs/windows-sandbox-rs/src/deny_read_resolver.rs
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/deny-read-requirements branch 2 times, most recently from 4db0235 to e665898 Compare April 17, 2026 00:44
Base automatically changed from codex/viyatb/deny-read-requirements to main April 17, 2026 15:40
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/windows-deny-read-parity branch from ec765ef to 1013499 Compare April 17, 2026 21:12
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 2, 2026

Closing this pull request because it has had no updates for more than 14 days. If you plan to continue working on it, feel free to reopen or open a new PR.

Comment thread codex-rs/windows-sandbox-rs/src/lib.rs Outdated
Comment thread codex-rs/windows-sandbox-rs/src/acl.rs
Comment thread codex-rs/windows-sandbox-rs/src/deny_read_acl.rs
Comment thread codex-rs/windows-sandbox-rs/src/deny_read_resolver.rs
Co-authored-by: Codex <noreply@openai.com>
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/windows-deny-read-parity branch from bdeee66 to 5ace284 Compare May 11, 2026 17:26
Copy link
Copy Markdown
Collaborator

@bolinfest bolinfest left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still reviewing, but I wanted to send what I found so far...

Comment thread codex-rs/cli/src/debug_sandbox.rs
Comment thread codex-rs/core/src/unified_exec/process_manager.rs
Comment thread codex-rs/core/src/exec.rs
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
};
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like we should create a macro or function that takes the TOML for config.toml because I find these test setups really hard to read...

@viyatb-oai viyatb-oai enabled auto-merge (squash) May 11, 2026 23:55
@viyatb-oai viyatb-oai disabled auto-merge May 11, 2026 23:56
Co-authored-by: Codex noreply@openai.com
Comment thread codex-rs/core/tests/suite/windows_sandbox.rs Outdated
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
@viyatb-oai viyatb-oai merged commit 46f30d0 into main May 12, 2026
27 checks passed
@viyatb-oai viyatb-oai deleted the codex/viyatb/windows-deny-read-parity branch May 12, 2026 06:04
@github-actions github-actions Bot locked and limited conversation to collaborators May 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants