Codex CLI 샌드박스 모드와 승인 정책 설정: 무엇이 막히나

게시 읽는 시간 약 10분 시작 가이드

Codex CLI의 codex sandbox로, 옵션 없이 작업 폴더에 파일 하나를 만들어 봤습니다.

codex sandbox -- bash -c 'echo x > f1.txt'
bash: line 1: f1.txt: Read-only file system

작업 폴더 안인데도 막혔어요. 기본 샌드박스가 read-only라서입니다.

코드를 고치게 하려면 -s workspace-write로 실행해야 하고, 그래도 작업 폴더와 임시 폴더(/tmp, Windows는 %TEMP%)에만 쓸 수 있습니다. 작업 폴더 안의 .git/·.aws/와 홈 폴더·상위 폴더는 여전히 막혀요.

2026년 9월 15일 Ubuntu 24.04에서 Codex CLI 0.154.0으로, 10월 2일 0.159.0으로, 10월 5일 Windows 11 · PowerShell 5.1에서 0.159.3으로 직접 확인했고, Windows 쪽은 10월 14일 0.162.1에서 다시 돌려 봤습니다.

확인한 버전·환경

  • Codex CLI 0.162.1 (npm) · Windows 11 · Windows PowerShell 5.1 · 확인일 2026-10-14
  • Codex CLI 0.159.0 (npm) · Ubuntu 24.04 LTS · bash · 확인일 2026-10-02

기본값으로는 작업 폴더에도 못 쓴다

codex sandbox는 로그인 없이, 모델을 거치지 않고 명령 하나를 같은 경계 안에서 실행하는 명령입니다. 경계를 눈으로 확인하기 좋아서 쓰기·읽기 경계는 이걸로 봤어요. 모드를 workspace-write로 바꾸면 위에서 막혔던 명령이 통과합니다.

codex sandbox -c sandbox_mode='"workspace-write"' -- bash -c 'echo x > f.txt && echo OK'
OK

세 모드는 쓰기 범위로 갈립니다.

모드 작업 폴더 쓰기 작업 폴더 밖 쓰기 언제 쓰나
read-only(기본) 거부 거부 읽고 설명만 들을 때
workspace-write 허용(일부 폴더 제외) 임시 폴더만 코드를 고칠 때
danger-full-access 허용 허용 컨테이너·가상 머신 안

평소 실행에서는 codex -s workspace-write처럼 -s(--sandbox)로 주거나, config.toml에 sandbox_mode로 적어 두면 됩니다.

danger-full-access로 두면 매번 막히지 않아 편하긴 합니다. 하지만 이 모드에서는 홈 폴더의 설정 파일이든 다른 저장소든 에이전트가 쓸 수 있어요. 이름 그대로 컨테이너처럼 바깥에 격리가 따로 있을 때만 고르는 선택지라고 생각합니다.

그리고 이 장치가 막지 못하는 게 있습니다. read-only에서도 작업 폴더 밖의 /etc/os-release와 홈 디렉터리의 파일이 그대로 읽혔거든요. 샌드박스 모드는 쓰기를 막는 장치이지 읽기를 막는 장치가 아닙니다. 자격 증명 파일이 걱정되면 실행 환경 자체를 나눠야 해요.

workspace-write가 막는 곳

git 저장소로 만든 작업 폴더에서 쓰기 대상만 바꿔 가며 확인했습니다.

쓰기 대상 0.154.0 0.159.0
작업 폴더 안 일반 파일 성공 성공
/tmp 성공 —
작업 폴더 안 .git/·.agents/·.codex/ 거부 거부
작업 폴더 안 .aws/ 성공 거부
홈 디렉터리·작업 폴더의 상위 폴더 거부 —

—는 0.159.0 비교에서 뺀 칸입니다. 거부된 곳은 모두 셸에서 Read-only file system으로 나왔어요.

