
sandbox-runtime v0.0.74
컨테이너 없이 OS 수준에서 임의의 프로세스에 대한 파일시스템 및 네트워크 제한을 적용하는 경량 샌드박싱 도구입니다.
Anthropic Sandbox Runtime (srt)
컨테이너 없이 OS 수준에서 임의의 프로세스에 파일시스템 및 네트워크 제한을 적용하기 위한 경량 샌드박싱 도구입니다.
srt는 네이티브 OS 샌드박싱 프리미티브(macOS에서는 sandbox-exec, Linux에서는 bubblewrap)와 프록시 기반 네트워크 필터링을 사용합니다. 에이전트, 로컬 MCP 서버, bash 명령 및 임의의 프로세스의 동작을 샌드박싱하는 데 사용할 수 있습니다.
베타 리서치 프리뷰
Sandbox Runtime은 더 안전한 AI 에이전트를 구현하기 위해 Claude Code용으로 개발된 리서치 프리뷰입니다. 더 넓은 생태계가 보다 안전한 에이전트 시스템을 구축할 수 있도록 초기 오픈 소스 프리뷰로 공개되었습니다. 초기 리서치 프리뷰인 만큼 API와 구성 형식은 변경될 수 있습니다. AI 에이전트를 기본적으로 더 안전하게 만들기 위한 피드백과 기여를 환영합니다!
설치
npm install -g @anthropic-ai/sandbox-runtime
기본 사용법
# Network restrictions
$ srt "curl anthropic.com"
Running: curl anthropic.com
<html>...</html> # Request succeeds
$ srt "curl example.com"
Running: curl example.com
Connection blocked by network allowlist # Request blocked
# Filesystem restrictions
$ srt "cat README.md"
Running: cat README.md
# Anthropic Sandb... # Current directory access allowed
$ srt "cat ~/.ssh/id_rsa"
Running: cat ~/.ssh/id_rsa
cat: /Users/ollie/.ssh/id_rsa: Operation not permitted # Specific file blocked
개요
이 패키지는 CLI 도구와 라이브러리로 모두 사용할 수 있는 독립형 샌드박스 구현을 제공합니다. 일반적인 개발자 사용 사례에 맞춘 기본적으로 안전(secure-by-default) 철학을 바탕으로 설계되었습니다. 프로세스는 최소한의 접근 권한으로 시작하며, 필요한 부분만 명시적으로 열어줍니다.
주요 기능:
- 네트워크 제한: HTTP/HTTPS 및 기타 프로토콜을 통해 접근할 수 있는 호스트/도메인 제어
- 파일시스템 제한: 읽기/쓰기가 가능한 파일/디렉터리 제어
- Unix 소켓 제한: 로컬 IPC 소켓에 대한 접근 제어
- 위반 모니터링: macOS에서 시스템의 샌드박스 위반 로그 저장소에 접근하여 실시간 알림 제공
사용 사례 예시: MCP 서버 샌드박싱
주요 사용 사례 중 하나는 Model Context Protocol(MCP) 서버를 샌드박싱하여 해당 기능을 제한하는 것입니다. 예를 들어, 파일시스템 MCP 서버를 샌드박싱하려면:
샌드박싱 없이 (.mcp.json):
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem"]
}
}
}
샌드박싱 사용 시 (.mcp.json):
{
"mcpServers": {
"filesystem": {
"command": "srt",
"args": ["npx", "-y", "@modelcontextprotocol/server-filesystem"]
}
}
}
그런 다음 ~/.srt-settings.json에서 제한 사항을 구성하십시오:
{
"filesystem": {
"denyRead": [],
"allowWrite": ["."],
"denyWrite": ["~/sensitive-folder"]
},
"network": {
"allowedDomains": [],
"deniedDomains": []
}
}
이제 MCP 서버는 거부된 경로에 쓰기가 차단됩니다:
> Write a file to ~/sensitive-folder
✗ Error: EPERM: operation not permitted, open '/Users/ollie/sensitive-folder/test.txt'
작동 방식
샌드박스는 OS 수준의 기본 요소를 사용하여 전체 프로세스 트리에 적용되는 제한을 시행합니다:
- macOS: 동적으로 생성된 Seatbelt 프로필과 함께
sandbox-exec를 사용합니다 - Linux: 네트워크 네임스페이스 격리를 통한 컨테이너화를 위해 bubblewrap을 사용합니다
- Windows: 전용
srt-sandbox로컬 사용자 계정으로 샌드박스된 프로세스를 실행하며, 해당 계정의 SID를 키로 하는 Windows Filtering Platform 이그레스 펜스와 작업 트리에 대한 세션별 명시적 ACE를 사용합니다
0d1c612947c798aef48e6ab4beb7e8544da9d41a-4096x2305
이중 격리 모델
효과적인 샌드박싱을 위해서는 파일 시스템과 네트워크 격리가 모두 필요합니다. 파일 격리가 없으면 침해된 프로세스가 SSH 키나 기타 민감한 파일을 유출할 수 있습니다. 네트워크 격리가 없으면 프로세스가 샌드박스를 탈출하여 무제한 네트워크 접근 권한을 얻을 수 있습니다.
파일 시스템 격리는 읽기 및 쓰기 제한을 시행합니다:
- 읽기 (거부 후 허용 패턴): 기본적으로 읽기 접근은 모든 곳에서 허용됩니다. 넓은 영역(예:
/Users)을 거부한 다음 그 안의 특정 경로(예:.)를 다시 허용할 수 있습니다.allowRead는denyRead보다 우선합니다 — 쓰기와는 반대로, 쓰기에서는denyWrite가allowWrite보다 우선합니다.allowRead영역 내부에 있으면서 그보다 더 구체적인denyRead항목(예:allowRead: ["."]와 함께denyRead: ["**/.env"]또는["./secrets"])은 여전히 거부된 상태로 유지됩니다. - 쓰기 (허용 전용 패턴): 기본적으로 쓰기 접근은 모든 곳에서 거부됩니다. 경로(예:
.,/tmp)를 명시적으로 허용해야 합니다. 빈 허용 목록은 쓰기 접근이 없음을 의미합니다.
네트워크 격리 (허용 전용 패턴): 기본적으로 모든 네트워크 접근이 거부됩니다. 도메인을 명시적으로 허용해야 합니다. 빈 allowedDomains 목록은 네트워크 접근이 없음을 의미합니다. 네트워크 트래픽은 호스트에서 실행되는 프록시 서버를 통해 라우팅됩니다:
-
Linux: 요청은 Unix 도메인 소켓을 통해 파일 시스템을 경유하여 라우팅됩니다. 샌드박스된 프로세스의 네트워크 네임스페이스가 완전히 제거되므로, 모든 네트워크 트래픽은 호스트에서 실행되는 프록시(샌드박스에 바인드 마운트된 Unix 소켓에서 수신 대기)를 통해야 합니다
-
macOS: Seatbelt 프로필은 특정 localhost 포트로의 통신만 허용합니다. 프록시가 이 포트에서 수신 대기하여 모든 네트워크 접근을 위한 제어된 채널을 만듭니다
-
Windows: 머신 전체 WFP 필터 세트가 프록시 포트 범위로의 루프백을 제외하고
srt-sandbox계정에서 발생하는 모든 아웃바운드 연결을 차단합니다. 프록시가 해당 범위 내에서 수신 대기하여 모든 네트워크 접근을 위한 제어된 채널을 만듭니다
HTTP/HTTPS(HTTP 프록시 경유)와 기타 TCP 트래픽(SOCKS5 프록시 경유) 모두 이러한 프록시에 의해 중개되며, 이 프록시가 도메인 허용 목록과 거부 목록을 시행합니다.
Claude Code의 샌드박싱에 대한 자세한 내용은 다음을 참조하세요:
아키텍처
src/
├── index.ts # Library exports
├── cli.ts # CLI entrypoint (srt command)
├── utils/ # Shared utilities
│ ├── debug.ts # Debug logging
│ ├── settings.ts # Settings reader (permissions + sandbox config)
│ ├── platform.ts # Platform detection
│ └── exec.ts # Command execution utilities
└── sandbox/ # Sandbox implementation
├── sandbox-manager.ts # Main sandbox manager
├── sandbox-schemas.ts # Zod schemas for validation
├── sandbox-violation-store.ts # Violation tracking
├── sandbox-utils.ts # Shared sandbox utilities
├── http-proxy.ts # HTTP/HTTPS proxy for network filtering
├── socks-proxy.ts # SOCKS5 proxy for network filtering
├── linux-sandbox-utils.ts # Linux bubblewrap sandboxing
├── macos-sandbox-utils.ts # macOS sandbox-exec sandboxing
└── windows-sandbox-utils.ts # Windows srt-win sandboxing
사용법
CLI 도구로 사용하기
srt 명령어(Anthropic Sandbox Runtime)는 모든 명령어를 보안 경계로 감쌉니다:
# Run a command in the sandbox
srt echo "hello world"
# With debug logging
srt --debug curl https://example.com
# Specify custom settings file
srt --settings /path/to/srt-settings.json npm install
설정 파일은 선택 사항입니다 — ~/.srt-settings.json에 파일이 없으면 srt는 내장 기본값으로 실행됩니다: 네트워크 접근 없음, 기본 쓰기 경로 외부에 쓰기 없음, 읽기는 제한 없음. 설정 파일이 있지만 비어 있거나, 읽을 수 없거나, 유효성 검사를 통과하지 못하면 오류입니다: srt는 그 사실을 알리고 종료하며, 기본값으로 폴백하지 않습니다. 기본값은 더 약한 설정이 아니라 다른 설정이기 때문입니다 — 폴백하면 파일의 denyRead, allowRead 및 자격 증명 규칙을 비롯해 파일이 명시한 모든 것이 사라집니다. --settings로 지정한 파일도 마찬가지이며, 이 파일 역시 존재해야 합니다.
명령 실행 중 설정 업데이트: --control-fd
--control-fd <fd>는 호출자가 이미 열어 둔 디스크립터에서 설정 업데이트를 읽으며, 설정 파일과 같은 형태의 JSON 객체가 한 줄에 하나씩 들어 있습니다. 각 줄은 전체 설정을 교체하지만, 이미 실행 중인 것에서 바뀌는 것은 네트워크 목록(allowedDomains / deniedDomains)뿐입니다: 프록시가 요청마다 이들을 참조합니다. 파일 시스템 규칙은 래핑 시점에 샌드박스에 컴파일되므로, 이를 변경하는 줄은 현재 실행 중인 것에는 아무것도 적용되지 않습니다.
# fd 3 is the read end of a pipe the caller writes lines to
srt --control-fd 3 -- npm test
- 디스크립터는 3 이상의 정수여야 하며 읽기 가능해야 합니다 —
0-2는 표준 스트림입니다. srt는 주어진 디스크립터를 읽을 수 없으면 명령을 실행하는 대신 오류와 함께 종료하므로, 죽은 채널이 살아 있는 채널로 통과되는 일은 없습니다. 단 하나의 업데이트도 전달하기 전에 죽은 채널은 명령을 함께 종료시키고, 전달한 후에 죽은 채널은 그 사실을 알리고 마지막으로 적용된 설정 아래에서 명령을 계속 실행합니다. - 유효한 설정이 아닌 줄은 stderr에 보고되고 무시되며, 이전 설정이 계속 적용됩니다.
- srt는 래핑된 명령과 함께 종료되며, 작성자가 디스크립터를 닫을 때까지 기다리지 않습니다. 입력의 끝도 오류가 아닙니다: 명령은 마지막으로 적용된 설정 아래에서 계속 실행됩니다.
- srt에 전용의 읽기 전용 끝을 제공하십시오. srt는 파이프나 소켓을
비차단 모드로 설정하며, 그 플래그는 열린 파일 설명에 존재하므로, 같은
설명을 보유한 다른 무엇이든 — 셸의
exec 3<fifo, 부모가 계속 사용하는 디스크립터의pass_fds— 그때부터 자체적인 차단 읽기에서EAGAIN을 받게 됩니다. - macOS와 Linux에서 샌드박스된 명령은 디스크립터를 받지 않습니다: srt는
명령에 대해 그 슬롯을
/dev/null로 지정하므로, 샌드박스 내부의 어떤 것도 업데이트를 읽거나 자체적인 설정을 작성할 수 없습니다.
라이브러리로서
import {
SandboxManager,
type SandboxRuntimeConfig,
} from '@anthropic-ai/sandbox-runtime'
import { spawn } from 'child_process'
// Define your sandbox configuration
const config: SandboxRuntimeConfig = {
network: {
allowedDomains: ['example.com', 'api.github.com'],
deniedDomains: [],
},
filesystem: {
denyRead: ['~/.ssh'],
allowWrite: ['.', '/tmp'],
denyWrite: ['.env'],
},
}
// Initialize the sandbox (starts proxy servers, etc.)
await SandboxManager.initialize(config)