AI how-to notes · 2026-09-17 · last run 2026-09-17 · 한국어 원문
Codex CLI sandbox read-only vs workspace-write — compared by writing a file on Windows
One line summary
We sent the same "please create hello.txt" request through codex exec -s read-only and -s workspace-write. Under read-only the write was blocked and no file appeared; under workspace-write the file was created. Both runs exited 0, so whether it worked has to be checked against the file itself.
Who this is for
- Anyone wiring
codex execinto automation and deciding whether to let it change files - Anyone who wants to see in the logs what read-only actually blocks on Windows
- Anyone confused about where options like
-sand-alive
Test environment
| Item | Value |
|---|---|
| OS | Windows 11 Home (10.0.26200) |
| Shells | Git Bash, PowerShell 7.6.6 |
| codex | codex-cli 0.153.4 |
| Model (as shown in the run banner) | gpt-6-astra |
| Working folders | Empty folders sbx_ro and sbx_ww under a temp folder |
| Shared options | --skip-git-repo-check --ephemeral, with < /dev/null so stdin ends immediately |
The options in the help text
The sandbox and approval part of codex exec --help:
-s, --sandbox <SANDBOX_MODE>
Select the sandbox policy to use when executing model-generated shell commands
[possible values: read-only, workspace-write, danger-full-access]
--approve-for-me
Route approval requests through automatic review using the workspace-write sandbox
--dangerously-bypass-approvals-and-sandbox
Skip all confirmation prompts and execute commands without sandboxing. EXTREMELY
DANGEROUS. Intended solely for running in environments that are externally sandboxed
--add-dir <DIR>
Additional directories that should be writable alongside the primary workspace-a, --ask-for-approval is not in codex exec --help; it appears only in the top-level codex --help.
-a, --ask-for-approval <APPROVAL_POLICY>
Configure when the model requires human approval before executing a command
Possible values:
- on-request: The model decides when to ask the user for approval
- never: Never ask for user approval Execution failures are immediately returned to
the modeldanger-full-access and --dangerously-bypass-approvals-and-sandbox are quoted from the help text only; we did not run them.
The official documentation describes read-only and workspace-write this way: "read-only : The agent can inspect files, but it can't edit files or run commands without approval. workspace-write : The agent can read files, edit within the workspace, and run routine local commands inside that boundary." (learn.chatgpt.com/docs/sandboxing, checked 2026-09-17)
1. Running with read-only
cd sbx_ro
codex exec --skip-git-repo-check --ephemeral -s read-only -o ../ro_last.txt \
'Create a file named hello.txt in the current working directory containing exactly: hello. Do not use any other directory. Then reply with one line: DONE if the file now exists, otherwise FAILED plus the error.' < /dev/null
echo "codex exit=$?"codex exit=0. The whole command, including the post-run file check, took 30.7 seconds. The folder was empty afterwards and hello.txt: not found was printed. The final answer read:
FAILED: Access denied when creating hello.txt; the current directory is read-only.The banner said approval: never and sandbox: read-only. Standard error shows codex attempting the write twice through PowerShell, blocked in two different ways each time.
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage
...
+ CategoryInfo : PermissionDenied: (C:\Users\User\A...bx_ro\hello.txt:String) [Set-Content], Unauthorized
AccessException
+ FullyQualifiedErrorId : GetContentWriterUnauthorizedAccessError,Microsoft.PowerShell.Commands.SetContentCommandThe first attempt ([System.IO.File]::WriteAllText) was blocked by PowerShell at the method call itself; the second (Set-Content) failed on file access denied. The Korean error explanations were garbled and unreadable. A third command, Test-Path, ran normally and returned False.
The documentation's read-only description says it can't run commands without approval. In this run (approval: never), both write attempts and Test-Path did execute, and only the writes failed.
2. Running with workspace-write
We changed only -s workspace-write, -o ../ww_last.txt and the empty folder sbx_ww, and sent the same request.
codex exit=0, final answer DONE. The whole command including the file check was 24.6 seconds. The banner printed the writable boundary alongside it.
approval: never
sandbox: workspace-write [workdir, /tmp, $TMPDIR]The file was created, but the contents weren't hello.
-rw-r--r-- 1 User 197121 6 Sep 17 18:13 hello.txt
hello.
68 65 6c 6c 6f 2eThe string codex wrote in the workspace-write run was 'hello.', while the string it tried to write in the read-only run was 'hello'. The two runs evidently read the period in the request containing exactly: hello. differently. When you write a request like this, quote the content. The [System.IO.File]::WriteAllText method that was blocked under read-only was called again here with different arguments (specifying UTF-8 encoding), and it succeeded.
Comparing the PowerShell environment in the two modes
We had codex run the same read-only command verbatim in both modes.
$ExecutionContext.SessionState.LanguageMode; (Get-Command python -ErrorAction SilentlyContinue).Source; $env:USERNAME| Where it ran | LanguageMode | python path | USERNAME |
|---|---|---|---|
Outside the sandbox (pwsh -NoProfile) | FullLanguage | C:\Users\User\AppData\Local\Programs\Python\Python312\python.exe | User |
codex -s read-only | ConstrainedLanguage | (no output) | User |
codex -s workspace-write | FullLanguage | (no output) | User |
Only under read-only was PowerShell running in ConstrainedLanguage, which lines up with the MethodInvocationNotSupportedInConstrainedLanguage from section 1. The python path printed nothing in either mode. Outside the sandbox the path did come out, so it's only in the environment codex runs commands in that it isn't found. The time codex tried to run tests and couldn't find python is written up separately in Reviewing code before you commit with codex review.
How the sandbox works on Windows
The argument description in codex sandbox --help names the Windows mechanism.
[COMMAND]...
Full command args to run under Windows restricted token sandboxThe Windows sandbox section of the official documentation describes two approaches: "When you run Codex natively on Windows, agent mode uses a Windows sandbox to block filesystem writes outside the working folder and prevent network access without your explicit approval." It says elevated uses "dedicated lower-privilege sandbox users" while unelevated uses "a restricted Windows token derived from your current user" (learn.chatgpt.com/docs/windows/windows-sandbox, checked 2026-09-17). We did not determine which of the two this PC ran under. We didn't open the config file, and the USERNAME values in the table above can't settle it.
Our attempts to run commands directly through codex sandbox were blocked all three times.
windows sandbox failed: runner failed during SpawnChild: CreateProcessAsUserW failed: 2 (지정된 파일을 찾을 수 없습니다.) | cwd=C:\Users\User\AppData\Local\Temp\longtail_A2 | cmd=windows --help | ...
error: the following required arguments were not provided:
--permission-profile <NAME>
Error: default_permissions requires a `[permissions]` tableThe first line is what happened when we typed codex sandbox windows --help: it took windows as the command to run and tried to execute it inside the sandbox. (This PC runs Korean-locale Windows, so the OS error text is in Korean — it reads "the specified file could not be found".) The second line is from running it without -P, the third from passing -P read-only. It looks like the config file needs a [permissions] table, and we stopped there.
Results
| Round | Mode | Exit code | Time | hello.txt | Final answer |
|---|---|---|---|---|---|
| 1 | -s read-only | 0 | 30.7s (whole command) | not created | FAILED: Access denied ... |
| 2 | -s workspace-write | 0 | 24.6s (whole command) | created (6 bytes, hello.) | DONE |
| 3 | Environment check in both modes (run back to back) | 0, 0 | 35.3s (both combined) | n/a | see the table |
What failed
This read-only run returned an answer saying file creation failed, and still exited 0. Automation must check a new file and its contents. The earlier suggestion, test -f hello.txt || echo ..., can print an error and still exit 0; it also accepts stale files and wrong contents.
Running codex sandbox -P read-only produced the error about needing a [permissions] table, so we stopped there in trying to feed commands directly to codex sandbox.
Newly checked — 2026-09-28
Save verify-new-output.sh in the current directory to run the write check. It requires Bash, mktemp, cmp, and an installed, authenticated Codex CLI.
bash verify-new-output.sh writeThe script creates a fresh directory with mktemp -d ./codex-check.XXXXXXXX and runs the request there with -s workspace-write. The request quotes "hello" and explicitly asks for five UTF-8 bytes with no period, BOM, or newline. A nonzero Codex exit code is preserved. Even after exit 0, hello.txt must be a regular file (not a symbolic link), and cmp must match those exact five bytes. Missing or incorrect output exits 1; success prints verified: <new directory>/hello.txt and exits 0. The test directory and final-answer file last.txt remain for inspection. Each run starts in a new directory, so it neither overwrites existing user files nor passes because of an old artifact.
This new check tested only the guard with a mock producer on Linux, Bash `5.2.21`. Correct output returned 0; missing, empty, wrong, newline-suffixed, and symbolic-link output each returned 1. A producer that wrote the correct file and exited 37 propagated 37. An old hello.txt in the parent directory did not rescue the missing-output case, and every run had a different fresh directory. No Codex binary, login, or Windows was available, so model-driven file creation and sandbox boundaries were not retested. These checks do not replace the 2026-09-17 measurements above.
What we did not test
- We did not run
danger-full-access,--dangerously-bypass-approvals-and-sandboxor--approve-for-me. - We did not test a flow where a human approves, such as
-a on-request. - We did not test what happens when workspace-write is asked to write outside the working folder. Our temp folder sits under
%TEMP%, so the banner's$TMPDIRallowance would muddy the result. - We did not check
--add-diror network access blocking. - We do not know whether this PC's Windows sandbox is
elevatedorunelevated. - We did not investigate why
pythonwasn't found in codex's PowerShell. - We did not run any of this on WSL, macOS or Linux.