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 -v works, while the same node appears "not found" to which/ls/fs.stat.
process.execPath is reported as node (not an absolute path), consistent with stat on 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-access makes 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/ls on 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, and pnpm test without EPERM.
Searched for duplicates
No exact match found (searched workspace-write with EPERM / Operation not permitted and sandbox / danger-full-access).
Summary
Under the default
workspace-writesandbox on macOS, read/stat/open on files outside the workspace returnsEPERM("Operation not permitted"), including/System/Library/OpenSSL/openssl.cnfand 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-accessmakes 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
workspace-write(default config, no customwritable_roots)Minimal reproduction (no toolchain involved)
In a normal
workspace-writesession:stat()on the directory succeeds, butstat()/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:Impact on the Node toolchain
which/command -vreport these as not found (the sandbox deniesstatduring PATH lookup), yet zsh still attempts the exec by name and the kernel returnsEPERM.Observed behavior: exec sometimes works, reads/stat do not
Probing each path from Node's
fsandfs.accessSync(X_OK/R_OK) inside theworkspace-writesandbox:~/.nvm/.../bin/node~/.nvm/.../bin/pnpm.../corepack/dist/pnpm.js/opt/homebrew/bin/brew/System/Library/OpenSSL/openssl.cnfFrom 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.Net effect: a native binary such as
nodecan 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.cat/lson system files, so it is not a Corepack network/cache issue.pnpm check,pnpm typecheck, andpnpm testwithout EPERM.Searched for duplicates
No exact match found (searched
workspace-writewithEPERM/Operation not permittedandsandbox/danger-full-access).