Skip to content

feat(config): support managed deny-read requirements#17740

Merged
bolinfest merged 2 commits intomainfrom
codex/viyatb/deny-read-requirements
Apr 17, 2026
Merged

feat(config): support managed deny-read requirements#17740
bolinfest merged 2 commits intomainfrom
codex/viyatb/deny-read-requirements

Conversation

@viyatb-oai
Copy link
Copy Markdown
Collaborator

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

Summary

  • adds managed requirements support for deny-read filesystem entries
  • constrains config layers so managed deny-read requirements cannot be widened by user-controlled config
  • surfaces managed deny-read requirements through debug/config plumbing

This PR lets managed requirements inject deny-read filesystem constraints into the effective filesystem sandbox policy. User-controlled config can still choose the surrounding permission profile, but it cannot remove or weaken the managed deny-read entries.

Managed deny-read shape

A managed requirements file can declare exact paths and glob patterns under [permissions.filesystem]:

# /etc/codex/requirements.toml
[permissions.filesystem]
deny_read = [
  "/Users/alice/.gitconfig",
  "/Users/alice/.ssh",
  "./managed-private/**/*.env",
]

Those entries are compiled into the effective filesystem policy as access = none rules, equivalent in shape to filesystem permission entries like:

[permissions.workspace.filesystem]
"/Users/alice/.gitconfig" = "none"
"/Users/alice/.ssh" = "none"
"/absolute/path/to/managed-private/**/*.env" = "none"

The important difference is that the managed entries come from requirements, so lower-precedence user config cannot remove them or make those paths readable again.

Relative managed deny_read entries are resolved relative to the directory containing the managed requirements file. Glob entries keep their glob suffix after the non-glob prefix is normalized.

Runtime behavior

  • Managed deny_read entries are appended to the effective FileSystemSandboxPolicy after the selected permission profile is resolved.
  • Exact paths become FileSystemPath::Path { access: None }; glob patterns become FileSystemPath::GlobPattern { access: None }.
  • When managed deny-read entries are present, sandbox_mode is constrained to read-only or workspace-write; danger-full-access and external-sandbox cannot silently bypass the managed read-deny policy.
  • On Windows, the managed deny-read policy is enforced for direct file tools, but shell subprocess reads are not sandboxed yet, so startup emits a warning for that platform.
  • /debug-config shows the effective managed requirement as permissions.filesystem.deny_read with its source.

Stack

  1. feat(permissions): add glob deny-read policy support #15979 - glob deny-read policy/config/direct-tool support
  2. feat(sandbox): add glob deny-read platform enforcement #18096 - macOS and Linux sandbox enforcement
  3. This PR - managed deny-read requirements

@viyatb-oai viyatb-oai force-pushed the codex/viyatb/deny-read-globs branch 2 times, most recently from 7ceefbb to f004fb3 Compare April 14, 2026 17:17
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/deny-read-requirements branch from 62bed94 to bded322 Compare April 14, 2026 17:23
@viyatb-oai viyatb-oai marked this pull request as ready for review April 14, 2026 17:47
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/deny-read-globs branch from c8ede2c to b31b932 Compare April 16, 2026 06:40
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/deny-read-requirements branch from bded322 to f2836d0 Compare April 16, 2026 06:40
@viyatb-oai viyatb-oai changed the base branch from codex/viyatb/deny-read-globs to codex/viyatb/deny-read-globs-sandbox April 16, 2026 06:41
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/deny-read-globs-sandbox branch 2 times, most recently from 6e2a8c9 to f74937c Compare April 16, 2026 16:49
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/deny-read-requirements branch 2 times, most recently from afdd075 to 57c3a35 Compare April 16, 2026 16:58
viyatb-oai added a commit that referenced this pull request Apr 16, 2026
## Summary
- adds first-class filesystem policy entries for deny-read glob patterns
- parses config such as :project_roots { "**/*.env" = "none" } into
pattern entries
- enforces deny-read patterns in direct read/list helpers
- fails closed for sandbox execution until platform backends enforce
glob patterns in #18096
- preserves split filesystem policy in turn context only when it cannot
be reconstructed from legacy sandbox policy

