Execpolicy allow rules silently stay sandboxed when any denied-read path is configured
What variant of Codex are you using?
Codex Desktop on macOS.
What version of Codex is running?
- Desktop:
26.803.81509 - Bundled CLI:
0.147.0-alpha.6.6
What is the issue?
An execpolicy allow rule silently stops running its matching command outside the sandbox as soon as the active filesystem permission profile contains any denied-read restriction.
This conflicts with the Rules documentation, which describes rules as controlling which commands run outside the sandbox. codex execpolicy check still reports allow, but execution remains in the default sandbox and no diagnostic explains that the rule cannot provide the documented sandbox placement.
Minimal reproduction
Use a synthetic denied path so no credential or private path is involved:
approval_policy = "on-request"
default_permissions = "repro"
[permissions.repro.filesystem]
":root" = "write"
"/tmp/codex-denied-read-probe" = "deny"
Add a matching rule:
prefix_rule(
pattern = ["/usr/bin/open"],
decision = "allow",
justification = "Synthetic sandbox-placement probe.",
match = [
"/usr/bin/open -Rb com.apple.TextEdit",
],
)
Verify the policy result:
$ codex execpolicy check --rules <CODEX_HOME>/rules/repro.rules --pretty /usr/bin/open -Rb com.apple.TextEdit
Decision: allow
Run the matching command directly from a Desktop task. It still receives the Seatbelt environment and LaunchServices access fails as it does for an ordinary sandboxed command.
The result is deterministic in the matching release source:
unsandboxed_execution_allowed()returns false wheneverhas_denied_read_restrictions()is true.sandbox_override_for_first_attempt()therefore refusesBypassSandboxFirstAttempteven forSkip { bypass_sandbox: true }.- Unix rule escalation maps a policy-driven match to
EscalationExecution::TurnDefaultwhen unsandboxed execution is not allowed.
Sources:
- https://github.com/openai/codex/blob/rust-v0.147.0-alpha.6.6/codex-rs/core/src/tools/sandboxing.rs
- https://github.com/openai/codex/blob/rust-v0.147.0-alpha.6.6/codex-rs/core/src/tools/runtimes/shell/unix_escalation.rs
- https://learn.chatgpt.com/docs/agent-configuration/rules
Expected behavior
A single denied-read path should not silently disable every configured per-command sandbox escape.
The safety check must not simply be removed: running the current command process unsandboxed would discard the denied-read restrictions. Instead, Codex needs either:
- a trusted host-side command executor that can run an explicitly matched executable outside the agent sandbox while the agent and ordinary shell commands remain subject to denied reads; or
- an independent sandbox-placement policy with a security model that preserves the intended credential boundary.
At minimum, if the active permission model cannot honor an outside-sandbox rule, config validation and runtime output should report that incompatibility instead of returning allow and silently using TurnDefault.
Impact
The current behavior makes two documented safety mechanisms mutually exclusive:
- denied reads protect credentials and other sensitive files from ordinary agent commands;
- Rules are supposed to let selected trusted CLIs use host-only state outside the sandbox.
Configuring even one denied-read path removes the second capability globally. Users must then choose between dropping credential protection, using full access, or implementing a separate trusted broker.
This is a concrete interaction with the broader sandbox-placement/approval separation requested in #20917.
2 Comments
I revalidated this against
origin/mainat72fa74fbc9c4b72d513304bfa0eda427d2402ed9.The current behavior is internally consistent but user-visible semantics are ambiguous:
allowdecision setsbypass_sandbox: true;sandbox_override_for_first_attempt()deliberately suppresses that bypass when the active filesystem policy has denied reads;EscalationExecution::TurnDefault;A previous attempt in #30120 built an otherwise-unrestricted sandbox profile that retained denied reads, but it was closed after remote-executor, managed-network, and Windows ACL-cost concerns. That makes a trusted host-side/independent-placement solution materially larger than a diagnostic-only change.
Could maintainers clarify the intended first-stage behavior when an
allowrule matches but denied reads make unsandboxed execution unsafe?Any option should keep denied-read protections intact. If option 1 or 2 is preferred and an external PR would be useful, please state the intended warning/error semantics and explicitly invite the contribution per the repository policy.
I did not open an upstream PR because the contribution policy says external PRs are invitation-only. I prepared a focused draft with regression coverage at https://github.com/dajiaohuang/codex/pull/3.
It preserves denied-read enforcement and takes the smallest reversible option from the earlier proposal: one deduplicated warning when an authoritative execpolicy allow match must remain sandboxed. The draft documents the alternative error/trusted-executor directions and the local Windows validation boundary for its Unix-only test.
If this direction fits the project's intended safety semantics, an invitation would let me submit it through the project's normal review process.