workspace-write 모드에서 쓰기가 되는 곳은 작업 폴더, /tmp(Windows는 %TEMP%), --add-dir이나 writable_roots로 더한 폴더이고, 작업 폴더 안의 .git·.agents·.codex 폴더(0.159.0부터는 .aws도), 홈 디렉터리, 작업 폴더의 상위 폴더는 쓰기가 거부된다는 것을 보여 주는 그림. 읽기는 이 경계 밖까지 열려 있습니다.
workspace-write에서 초록 칸에만 쓸 수 있고, 작업 폴더 안이라도 .git·.agents·.codex·.aws는 막힙니다.

해 보고 의외였던 건 /tmp가 기본으로 열려 있다는 점이었습니다. 작업 폴더에만 쓴다고 생각하고 고르면 임시 디렉터리에도 파일이 남을 수 있어요.

.git/·.agents/·.codex/가 작업 폴더 안인데도 막힌다는 것도 예상 밖이었고요. 커밋 기록과 훅, 에이전트 설정이 있는 자리라 빠진 것으로 보입니다.

0.159.0부터는 .aws/도 막힌다

0.159.0(2026년 9월 29일) 릴리스 노트에 쓰기 뿌리 아래의 .aws 디렉터리를 기본으로 보호한다는 수정이 들어 있습니다. 이 변경(#48176)은 .aws를 .git·.agents·.codex와 같은 보호 목록에 넣었고, 작업 폴더와 추가 쓰기 폴더 양쪽에 적용돼요. AWS 프로필이 실행할 자격 증명 도우미 프로그램을 지정할 수 있어서라고 합니다.

사용자가 명시적으로 적은 규칙은 이 기본 보호보다 우선한다고 합니다.

같은 날 두 버전에서 작업 폴더의 .aws/config를 읽고 한 줄을 덧붙여 봤습니다.

$ codex sandbox -c sandbox_mode='"workspace-write"' -- bash -c 'cat .aws/config; echo y >> .aws/config && echo APPENDED'
# 0.154.0
[default]
APPENDED
# 0.159.0
[default]
bash: line 1: .aws/config: Read-only file system

읽기는 그대로 되고 쓰기만 막혔습니다. writable_roots로 더한 폴더 안의 .aws/도 0.159.0에서 같이 거부됐어요.

함정: 0.159.0에서는 .aws/가 없는 작업 폴더에서 mkdir .aws를 해도 mkdir: cannot create directory '.aws': File exists로 실패하고 폴더는 생기지 않았습니다(리눅스). 이미 있다는 말이 아니라 보호 경로라서 막힌 것입니다.

필요한 폴더만 더하기

쓰기 경로가 더 필요해도 모드를 danger-full-access로 올리지 마세요. 그 폴더만 더하면 됩니다.

설정 하는 일 확인한 결과
--add-dir <DIR> 이번 실행에 쓰기 폴더 추가 헤더 목록 끝에 추가
sandbox_workspace_write.writable_roots 쓰기 폴더를 늘 추가 그 폴더에 쓰기 성공
sandbox_workspace_write.exclude_slash_tmp = true /tmp 쓰기 막기 거부로 바뀜
sandbox_workspace_write.network_access = true 네트워크 허용 연결 단계 통과

저는 한 번만 쓸 경로는 --add-dir, 늘 쓰는 경로는 config.toml의 writable_roots에 두길 권합니다. 네트워크는 기본값에서 샌드박스 안의 연결 시도가 연결 단계에서 실패했고, network_access=true를 주자 그 단계를 지나갔습니다.

키 이름이 맞는지 의심되면 --strict-config를 붙이세요.

없는 키를 넣으면 Error loading config.toml: unknown configuration field ... in -c/--config override로 실행 전에 멈춥니다. 오타를 넣고 조용히 기본값으로 도는 일을 막아 줘요.

승인 정책은 on-request와 never뿐

다른 글에서 본 명령을 그대로 붙이면 이렇게 멈춥니다.

$ codex -a untrusted
error: invalid value 'untrusted' for '--ask-for-approval <APPROVAL_POLICY>'
  [possible values: on-request, never]

승인 정책(-a, --ask-for-approval)은 명령을 실행하기 전에 사용자 승인을 언제 받을지 정합니다. 지금 받는 값은 오류 메시지대로 둘이에요. on-request는 승인을 물을지 모델이 판단하고, never는 묻지 않고 실행이 실패하면 바로 모델에게 돌려줍니다.

untrusted를 설정 파일이나 -c로 넣어도 Error: approval_policy = "untrusted" is no longer supported; remove this setting로 멈추고, on-failure도 -a에서는 거부됩니다. --full-auto 플래그는 아예 사라졌어요(error: unexpected argument '--full-auto' found).

다른 글의 명령줄을 복사하기 전에 codex --help를 한 번 열어 보세요.

--full-auto를 쓰던 스크립트라면 두 축을 따로 지정하면 됩니다. 쓰기가 필요하면 -s workspace-write, 승인을 자동 검토로 넘기려면 codex exec에 --approve-for-me를 줍니다. 고치기 전에 codex exec --help로 지금 버전이 받는 플래그를 확인하세요.

실제 값은 exec 헤더로 본다

설정을 어떻게 적었든 실제로 적용된 값은 codex exec가 시작할 때 찍는 헤더의 approval:·sandbox: 두 줄에 나옵니다(0.154.0).

실행 옵션 approval: sandbox:
(없음) never read-only
-s workspace-write never workspace-write [workdir, /tmp, $TMPDIR]
-s workspace-write --add-dir /tmp/extra never … $TMPDIR, /tmp/extra]
--approve-for-me on-request workspace-write [workdir, /tmp, $TMPDIR]
--dangerously-bypass-approvals-and-sandbox never danger-full-access

