Show HN: Zerobox – 파일, 네트워크, 자격 증명 제어를 통한 명령어 샌드박싱 (Sandbox)
요약
Zerobox는 OpenAI Codex의 샌드박스 런타임을 기반으로 하는 가볍고 크로스 플랫폼을 지원하는 프로세스 샌드박싱 도구입니다. 파일 액세스, 네트워크 트래픽, 환경 변수 및 자격 증명을 정밀하게 제어하며, Docker나 VM 없이도 매우 낮은 오버헤드로 안전한 명령어 실행 환경을 제공합니다.
핵심 포인트
- 기본 차단(Deny by default) 원칙을 적용하여 쓰기, 네트워크, 환경 변수를 엄격히 제한함
- 자격 증명 주입 기능을 통해 프로세스가 실제 API 키를 볼 수 없도록 플레이스홀더 방식으로 보안 강화
- 파일 시스템 변경 사항을 기록하고 실행 후 자동으로 되돌리거나(restore) 스냅샷을 통해 검토 가능
- Rust, TypeScript, Python SDK를 지원하며 macOS 및 Linux 환경에서 약 10ms의 낮은 오버헤드로 동작
- 도메인별 네트워크 필터링 및 특정 경로에 대한 파일 읽기/쓰기 제어 기능 제공
OpenAI Codex의 샌드박스 런타임 (sandbox runtime)을 기반으로 하는 가볍고 크로스 플랫폼(cross-platform)을 지원하는 프로세스 샌드박싱 (process sandboxing) 도구입니다.
기본 차단 (Deny by default): 쓰기, 네트워크 및 환경 변수 (environment variables)는 허용되지 않는 한 모두 차단됩니다.
자격 증명 주입 (Credential injection): 프로세스가 절대 볼 수 없는 API 키를 전달합니다. Zerobox는 승인된 호스트 (hosts)에 대해서만 실제 값을 주입합니다.
파일 액세스 제어 (File access control): 특정 경로에 대한 읽기 및 쓰기를 허용하거나 차단합니다.
네트워크 필터링 (Network filtering): 도메인 (domain)별로 아웃바운드 트래픽 (outbound traffic)을 허용하거나 차단합니다.
깨끗한 환경 (Clean environment): 기본적으로 필수적인 환경 변수 (env vars) (PATH, HOME 등)만 상속됩니다.
Rust, TypeScript, Python용 SDK 지원 모든 언어에서 일관된 API를 제공합니다.
크로스 플랫폼 (Cross-platform): macOS 및 Linux 지원. Windows 지원 예정
단일 바이너리 (Single binary): Docker나 VM (가상 머신) 없이 약 10ms의 오버헤드만 발생합니다.
| 채널 (Channel) | 명령 (Command) |
|---|---|
| Shell (macOS / Linux) | `curl -fsSL https://raw.githubusercontent.com/afshinm/zerobox/main/install.sh |
| ... |
쓰기 및 네트워크 액세스 없이 명령어를 실행합니다:
zerobox -- node -e "console.log('hello')"
특정 디렉토리에 대한 쓰기를 허용합니다:
zerobox --allow-write=. -- node script.js
특정 도메인에 대한 네트워크를 허용합니다:
zerobox --allow-net=api.openai.com -- node agent.js
특정 호스트에 비밀 값 (secret)을 전달하며, 내부 프로세스는 실제 값을 절대 볼 수 없습니다:
zerobox --secret OPENAI_API_KEY=sk-proj-123 --secret-host OPENAI_API_KEY=api.openai.com -- node agent.js
파일 시스템 변경 사항을 기록하고 실행 후 이를 되돌립니다:
zerobox --restore --allow-write=. -- npm install
또는 복구 없이 기록한 후, 나중에 검사하고 되돌립니다:
zerobox --snapshot --allow-write=. -- npm install
zerobox snapshot list
zerobox snapshot diff <session-id>
...
프로그래밍 방식의 사용을 원하시면 사용 중인 스택에 맞는 SDK로 이동하세요:
비밀 값 (Secrets)은 샌드박스 내부에서 절대 노출되어서는 안 되는 API 키, 토큰 또는 자격 증명 (credentials)을 의미합니다. 샌드박스 처리된 프로세스는 환경 변수에서 플레이스홀더 (placeholder)를 보게 되며, 실제 값은 요청된 호스트에 대해서만 네트워크 프록시 (network proxy) 수준에서 교체됩니다.
sandbox process: echo $OPENAI_API_KEY
-> ZEROBOX_SECRET_a1b2c3d4e5... (placeholder)
sandbox process: curl -H "Authorization: Bearer $OPENAI_API_KEY" https://api.openai.com/...
...
--secret을 사용하여 비밀 값 (secret)을 전달하고
--secret-host를 사용하여 특정 도메인으로 제한합니다:
zerobox --secret OPENAI_API_KEY=sk-proj-123 --secret-host OPENAI_API_KEY=api.openai.com -- node app.js
--secret-host가 없으면, 비밀 값은 모든 도메인에 전달됩니다:
zerobox --secret TOKEN=abc123 -- node app.js
서로 다른 호스트를 가진 여러 개의 비밀 값:
zerobox \
--secret OPENAI_API_KEY=sk-proj-123 --secret-host OPENAI_API_KEY=api.openai.com \
--secret GITHUB_TOKEN=ghp-456 --secret-host GITHUB_TOKEN=api.github.com \
...
Node.js의 fetch는 기본적으로 HTTPS_PROXY를 준수하지 않습니다. 비밀 값이 포함된 샌드박스 (sandbox) 내부에서 Node.js를 실행할 때는 반드시 --use-env-proxy 인자 (argument)를 전달해야 합니다.
SDK 코드 예제는 Rust, TypeScript 또는 Python README를 참조하세요.
기본적으로 PATH, HOME, USER, SHELL, TERM, LANG과 같은 필수 변수들만 샌드박스로 전달됩니다.
모든 부모 환경 변수 (env vars)를 상속합니다:
zerobox --allow-env -- node app.js
특정 환경 변수만 상속합니다:
zerobox --allow-env=PATH,HOME,DATABASE_URL -- node app.js
특정 환경 변수를 차단합니다:
zerobox --allow-env --deny-env=AWS_SECRET_ACCESS_KEY -- node app.js
또는 명시적인 변수를 설정합니다:
zerobox --env NODE_ENV=production --env DEBUG=false -- node app.js
파일 손상이나 데이터 유출 위험 없이 AI가 생성한 코드를 실행합니다:
zerobox -- python3 /tmp/task.py
또는 출력 디렉토리 (output directory)에 대해서만 쓰기를 허용합니다:
zerobox --allow-write=/tmp/output -- python3 /tmp/task.py
각 AI 도구 호출은 개별적으로 샌드박싱될 수 있습니다. 부모 에이전트 (agent) 프로세스는 정상적으로 실행되며 일부 작업만 샌드박싱됩니다. 전체 작동 예제:
examples/ai-agent-sandboxed는 에이전트 프로세스 전체를 비밀 값과 함께 래핑 (wrap)하여 API 키가 노출되지 않도록 합니다. examples/ai-agent
도구별 샌드박싱 (sandboxing) 및 비밀 값 (secrets) 처리가 포함된 Vercel AI SDK를 사용합니다. examples/workflow
샌드박싱된 지속 가능한 단계 (durable steps)로 Vercel Workflow를 실행합니다.
네트워크 액세스 권한을 가지되 쓰기 작업은 ./dist로 제한된 빌드를 실행합니다.
:
zerobox --allow-write=./dist --allow-net -- npm run build
네트워크 없이 테스트를 실행하여 의도치 않은 외부 호출을 포착합니다:
zerobox --allow-write=/tmp -- npm test
샌드박싱 오버헤드 (overhead)는 최소한이며, 일반적으로 약 10ms 및 약 7MB입니다:
| 명령어 | 기본 (Bare) | 샌드박싱 (Sandboxed) | 오버헤드 | 기본 메모리 | 샌드박스 메모리 |
|---|---|---|---|---|---|
echo hello | <1ms | 10ms | +10ms | 1.2 MB | 8.4 MB |
node -e '...' | 10ms | 20ms | +10ms | 39.3 MB | 39.1 MB |
python3 -c '...' | 10ms | 20ms | +10ms | 12.9 MB | 13.0 MB |
cat 10MB file | <1ms | 10ms | +10ms | 1.9 MB | 8.4 MB |
curl https://... | 50ms | 60ms | +10ms | 7.2 MB | 8.4 MB |
Apple M5 Pro에서 웜업 (warmup)을 포함한 10회 실행 중 최댓값 기준. 재현하려면 ./bench/run.sh를 실행하세요.
| 플랫폼 | 백엔드 (Backend) | 상태 |
|---|---|---|
| macOS | Seatbelt (sandbox-exec ) | 완벽 지원 |
| Linux | Bubblewrap + Seccomp + Namespaces | 완벽 지원 |
| Windows | Restricted Tokens + ACLs + Firewall | 계획 중 |
| 플래그 (Flag) | 예시 (Example) | 설명 (Description) |
|---|---|---|
--allow-read <paths> | --allow-read=/tmp,/data | 읽기 가능한 사용자 데이터를 지정된 경로로 제한합니다. 시스템 라이브러리는 계속 접근 가능합니다. 기본값: 모든 읽기 허용. |
--deny-read <paths> | --deny-read=/secret | 해당 경로로부터의 읽기를 차단합니다. --allow-read보다 우선순위가 높습니다. |
--allow-write [paths] | --allow-write=. | 해당 경로에 대한 쓰기를 허용합니다. 값이 없으면 모든 곳에 대한 쓰기를 허용합니다. 기본값: 쓰기 불허. |
--deny-write <paths> | --deny-write=./.git | 해당 경로에 대한 쓰기를 차단합니다. --allow-write보다 우선순위가 높습니다. |
--allow-net [domains] | --allow-net=example.com | 외부 네트워크 접속을 허용합니다. 값이 없으면 모든 도메인을 허용합니다. 기본값: 네트워크 불허. |
--deny-net <domains> | --deny-net=evil.com | 해당 도메인으로의 네트워크 접속을 차단합니다. --allow-net보다 우선순위가 높습니다. |
--env <KEY=VALUE> | --env NODE_ENV=prod | 샌드박스 내에 환경 변수 (env var)를 설정합니다. 여러 번 반복 사용할 수 있습니다. |
--allow-env [keys] | --allow-env=PATH,HOME | 부모 프로세스의 환경 변수를 상속합니다. 값이 없으면 모두 상속합니다. 기본값: PATH, HOME, USER, SHELL, TERM, LANG만 상속. |
--deny-env <keys> | --deny-env=SECRET | 부모의 환경 변수 중 해당 항목을 제외합니다. --allow-env보다 우선순위가 높습니다. |
--secret <KEY=VALUE> | --secret API_KEY=sk-123 | 비밀 값 (secret)을 전달합니다. 프로세스는 플레이스홀더 (placeholder)를 보게 됩니다. 실제 값은 승인된 호스트를 위한 프록시 (proxy) 단계에서 주입됩니다. |
--secret-host <KEY=HOSTS> | --secret-host API_KEY=api.openai.com | 비밀 값을 특정 호스트로 제한합니다. 이 설정이 없으면 모든 호스트에 대해 비밀 값이 치환됩니다. |
-A , --allow-all | -A | 모든 파일 시스템 및 네트워크 권한을 부여합니다. 환경 변수와 비밀 값 설정은 여전히 적용됩니다. |
--no-sandbox | --no-sandbox | 샌드박스 (sandbox) 기능을 완전히 비활성화합니다. |
--strict-sandbox | --strict-sandbox | 완전한 샌드박스 (bubblewrap)를 요구합니다. 더 약한 격리 방식으로 폴백 (fallback)하는 대신 실패 처리합니다. |
--debug | --debug | 샌드박스 설정과 프록시 결정 사항을 표준 에러 (stderr)로 출력합니다. |
--snapshot | --snapshot | 실행 중 발생하는 파일 시스템 변경 사항을 기록합니다. |
| --restore | --restore | 기록된 파일을 종료 후 실행 전 상태로 복구합니다. --snapshot 옵션이 포함됩니다. |
| --snapshot-path <paths> | --snapshot-path=./src | 스냅샷(Snapshot)을 기록할 경로 (기본값: 현재 작업 디렉토리(cwd)) |
| --snapshot-exclude <patterns> | --snapshot-exclude=build | 스냅샷에서 제외할 패턴 |
| -C <dir> | -C /workspace | 샌드박스(Sandboxed) 명령의 작업 디렉토리 설정 |
| -V , --version | --version | 버전 출력 |
| -h , --help | --help | 도움말 출력 |
| 명령어 (Command) | 설명 (Description) |
|---|---|
zerobox snapshot list | 기록된 세션 목록을 나열합니다. |
zerobox snapshot diff <id> | 특정 세션의 변경 사항을 보여줍니다. |
zerobox snapshot restore <id> | 파일 시스템을 특정 세션의 기준 상태(Baseline)로 복구합니다. |
zerobox snapshot clean --older-than=<days> | 오래된 스냅샷 세션을 삭제합니다. |
| 언어 (Language) | 패키지 (Package) | README |
|---|---|---|
| Rust | zerobox on crates.io | crates/zerobox/README.md |
| TypeScript / Node | zerobox on npm | packages/zerobox/README.md |
| Python | zerobox on PyPI | sdks/python/README.md |
Apache-2.0
AI 자동 생성 콘텐츠
본 콘텐츠는 HN OpenAI Codex의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기