---
title: "Codex CLI는 에이전트를 어떻게 샌드박싱하는가 — OS 네이티브 격리 심층 분석"
published: 2026-01-12T23:02:27.000Z
canonical: https://jeff.news/article/710
---
# Codex CLI는 에이전트를 어떻게 샌드박싱하는가 — OS 네이티브 격리 심층 분석

Codex CLI가 Docker 없이 OS 네이티브 샌드박싱(macOS Seatbelt, Linux Landlock+seccomp)으로 코딩 에이전트의 bash 실행을 격리하는 방법을 상세히 분석함. 3가지 권한 모드, 실행 파이프라인, 플랫폼별 구현, 자식 프로세스 관리, 세션 기반 신뢰 목록까지 다룸.

## 코딩 에이전트의 보안 딜레마

- 코딩 에이전트는 bash 접근 권한이 있어야 강력해지는데, 이게 동시에 가장 위험한 부분임 — 임의의 bash 세션이 프로덕션 자격증명 접근이나 홈 디렉토리 삭제까지 가능하게 만듦
- 가장 안전한 방법은 가상화(컨테이너 부팅 후 제한된 범위에서 실행)인데, 실제로 이렇게 하는 사람은 거의 없음. `--dangerously-skip-permissions` 플래그 이름이 잘 지어졌지만 대부분 그냥 무시하고 실행함
- Claude Code나 Cursor에서 쓰는 커맨드 화이트리스트 방식은 brittle함 — 새 디렉토리에서 명령 실행하면 `cd`조차 승인 필요하고, 자리를 비우면 사실상 사용 불가능함

## Codex의 3가지 권한 모드

- **Read Only**: 파일 읽기와 질문 답변만 가능. 편집, 명령 실행, 네트워크 접근 모두 승인 필요
- **Auto (기본값)**: 워크스페이스 내 파일 읽기, 편집, 명령 실행 가능. 워크스페이스 외부 접근이나 네트워크는 승인 필요
- **Full Access**: 네트워크 포함 모든 권한을 승인 없이 사용 가능

> [!NOTE]
> Auto 모드가 핵심임. Docker를 쓰지 않고 OS 네이티브 샌드박싱 API로 제한을 구현해서, 오버헤드 없이 꽤 강력한 격리를 달성함.

## 실행 파이프라인 구조

```mermaid
sequenceDiagram
    participant Agent as 코딩 에이전트
    participant Main as main() / arg0_dispatch_or_else
    participant Router as process_exec_tool_call
    participant Safety as assess_command_safety
    participant SB as SandboxType 라우터
    participant Mac as macOS Seatbelt
    participant Linux as Linux Landlock+seccomp
    participant None as Raw Execution

    Agent->>Main: 도구 호출 요청
    Main->>Main: 바이너리 이름 확인 (codex-linux-sandbox?)
    Main->>Router: CLI 메인 로직으로 전달
    Router->>Safety: 명령어 안전성 평가
    Safety-->>Router: Safe / NeedsApproval / Unsandboxed
    Router->>SB: SandboxType에 따라 분기
    alt macOS
        SB->>Mac: spawn_command_under_seatbelt()
        Mac->>Mac: /usr/bin/sandbox-exec 실행
    else Linux
        SB->>Linux: codex-linux-sandbox 바이너리 spawn
        Linux->>Linux: Landlock(파일시스템) + seccomp(네트워크) 적용
    else None
        SB->>None: 샌드박스 없이 직접 실행
    end
```

## macOS 구현: Apple Seatbelt

- `/usr/bin/sandbox-exec`를 하드코딩해서 사용함. Apple이 Seatbelt를 deprecated로 표시했지만 Apple 자체 시스템 소프트웨어와 웹 브라우저 등에서 여전히 광범위하게 사용 중이라 당분간 사라지지 않음
- 정책 설정에서 쓰기 가능한 루트 디렉토리를 열거하되, `.git` 디렉토리는 읽기 전용으로 별도 처리함 — 에이전트가 워크스페이스는 수정할 수 있지만 git 히스토리는 건드릴 수 없게 한 설계가 영리함
- 네트워크 접근은 전부 허용 아니면 전부 차단의 이분법적 구조임. Seatbelt가 기본적으로 deny이므로 네트워크 권한을 아예 안 넣으면 자동 차단됨