대괄호 안이 쓰기가 허용된 목록입니다. 다만 .git/ 같은 예외는 이 목록에 나오지 않아요.

Windows 11 · 0.162.1에서도 헤더 모양은 같았습니다. -s workspace-write는 sandbox: workspace-write [workdir, /tmp, $TMPDIR], --add-dir C:\work\extra를 더하면 [workdir, /tmp, $TMPDIR, C:\work\extra]였어요. Windows인데도 %TEMP%가 아니라 /tmp, $TMPDIR로 찍히니, 이 두 이름을 Windows의 임시 폴더로 읽으면 됩니다.

codex exec에는 헷갈리는 데가 몇 군데 있습니다. 우선 codex exec에는 -a가 없어요.

대신 --approve-for-me를 주면 승인을 사람에게 묻지 않고 workspace-write 샌드박스의 자동 검토로 넘깁니다. 위 표에서 이 플래그만 on-request를 만들었죠.

approval_policy 설정도 exec 헤더에 반영되지 않았습니다. on-request·never·on-failure로 바꿔도 세 번 모두 approval: never였어요. 실제로 적용된 값은 헤더를 보세요.

--dangerously-bypass-approvals-and-sandbox는 모든 확인을 건너뛰고 샌드박스 없이 실행합니다. 도움말 스스로 매우 위험하며 바깥에서 이미 격리된 환경 전용이라고 경고해요.

Windows에서 해 보니

Windows 11 · PowerShell 5.1 · Codex CLI 0.159.3에서 작업 폴더를 C:\work\project로 두고 바깥에 파일을 써 봤습니다.

codex sandbox -c sandbox_mode=workspace-write -- powershell.exe -NoProfile -Command 'Set-Content -Path C:\work\outside.txt -Value hi'
Set-Content : 'C:\work\outside.txt' 경로에 대한 액세스가 거부되었습니다.

PowerShell 5.1에서는 -c 값을 이렇게 따옴표 없이 적습니다. 외부 프로그램에 넘기는 인자에서 안쪽 큰따옴표가 지워지는데, -c는 TOML로 읽히지 않는 값을 문자열로 받으므로 그대로 동작하거든요. 나머지 결과도 리눅스와 같았습니다.