## Stack
1. This PR - glob deny-read policy/config/direct-tool support
2. #18096 - macOS and Linux sandbox enforcement
3. #17740 - managed deny-read requirements

## Verification
- just fmt
- cargo check -p codex-core -p codex-sandboxing --tests

---------

Co-authored-by: Codex <noreply@openai.com>
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/deny-read-globs-sandbox branch 2 times, most recently from 4fac10c to 2cb6091 Compare April 16, 2026 17:51
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/deny-read-requirements branch from 57c3a35 to 4db0235 Compare April 16, 2026 22:51
@viyatb-oai viyatb-oai requested a review from bolinfest April 16, 2026 23:53
viyatb-oai added a commit that referenced this pull request Apr 17, 2026
## Summary
- adds macOS Seatbelt deny rules for unreadable glob patterns
- expands unreadable glob matches on Linux and masks them in bwrap,
including canonical symlink targets
- keeps Linux glob expansion robust when `rg` is unavailable in minimal
or Bazel test environments
- adds sandbox integration coverage that runs `shell` and `exec_command`
with a `**/*.env = none` policy and verifies the secret contents do not
reach the model

## Linux glob expansion

```text
Prefer:   rg --files --hidden --no-ignore --glob <pattern> -- <search-root>
Fallback: internal globset walker when rg is not installed
Failure:  any other rg failure aborts sandbox construction
```

```
[permissions.workspace.filesystem]
glob_scan_max_depth = 2

[permissions.workspace.filesystem.":project_roots"]
"**/*.env" = "none"
```


This keeps the common path fast without making sandbox construction
depend on an ambient `rg` binary. If `rg` is present but fails for
another reason, the sandbox setup fails closed instead of silently
omitting deny-read masks.

## Platform support
- macOS: subprocess sandbox enforcement is handled by Seatbelt regex
deny rules
- Linux: subprocess sandbox enforcement is handled by expanding existing
glob matches and masking them in bwrap
- Windows: policy/config/direct-tool glob support is already on `main`
from #15979; Windows subprocess sandbox paths continue to fail closed
when unreadable split filesystem carveouts require runtime enforcement,
rather than silently running unsandboxed

## Stack
1. #15979 - merged: cross-platform glob deny-read
policy/config/direct-tool support for macOS, Linux, and Windows
2. This PR - macOS/Linux subprocess sandbox enforcement plus Windows
fail-closed clarification
3. #17740 - managed deny-read requirements

## Verification
- Added integration coverage for `shell` and `exec_command` glob
deny-read enforcement
- `cargo check -p codex-sandboxing -p codex-linux-sandbox --tests`
- `cargo check -p codex-core --test all`
- `cargo clippy -p codex-linux-sandbox -p codex-sandboxing --tests`
- `just bazel-lock-check`

---------

Co-authored-by: Codex <noreply@openai.com>
Base automatically changed from codex/viyatb/deny-read-globs-sandbox to main April 17, 2026 00:35
viyatb-oai and others added 2 commits April 16, 2026 17:39
Add managed requirements plumbing for deny-read filesystem entries now that glob deny-read policy and platform enforcement are split below it in the stack.

Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex noreply@openai.com
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/deny-read-requirements branch from 4db0235 to e665898 Compare April 17, 2026 00:44
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.

This needs an end-to-end test in a follow-up.

@bolinfest bolinfest merged commit dae0608 into main Apr 17, 2026
53 of 58 checks passed
@bolinfest bolinfest deleted the codex/viyatb/deny-read-requirements branch April 17, 2026 15:40
@github-actions github-actions bot locked and limited conversation to collaborators Apr 17, 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.

2 participants