Codex는 coding agent입니다. 작업을 시키면 파일을 읽고 고치며 PowerShell 같은 shell에서 명령도 실행합니다. 실제 작업에 필요한 기능입니다. 문제는 Codex가 실행하는 모든 명령에 현재 Windows에 로그인한 사용자의 권한을 그대로 줘도 되느냐는 것입니다.
로그인한 사용자가 열 수 있는 파일과 접근할 수 있는 system resource를 Codex의 명령도 똑같이 다룰 수 있다면, 명령 하나를 잘못 실행했을 때 영향이 필요 이상으로 커집니다. Windows sandbox는 이 범위를 줄이는 장치입니다. 각 명령이 안전한지 위험한지를 판단하는 대신, 승인받지 않은 명령이 넘어갈 수 없는 경계를 OS 수준에서 만듭니다.
경계를 넘을 때는 Approval, 기본 상한선은 sandbox
Approval과 sandbox는 역할이 다릅니다.
Approval은 정해진 경계를 넘어야 할 때 사용자에게 허락을 구하는 절차입니다. 예를 들어 현재 workspace 밖에 파일을 써야 한다면 Codex는 바로 실행하지 않고 사용자에게 승인을 요청할 수 있습니다. 반면 sandbox는 승인 없이 실행하는 명령이 어디까지 접근할 수 있는지 제한합니다. 사용자가 승인 요청에 답하기 전부터 적용되는 기본 상한선입니다.
Codex의 Windows 공식 문서는 agent mode에서 작업 폴더 밖의 filesystem 쓰기와 명시적으로 승인되지 않은 network 접근을 막는다고 설명합니다. 이 격리는 WSL이나 VM 없이 Windows에서 직접 작동합니다.
여기서 말하는 Windows sandbox는 Microsoft가 별도로 제공하는 Windows Sandbox 제품처럼 작은 Windows를 하나 더 실행하는 기능이 아닙니다. Windows에 이미 있는 사용자 프로필, token, ACL, firewall, desktop, Job Object를 조합해 경계를 만듭니다.
추상적인 허용 범위를 실제 Windows 경계로 바꾼다
Codex에서 권한 범위의 출발점은 PermissionProfile입니다. 여기에는 :workspace처럼 사람이 이해하기 쉬운 작업 범위가 담깁니다. 하지만 Windows는 :workspace라는 표현만 보고 파일 접근을 막아 주지 않습니다. 실제 경로와 접근 조건이 필요합니다.
Codex CLI 0.146.0의 sandbox manager는 이 상위 정책을 Windows sandbox manager에 넘깁니다. Windows 구현은 이 정책을 현재 workspace root, 추가로 쓰기를 허용할 root, 읽기를 허용할 root, network 허용 여부 같은 구체적인 조건으로 바꿉니다. 이 과정은 resolved permissions와 unified execution 코드에서 확인할 수 있습니다.
앞에서 정리한 경로와 접근 조건을 바탕으로, Windows sandbox manager는 명령을 어떤 방식 으로 격리할지 결정합니다. 그에 맞는 backend를 선택해 sandbox session을 준비하고, 실제 명령은 그다음에 실행합니다.
먼저 프로필과 출입 명단을 준비한다
Elevated 방식에서는 현재 Windows에 로그인한 사용자 계정으로 명령을 실행하지 않습니다. 대신 CodexSandboxOffline과 CodexSandboxOnline이라는 별도 사용자 계정을 만듭니다.
Codex의 명령은 network 조건에 따라 둘 중 하나의 계정에서 제한된 권한으로 실행됩니다.
Workspace마다 capability SID도 만듭니다. SID는 Windows가 사용자나 group 같은 security principal을 구별하는 식별자입니다. Codex는 이 capability SID와 sandbox group을 허용 경로의 ACL에 넣습니다.
Token을 프로세스가 내미는 신분증이라고 보면, ACL은 파일이나 폴더 앞에 놓인 출입 명단에 가깝습니다. 신분증에 어떤 신분과 제한이 적혀 있는지, 출입 명단이 그 신분에 어떤 접근을 허용하는지를 Windows가 함께 검사합니다.
Network 경계도 설정 단계에서 준비합니다. Codex CLI 0.146.0 source에는 offline 사용자의 outbound traffic을 막는 firewall 규칙을 만들고, 사용자 범위에 적용할 WFP(Windows Filtering Platform) filter를 추가하는 코드가 있습니다. 관련 구성은 setup, sandbox users, capability SID, firewall, WFP 코드에서 확인할 수 있습니다.
다만 이번에는 현재 host에 등록된 firewall 규칙의 상태나 network 차단 효과를 직접 측정하지 못했습니다. Source code에 이런 구성이 있다는 사실과 실제 환경에서 나타나는 차단 효과는 구분해서 봐야 합니다.
한 명령은 restricted token을 받아 실행된다
설정이 끝나면 명령 하나가 실행되는 경로를 따라갈 수 있습니다. 여기서는 Codex CLI 0.146.0의 elevated shared backend와 command runner를 기준으로 설명합니다.
Elevated backend는 network 조건에 맞는 전용 sandbox 사용자를 고른 뒤, 그 사용자로 command runner를 시작합니다. Command runner는 사용자 token을 실제 명령에 그대로 넘기지 않습니다. 사용자 SID와 workspace의 capability SID를 restricting SID로 추가하고, DISABLE_MAX_PRIVILEGE, LUA_TOKEN, WRITE_RESTRICTED 조건을 적용해 restricted token을 만듭니다.
Command runner는 이 restricted token으로 Windows API인 CreateProcessAsUserW를 호출해 실제 명령을 실행합니다. 입출력은 상황에 따라 ConPTY 또는 pipe에 연결됩니다. 이 흐름은 elevated backend, command runner, token, process 코드에서 각각 확인할 수 있습니다.
Restricted token과 ACL이 한 쌍으로 작동한다는 점이 중요합니다. Windows의 restricted token 문서에 따르면, Windows는 일반 access check를 통과한 뒤 restricting SID를 대상으로 두 번째 검사를 수행합니다. 두 검사를 모두 통과해야 접근이 허용됩니다. WRITE_RESTRICTED에서는 이 두 번째 검사가 쓰기처럼 대상을 변경하는 접근에 적용됩니다.
DACL은 어떤 security principal에 접근을 허용하거나 거부할지 정합니다. Restricted token의 restricting SID와 일치하는 허용 항목이 폴더 ACL에 없으면 쓸 수 없습니다. 반대로 ACL에 허용 항목을 하나 추가했다고 모든 프로세스가 접근할 수 있는 것도 아닙니다. 명령의 token과 대상 ACL이 모두 조건을 충족해야 합니다.
Private desktop과 Job Object는 filesystem 밖의 경계도 보완한다
Filesystem 경계만으로 명령이 닿을 수 있는 모든 대상을 통제할 수 있는 것은 아닙니다. Windows에는 window와 message 같은 user interface object가 있고, 실행한 명령이 다시 child process를 만들 수도 있습니다.
Codex CLI 0.146.0은 명령을 실행할 때 무작위 이름의 private desktop을 만들고, 새 process의 startup 정보에 그 desktop을 지정합니다. Windows에서 desktop은 window, menu, hook 같은 user interface object를 담는 논리적인 화면 공간입니다. Private desktop은 sandbox process가 기존 desktop의 window와 message에 접근할 수 있는 범위를 줄입니다. 공식 문서에 따르면 elevated와 unelevated 방식 모두 기본적으로 private desktop을 사용합니다.
Job Object는 여러 process를 하나의 단위로 묶어 관리하는 Windows 장치입니다. Codex는 실행한 process를 Job Object에 넣어 그 명령이 만든 process tree의 수명과 종료를 함께 관리합니다.
둘의 역할은 다릅니다. Private desktop은 window object를 격리하고, Job Object는 process tree를 관리합니다. 파일이나 폴더에 쓸 수 있는지는 이들이 아니라 restricted token과 ACL의 결합으로 결정됩니다.
Parent와 child에도 같은 경계가 이어졌다
2026년 7월 31일 KST에 Windows native codex sandbox를 직접 실행해 이 구조를 확인했습니다. Codex CLI 0.146.0, elevated 설정, PowerShell, :workspace 조건이었고 sandbox 내부에서는 추가 승인을 받지 않았습니다.
Parent PowerShell과 여기서 만든 child PowerShell은 모두 CodexSandboxOffline 사용자로 실행됐습니다. 둘 다 restricted token을 가지고 Job Object 안에서 실행됐습니다. Desktop 이름도 CodexSandboxDesktop-ab69833b728db109b54f73a638a4e0f로 같았습니다. Source code에서 확인한 신분·token·desktop 경계가 실제 실행 결과에서도 나타났습니다.
두 process 모두 허용된 workspace 안에는 파일을 만들 수 있었습니다. 그러나 workspace 밖에 마련한 sibling canary에 쓰려고 하면 access denied가 발생했습니다. Sandbox 밖에서 실행한 host process는 같은 canary에 파일을 쓸 수 있었습니다.
ACL도 이 결과와 맞았습니다. Workspace에는 CodexSandboxUsers와 해당 workspace의 capability SID에 modify 권한을 주는 항목이 있었습니다. Sibling canary에는 두 항목 모두 없었습니다. Parent와 child가 같은 sandbox 신분과 restricted token을 물려받았더라도, ACL이 맞는 workspace에만 쓸 수 있었던 이유입니다.
확인 범위에는 한계가 있습니다. Parent와 child가 각각 Job Object 안에 있다는 사실은 확인했지만, 두 process의 Job Object ID는 직접 비교하지 않았습니다. 따라서 둘이 같은 Job Object에 속했는지는 확인하지 못했습니다.
Sandbox가 막아 주지 않는 것
여기까지 읽으면 sandbox가 명령을 안전한 것과 위험한 것으로 판별해 줄 것처럼 보일 수 있습니다. 하지만 sandbox는 명령의 의도를 판단하지 않습니다. 허용된 workspace 안에서는 parent와 child 모두 실제로 파일을 만들었습니다. 같은 권한으로 기존 파일을 덮어쓰거나 지우는 명령도 실행할 수 있습니다.
Windows sandbox가 하는 일은 위험을 없애는 것이 아닙니다. 승인이 없는 명령이 영향을 줄 수 있는 범위를 줄이는 일입니다.
따라서 sandbox가 있어도 workspace 안의 변경까지 안전하다고 생각해서는 안 됩니다. Windows sandbox는 잘못된 명령이 로그인한 사용자의 전체 권한을 그대로 행사하지 못하게 하는 기본 경계입니다. 이 경계를 Windows에 적용하는 elevated와 unelevated 방식의 차이와 선택 기준은 연결 글에서 이어서 살펴볼 수 있습니다.