시도 결과
read-only에서 작업 폴더 안 쓰기 거부
workspace-write에서 작업 폴더 안 / %TEMP% 쓰기 허용
작업 폴더 밖·홈 폴더(%USERPROFILE%) 쓰기 거부
작업 폴더 안 .git\·.aws\ 쓰기 거부
작업 폴더 밖 파일 읽기 허용
Invoke-WebRequest https://example.com 실패(원격 서버에 연결할 수 없습니다.)

10월 14일 0.162.1에서 작업 폴더 안 쓰기, 작업 폴더 밖·.git\·.aws\ 쓰기, Invoke-WebRequest를 다시 해 봐도 결과가 표와 같았습니다.

경계는 같았고, 다른 건 겉모습이었어요. 거부될 때 Read-only file system 대신 PowerShell의 UnauthorizedAccessException, 한국어 Windows에서는 “경로에 대한 액세스가 거부되었습니다”로 나옵니다.

더 조심할 건 종료 코드입니다. Set-Content의 거부는 명령을 멈추지 않는 오류라서, Set-Content …; "OK"처럼 뒤에 명령을 이어 붙이면 거부 메시지가 찍히고도 종료 코드는 0이었어요. 스크립트에서는 메시지를 같이 보세요.

공식 Windows 문서는 샌드박스가 어떤 폴더를 읽지 못해 실패하면 /sandbox-add-read-dir C:\absolute\directory\path로 읽기 폴더를 더하라고 안내합니다. 이번에는 작업 폴더 밖 파일도 그대로 읽혀 필요하지 않았습니다.

처음 보는 CodexSandboxUsers 그룹

사용자 관리 화면에서 처음 보는 그룹과 계정이 보였다면 이것입니다.

PS> net localgroup CodexSandboxUsers
Alias name     CodexSandboxUsers
Comment        Codex sandbox internal group (managed)
Members
CodexSandboxOffline
CodexSandboxOnline

Windows 샌드박스에는 elevated와 unelevated 두 방식이 있고, config.toml의 [windows] 아래 sandbox로 고릅니다. elevated는 권한이 낮은 전용 샌드박스 사용자, 파일 시스템 권한 경계, 방화벽 규칙, 로컬 정책 변경으로 경계를 걸어요.

테스트 환경은 sandbox = "elevated"였습니다. 두 계정은 이름으로 보아 네트워크를 막은 실행과 허용한 실행에 각각 쓰는 것으로 추정하지만, 문서가 이름으로 설명하지는 않습니다. 한국어 Windows 기본 창에서는 항목 이름이 “별칭·설명·구성원”으로 나와요.

관리자 승인이 필요한 elevated를 회사 정책 등으로 쓸 수 없다면 unelevated를 씁니다. elevated보다 약하지만 그런 환경에서는 여전히 쓸모 있다고 문서가 설명합니다.

막혔을 때 보는 오류

Read-only file system

파일을 만들거나 고치는 명령이 셸에서 이 오류로 끝나는 경우입니다. 디스크가 찬 것도, 권한 문제(Permission denied)도 아니에요. Windows에서는 “경로에 대한 액세스가 거부되었습니다”로 나옵니다.

그 경로가 지금 모드의 쓰기 경계 밖이라는 뜻입니다. read-only에서는 작업 폴더도 밖이고, workspace-write에서는 상위 폴더·홈·.git/이, 0.159.0부터는 .aws/도 밖이에요.

헤더의 sandbox: 줄로 지금 모드와 쓰기 목록을 보고, 필요한 폴더만 --add-dir이나 writable_roots로 더하세요.

같은 경계가 에이전트의 보고(patch rejected: writing is blocked by read-only sandbox)로 나오고 종료 코드 0으로 끝나는 경우는 Codex CLI 오류 7가지와 종료 코드에 있습니다.

error: invalid value 'untrusted' for '--ask-for-approval <APPROVAL_POLICY>'

그 값이 이 버전에 없다는 뜻입니다. 오류 메시지 대괄호 안의 값(on-request, never) 중에서 고르고, 설정 파일에 있으면 그 줄을 지우면 됩니다.

