openai / openai/codex

macOS app-server: nested workspace-write tools fail before execution with sandbox_apply exit 71

Open
#45,657 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app-server bug sandbox tool-calls
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Summary

On macOS, a long-running Codex app-server that is already running under an outer Seatbelt policy cannot start normal workspace-write tool commands. Both exec_command and the internal apply_patch tool fail before the requested operation begins with:

sandbox-exec: sandbox_apply: Operation not permitted

The same read-only command succeeds when retried through require_escalated, which bypasses the failing nested sandbox path. This points to sandbox setup rather than project file permissions.

Environment

  • macOS 26.6 / Darwin 25.6.0, Apple Silicon arm64
  • Bundled Codex CLI: 0.154.0-alpha.6.2
  • Surface: long-running codex app-server over stdio
  • Parent app-server process is already constrained by an outer macOS Seatbelt policy
  • Turn policy: workspace-write
  • cwd and writable root both contain the target file

Observed behavior

A normal exec_command that only reads a file inside the writable workspace fails immediately:

sandbox-exec: sandbox_apply: Operation not permitted

No command output is produced, indicating that the requested child command never starts.

Retrying the same read via require_escalated succeeds.

The internal apply_patch tool also fails on a file inside the workspace:

apply_patch verification failed: Failed to read file to update $WORKSPACE/file.md:
fs sandbox helper failed with status exit status: 71:
sandbox-exec: sandbox_apply: Operation not permitted

Because apply_patch has no per-call escalation path, ordinary workspace edits are blocked even though the file is within the declared writable root.

Expected behavior

  • A workspace-write tool call should be able to read and edit files inside its declared writable root even when app-server has an outer security boundary.
  • If nested Seatbelt application is unsupported, the runtime should preserve the parent sandbox and avoid applying a conflicting child sandbox, or return a structured diagnostic with a safe recovery path.
  • apply_patch should not become unusable solely because its sandbox helper cannot apply a second profile.

Reproduction outline

  1. Launch codex app-server on macOS from a parent process already constrained by Seatbelt.
  2. Start a turn using workspace-write with a valid cwd and writable root.
  3. Run a trivial exec_command against a file inside that root.
  4. Run apply_patch against the same file.
  5. Observe both fail before execution with sandbox_apply and exit 71.
  6. Retry the read through require_escalated and observe it succeed.

Notes

This resembles nested macOS sandbox failures reported in:

  • #30615
  • #26262
  • #18243
  • #19020

The exact surface here is different: a long-running app-server turn where both exec_command and internal apply_patch fail, while the same command succeeds through the escalation path.

I have not disabled sandboxing as a workaround because that would weaken the intended security boundary.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Begin by tracing the macOS sandbox setup used by the app-server's exec_command and apply_patch paths; no source files or tests are identified in the report. Reproduce the nested Seatbelt case and compare normal workspace-write with require_escalated. Done means workspace reads and edits work under an outer policy, or a structured safe diagnostic and recovery path is covered.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, rust
Domain
backend, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.