> [!WARNING]
> Seatbelt의 한계: 커스텀 정책 작성 시 홈 디렉토리의 dotfile이나 `~/Library` 접근 차단을 놓치기 쉬움. 또한 특정 도메인/프로토콜 단위의 세밀한 네트워크 제어가 불가능함.

## Linux 구현: Landlock + seccomp-BPF

- `codex-linux-sandbox`라는 별도 바이너리를 서브프로세스로 spawn하여, 직렬화된 정책과 대상 명령을 파싱한 뒤 제한을 적용하고 `execvp`로 실제 명령을 실행함
- **Landlock** (Linux 5.13+): 파일시스템 전체에 읽기 접근을 허용하되, 쓰기는 화이트리스트된 루트(+ `/dev/null`)로만 제한함. `execvp` 전에 규칙을 적용해서 대상 명령이 시작되는 시점에는 이미 샌드박싱된 상태임
- **seccomp-BPF**: `connect`, `bind`, `listen`, `sendto`, `sendmsg` 등 네트워크 관련 시스템콜을 선택적으로 차단함 (AF_UNIX는 로컬 IPC용으로 허용). macOS Seatbelt보다 더 세밀한 제어가 가능함

## 자식 프로세스 관리와 보안

- `spawn_child_async`에서 `env_clear()`로 환경변수를 완전히 초기화한 뒤 필요한 것만 다시 설정함 — 민감한 환경변수 유출을 방지하는 조치임
- 네트워크 비활성화 시 `CODEX_SANDBOX_NETWORK_DISABLED=1` 환경변수를 설정해서 하위 도구들이 상태를 인식할 수 있게 함
- Linux에서는 `prctl(PR_SET_PDEATHSIG)`로 부모 프로세스가 죽으면 자식 프로세스도 함께 종료되도록 보장함 — 샌드박싱된 고아 프로세스가 남아도는 것을 방지함

## 커맨드 화이트리스팅과 신뢰 관리

- 모든 명령 실행 전 `assess_command_safety`를 통과해야 함 — 자동 실행 가능, 사용자 승인 필요, 샌드박스 없이 실행 필요의 3가지로 분류됨
- 신뢰 목록은 세션 범위(session-scoped)로 관리됨. 한번 승인한 명령은 해당 세션 동안 계속 신뢰됨
- 샌드박스된 명령이 권한 문제로 실패하면 샌드박스 없이 재실행할지 물어봄. 승인하면 `SandboxType::None`으로 재실행하는 합리적인 탈출구가 있음

## 디버깅 도구

- `codex debug seatbelt`와 `codex debug landlock` 명령으로 샌드박스를 통해 임의의 명령을 테스트할 수 있음
- 메인 CLI의 `--full-auto` 플래그와 동일한 옵션을 지원함
- 샌드박싱이 실제로 어떻게 동작하는지 이해하는 데 유용한 도구임

## 핵심 포인트

- Codex는 Read Only, Auto, Full Access 3가지 모드 지원 — Auto가 기본값으로 OS 네이티브 샌드박싱 적용
- macOS는 Apple Seatbelt로 .git을 읽기 전용으로 보호하고 네트워크를 all-or-nothing으로 제어
- Linux는 Landlock(파일시스템)과 seccomp-BPF(네트워크 시스템콜)를 조합하여 더 세밀한 격리 구현
- env_clear()로 환경변수 유출 방지, PR_SET_PDEATHSIG로 고아 프로세스 방지 등 보안 세부사항이 견고함
- 세션 범위 신뢰 목록과 샌드박스 실패 시 재실행 탈출구로 사용성과 보안의 균형을 맞춤

## 인사이트

컨테이너 없이 OS 네이티브 기능만으로 실용적인 에이전트 샌드박싱을 구현할 수 있다는 점이 핵심. 기본값을 샌드박스로 설정하고 필요시 선택적으로 권한을 올리는 opt-out 설계가, 보안과 개발자 경험 사이의 균형점을 잘 잡은 사례임.
