workspace-write sandbox denies file reads outside workspace on macOS, breaking pnpm/Corepack
Summary
Under the default workspace-write sandbox on macOS, read/stat/open on files outside the workspace returns EPERM ("Operation not permitted"), including /System/Library/OpenSSL/openssl.cnf and Homebrew/nvm paths. This is not a write or network restriction; plain reads are blocked. As a result, Node cannot load its OpenSSL config, and pnpm/Corepack cannot run. Running with --sandbox danger-full-access makes everything work, which points to the sandbox profile rather than macOS TCC or the toolchain.
Is denying reads outside the workspace the intended behavior for workspace-write? If so, could Node's OpenSSL config read (and script/symlink-based tools such as pnpm/Corepack) be accommodated? If not, this looks like a regression.
Environment
| | |
|---|---|
| macOS | Tahoe 26.5.1 (build 25F80) |
| Kernel | Darwin 25.5.0 arm64 |
| Codex CLI | 0.141.0 |
| Shell | zsh |
| Node | v24.13.0 (nvm) |
| pnpm | 10.30.2 (Corepack shim) |
| Sandbox | workspace-write (default config, no custom writable_roots) |
Minimal reproduction (no toolchain involved)
In a normal workspace-write session:
ls -ld /System/Library/OpenSSL # success (dir stat OK)
ls -l /System/Library/OpenSSL/openssl.cnf # Operation not permitted
cat /System/Library/OpenSSL/openssl.cnf # Operation not permitted
ls -l /opt/homebrew/bin/brew # Operation not permitted
stat() on the directory succeeds, but stat()/open() on files within it is denied, so this is a file read/stat denial rather than a missing or untraversable path.
The same commands succeed under codex --sandbox danger-full-access:
ls -l /opt/homebrew/bin/pnpm # ../Cellar/pnpm/10.21.0/bin/pnpm
pnpm --version # 10.30.2
Impact on the Node toolchain
# Node cannot read its OpenSSL config:
node --input-type=module -e "console.log(process.version)"
# OpenSSL configuration error
# BIO_new_file: Operation not permitted
# calling fopen(/System/Library/OpenSSL//openssl.cnf, rb)
# Workaround (point OPENSSL_CONF at a nonexistent file so Node skips it):
env OPENSSL_CONF=/private/tmp/nonexistent-openssl.cnf \
node --input-type=module -e "console.log(process.version)"
# v24.13.0 (exit 0)
# pnpm / Corepack cannot run:
pnpm --version # exit 127, zsh:1: operation not permitted: pnpm
corepack --version # exit 127, zsh:1: operation not permitted: corepack
which/command -v report these as not found (the sandbox denies stat during PATH lookup), yet zsh still attempts the exec by name and the kernel returns EPERM.
Observed behavior: exec sometimes works, reads/stat do not
Probing each path from Node's fs and fs.accessSync (X_OK/R_OK) inside the workspace-write sandbox:
| path | type | stat | readFile | access X | access R |
|---|---|---|---|---|---|
| ~/.nvm/.../bin/node | Mach-O binary | EPERM | EPERM | OK | EPERM |
| ~/.nvm/.../bin/pnpm | symlink | EPERM | EPERM | EPERM | EPERM |
| .../corepack/dist/pnpm.js | JS shim | EPERM | EPERM | OK | EPERM |
| /opt/homebrew/bin/brew | Mach-O binary | EPERM | EPERM | OK | EPERM |
| /System/Library/OpenSSL/openssl.cnf | config file | EPERM | EPERM | — | EPERM |
From the observed behavior, it looks like file reads/stat calls are denied while some direct exec paths are still allowed. This is consistent with the otherwise confusing results:
node -vworks, while the samenodeappears "not found" towhich/ls/fs.stat.process.execPathis reported asnode(not an absolute path), consistent withstaton argv0 being denied.- pnpm/Corepack fail even though some exec checks pass, likely because launching a symlink/JS shim involves resolving or reading files that are denied by the sandbox.
Net effect: a native binary such as node can execute, but tools that need to read files outside the workspace during startup (symlinks, JS shims, shebang scripts, config files, which/stat) fail with EPERM.
Additional notes
danger-full-accessmakes all of the above succeed, which makes this look specific to Codex's sandbox profile rather than a general macOS TCC / Full Disk Access issue.- It reproduces with a plain
cat/lson system files, so it is not a Corepack network/cache issue. - For reference, another sandboxed coding tool on the same machine, same repo, and same Node/pnpm setup can run
pnpm check,pnpm typecheck, andpnpm testwithout EPERM.
Searched for duplicates
No exact match found (searched workspace-write with EPERM / Operation not permitted and sandbox / danger-full-access).
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