Codex could not find bubblewrap on PATH

리눅스에서 리눅스 샌드박스가 쓰는 bubblewrap이 PATH에 없을 때 경고가 한 줄 뜨고, 실행은 멈추지 않습니다. 경고 문구대로 그동안은 함께 배포된 bubblewrap을 쓰며, 이 상태에서도 위의 쓰기 거부는 그대로 동작했어요. 경고를 없애려면 패키지 관리자로 bubblewrap을 설치하세요.

다른 사람들이 겪은 문제

헤더를 매번 보라고 하는 이유가 여기 있습니다. 설정과 실제 경계가 어긋났다는 보고들이에요.

아래 두 건은 다른 사람이 공개 저장소에 올린 보고입니다. 2026년 9월 15일 확인 시점에 모두 열려 있었습니다.

  • mattgdrums-cloud는 커스텀 에이전트 파일에 sandbox_mode = "read-only"를 적어도, codex exec에서 띄운 자식 에이전트가 부모의 workspace-write로 돌아 파일 쓰기까지 성공했다고 보고했습니다(2026-09-14, #45482, 0.153.4). model은 7건 모두 맞았는데 sandbox_mode를 read-only로 적은 2건은 모두 어긋났고, 우회법은 없습니다.
  • mattiika69는 직접 준 승인이 반복해서 신뢰되지 않은 것으로 처리되고 /approve에는 누를 항목이 없었다고 보고했습니다(2026-09-15, #45604). 버전과 운영체제는 적혀 있지 않습니다.

마치며

샌드박스를 직접 두드려 보고 남은 건, 이 장치가 쓰기를 막는 장치이지 읽기를 막는 장치가 아니라는 점입니다. 그리고 쓰기 경계도 “작업 폴더만”이 아니었어요.

/tmp는 열려 있고, 작업 폴더 안의 .git/·.aws/는 닫혀 있었습니다. Linux와 Windows에서 경계는 같았지만, Windows에서는 거부되고도 종료 코드 0으로 끝나는 경우가 있었고요.

그러니 모드를 정하기 전에 작업 폴더에서 codex sandbox -- <쓰기 명령>을 한 번 실행해 경계를 직접 확인해 보시길 권합니다.

모드를 config.toml에 적어 두고 쓸 계획이라면, 어느 설정이 이기는지 정리한 Codex CLI config.toml 우선순위와 값이 무시될 때를 이어서 읽으면 됩니다. 다른 도구와의 비교는 Claude Code·Codex·Gemini CLI 샌드박스 비교에 있어요.

참고한 공식 자료

인용한 공개 사례

변경 이력

  • 2026-10-14 — Windows 11에서 Codex CLI 0.162.1로 쓰기·네트워크 경계를 다시 확인했고 결과는 같았습니다. Windows에서 codex exec 헤더가 보여 주는 sandbox 줄을 더했습니다.
  • 2026-10-07 — 인용했던 공개 이슈(#45618, apply_patch가 기존 파일을 고치지 못한다는 리눅스 보고)가 GitHub에서 삭제돼 더는 확인할 수 없어, 다른 사람들이 겪은 문제에서 그 사례를 뺐습니다.
  • 2026-10-05 — Windows 11에서 Codex CLI 0.159.3으로 같은 경계를 다시 확인한 절을 더했습니다. 쓰기·읽기·네트워크 경계는 리눅스와 같았고, 오류 메시지의 모습과 PowerShell에서 종료 코드가 0으로 끝나는 경우, elevated 샌드박스가 만드는 CodexSandboxUsers 그룹을 적었습니다.
  • 2026-10-02 — Codex CLI 0.159.0부터 workspace-write의 작업 폴더와 추가 쓰기 뿌리 안의 `.aws/`가 기본으로 쓰기 거부돼, 0.159.0에서 다시 실행한 결과와 릴리스 노트를 '0.159.0부터 달라진 점'으로 덧붙이고 쓰기 경계 설명과 오류 항목을 고쳤습니다.