메타의 Confucius Code Agent에 이어서 Anthropic이 공개한 Sandbox Runtime에 대해서 리뷰해보고자 합니다. Sandbox Runtime 은 컨테이너 없이도 OS 레벨에서 프로세스의 파일시스템과 네트워크 접근을 제한할 수 있는 경량 샌드박싱 도구입니다. Claude Code를 위해 개발되었으며, AI 에이전트를 더 안전하게 만들기 위한 연구 프리뷰로 오픈소스로 공개되었습니다.
왜 필요한가?
AI 에이전트가 코드를 실행하거나 파일을 수정할 때, 우리는 다음과 같은 걱정을 하게 됩니다:
- 민감한 SSH 키나 설정 파일에 접근하면 어쩌지?
- 허가되지 않은 외부 서버로 데이터를 전송하면?
- 시스템 파일을 실수로 삭제하거나 수정하면?
Sandbox Runtime은 이러한 위험을 기본적으로 차단하고, 필요한 권한만 명시적으로 허용하는 철학으로 설계되었습니다.
설치 및 기본 사용법
설치
npm install -g @anthropic-ai/sandbox-runtime
간단한 예제
# 네트워크 제한 - anthropic.com은 허용
$ srt "curl anthropic.com"
Running: curl anthropic.com
<html>...</html> # 요청 성공
# example.com은 차단
$ srt "curl example.com"
Running: curl example.com
Connection blocked by network allowlist # 요청 차단!
# 파일시스템 제한 - 현재 디렉토리는 허용
$ srt "cat README.md"
Running: cat README.md
# Anthropic Sandb... # 읽기 성공
# SSH 키는 차단
$ srt "cat ~/.ssh/id_rsa"
Running: cat ~/.ssh/id_rsa
cat: /Users/user/.ssh/id_rsa: Operation not permitted # 차단됨!
핵심 특징
1. 네트워크 제한
특정 도메인과 호스트로만 HTTP/HTTPS 및 기타 프로토콜 접근 제어:
{
"network": {
"allowedDomains": [
"github.com",
"*.github.com",
"npmjs.org"
],
"deniedDomains": [
"malicious.com"
]
}
}
2. 파일시스템 제한
읽기/쓰기 권한을 세밀하게 제어 (기본값: 현재 작업 디렉토리만 쓰기 허용):
{
"filesystem": {
"denyRead": ["~/.ssh"],
"allowWrite": [".", "/tmp"],
"denyWrite": [".env", "secrets/"]
}
}
3. Unix 소켓 제한
로컬 IPC 소켓 접근 제어:
{
"network": {
"allowUnixSockets": ["/var/run/docker.sock"]
}
}
4. 실시간 위반 모니터링
macOS에서는 시스템 샌드박스 위반 로그를 실시간으로 추적:
# 샌드박스 위반 실시간 모니터링
log stream --predicate 'process == "sandbox-exec"' --style syslog
실전 예제: MCP 서버 샌드박싱
MCP (Model Context Protocol) 서버를 샌드박스에서 실행하는 것이 주요 사용 사례입니다.
샌드박스 없이 (.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": []
}
}
> Write a file to ~/sensitive-folder
✗ Error: EPERM: operation not permitted, open '/Users/user/sensitive-folder/test.txt'
작동 원리
이중 격리 모델
효과적인 샌드박싱을 위해서는 파일시스템과 네트워크 격리가 모두 필요합니다.
┌─────────────────────────────────────────────────────┐
│ Host Machine │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ HTTP Proxy │ │ SOCKS5 Proxy │ │
│ │ (필터링) │ │ (필터링) │ │
│ └──────┬───────┘ └───────┬──────┘ │
│ │ │ │
│ ┌──────┴─────────────────────────┴──────┐ │
│ │ Sandboxed Process │ │
│ │ - 네트워크 네임스페이스 제거 (Linux) │ │
│ │ - Localhost만 허용 (macOS) │ │
│ │ - 파일시스템 제한 │ │
│ └────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
플랫폼별 구현
macOS:
- sandbox-exec와 Seatbelt 프로파일 사용
- 동적으로 생성된 프로파일로 파일 경로 제어
Linux:
- bubblewrap를 사용한 컨테이너화
- 네트워크 네임스페이스 격리
- Unix 소켓을 통한 프록시 통신
네트워크 격리 아키텍처
- HTTP/HTTPS 트래픽: HTTP 프록시가 요청을 가로채고 허용/차단 도메인 검증
- 기타 네트워크 트래픽: SOCKS5 프록시가 SSH, 데이터베이스 연결 등 TCP 연결 처리
- 권한 강제: 프록시가 설정 규칙에 따라 권한 강제 적용
Linux: Unix 도메인 소켓으로 파일시스템을 통해 라우팅 (socat 사용). 네트워크 네임스페이스를 완전히 제거하여 모든 트래픽이 프록시를 거치도록 강제.
macOS: Seatbelt 프로파일이 특정 localhost 포트만 허용. 프록시가 이 포트에서 대기하며 모든 네트워크 접근 제어.
파일시스템 격리
기본 권한:
- 읽기: 기본적으로 모든 곳 허용, 특정 경로 차단 가능
- 쓰기: 기본적으로 현재 작업 디렉토리만 허용
# 예시 설정
{
"filesystem": {
"denyRead": ["~/.ssh"], # SSH 키 읽기 차단
"allowWrite": [".", "/tmp"], # 현재 디렉토리와 /tmp 쓰기 허용
"denyWrite": [".env"] # .env 파일 쓰기 차단
}
}
macOS에서 glob 패턴 지원:
{
"allowWrite": [
"src/**/*.ts", // src/ 내 모든 .ts 파일 허용
"test/*.js" // test/ 내 .js 파일만 허용
]
}
라이브러리로 사용하기
CLI 도구뿐만 아니라 Node.js 라이브러리로도 사용할 수 있습니다
import { SandboxManager, type SandboxRuntimeConfig } from '@anthropic-ai/sandbox-runtime'
import { spawn } from 'child_process'
// 샌드박스 구성 정의
const config: SandboxRuntimeConfig = {
network: {
allowedDomains: ['example.com', 'api.github.com'],
deniedDomains: []
},
filesystem: {
denyRead: ['~/.ssh'],
allowWrite: ['.', '/tmp'],
denyWrite: ['.env']
}
}
// 샌드박스 초기화 (프록시 서버 시작 등)
await SandboxManager.initialize(config)
// 샌드박스 제한과 함께 명령어 래핑
const sandboxedCommand = await SandboxManager.wrapWithSandbox('curl https://example.com')
// 샌드박스된 명령어 실행
const child = spawn(sandboxedCommand, { shell: true, stdio: 'inherit' })
// 종료 처리
child.on('exit', (code) => {
console.log(`Command exited with code ${code}`)
})
// 정리 (선택사항, 프로세스 종료 시 자동 발생)
await SandboxManager.reset()
위반 감지 예제
import { SandboxViolationStore } from '@anthropic-ai/sandbox-runtime'
// 위반 감지 리스너 설정
SandboxViolationStore.onViolation((violation) => {
console.log('Sandbox violation detected:', violation)
// {
// type: 'file-read',
// path: '/Users/user/.ssh/id_rsa',
// timestamp: '2025-01-13T...',
// process: 'cat'
// }
})
// 명령 실행
await SandboxManager.wrapWithSandbox('cat ~/.ssh/id_rsa')
고급 설정
완전한 구성 예제
{
"network": {
"allowedDomains": [
"github.com",
"*.github.com",
"npmjs.org",
"*.npmjs.org"
],
"deniedDomains": ["malicious.com"],
"allowUnixSockets": ["/var/run/docker.sock"],
"allowLocalBinding": false
},
"filesystem": {
"denyRead": ["~/.ssh"],
"allowWrite": [".", "src/", "test/", "/tmp"],
"denyWrite": [".env", "config/production.json"]
},
"ignoreViolations": {
"*": ["/usr/bin", "/System"],
"git push": ["/usr/bin/nc"],
"npm": ["/private/tmp"]
},
"enableWeakerNestedSandbox": false
}
일반적인 구성 방법
GitHub 접근 허용:
{
"network": {
"allowedDomains": [
"github.com",
"*.github.com",
"lfs.github.com",
"api.github.com"
]
}
}
특정 디렉토리로 제한:
{
"filesystem": {
"denyRead": ["~/.ssh"],
"allowWrite": [".", "src/", "test/"],
"denyWrite": [".env", "secrets/"]
}
}
Linux의 Unix 소켓 제한
Linux에서는 seccomp BPF (Berkeley Packet Filter)를 사용하여 시스템 콜 레벨에서 Unix 소켓 생성을 차단합니다:
┌─────────────────────────────────────────┐
│ Outer bubblewrap │
│ - 파일시스템 제한 │
│ - 네트워크 네임스페이스 격리 │
│ │
│ ┌─────────────────────────────────┐ │
│ │ apply-seccomp binary │ │
│ │ - socket(AF_UNIX) 차단 │ │
│ │ - prctl()로 seccomp 적용 │ │
│ │ │ │
│ │ ┌──────────────────────────┐ │ │
│ │ │ User Command │ │ │
│ │ │ - Unix 소켓 생성 불가 │ │ │
│ │ └──────────────────────────┘ │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
작동 방식:
- 사전 생성된 BPF 필터가 x64, ARM64용으로 포함 (vendor/seccomp/)
- 런타임에 시스템 아키텍처를 감지하고 적절한 필터 로드
- BPF 필터가 socket() 시스템 콜을 가로채고 AF_UNIX 소켓 생성 시 EPERM 반환
일반적인 문제와 팁
Jest 실행하기
Watchman이 샌드박스 경계 밖의 파일에 접근하므로 --no-watchman 플래그를 사용하세요:
srt "jest --no-watchman"
Linux 위반 추적
Linux에서는 strace를 사용하여 차단된 작업을 추적할 수 있습니다:
# 모든 거부된 작업 추적
strace -f srt <your-command> 2>&1 | grep EPERM
# 특정 파일 작업 추적
strace -f -e trace=open,openat,stat,access srt <your-command> 2>&1 | grep EPERM
# 네트워크 작업 추적
strace -f -e trace=network srt <your-command> 2>&1 | grep EPERM
플랫폼 지원 및 의존성
macOS
- 기본 제공 (sandbox-exec 사용)
- ripgrep 필요: brew install ripgrep
Linux
필수 도구:
# Ubuntu/Debian
apt-get install bubblewrap socat ripgrep
# Fedora
dnf install bubblewrap socat ripgrep
# Arch
pacman -S bubblewrap socat ripgrep
src/
├── index.ts # 라이브러리 익스포트
├── cli.ts # CLI 진입점 (srt 명령)
├── utils/ # 공유 유틸리티
│ ├── debug.ts # 디버그 로깅
│ ├── settings.ts # 설정 리더
│ ├── platform.ts # 플랫폼 감지
│ └── exec.ts # 명령 실행 유틸리티
└── sandbox/ # 샌드박스 구현
├── sandbox-manager.ts # 메인 샌드박스 매니저
├── sandbox-schemas.ts # Zod 스키마 (검증)
├── sandbox-violation-store.ts # 위반 추적
├── http-proxy.ts # HTTP/HTTPS 프록시
├── socks-proxy.ts # SOCKS5 프록시
├── linux-sandbox-utils.ts # Linux bubblewrap
└── macos-sandbox-utils.ts # macOS sandbox-exec
보안 제한사항
알아야 할 중요한 사항
- 네트워크 샌드박싱 한계: 도메인 기반 필터링만 수행하며 트래픽 내용은 검사하지 않음. 신뢰할 수 있는 도메인만 허용해야 합니다.
- Unix 소켓을 통한 권한 상승: /var/run/docker.sock 같은 소켓을 허용하면 호스트 시스템 접근 권한을 부여하는 것과 같습니다.
- 파일시스템 권한 상승: $PATH의 실행 파일, 시스템 구성 디렉토리, 쉘 구성 파일에 대한 쓰기 권한은 신중하게 부여해야 합니다.
- Linux 약한 샌드박스 모드: enableWeakerNestedSandbox 옵션은 Docker 환경에서 작동하지만 보안이 크게 약화됩니다.
고급: 커스텀 프록시 사용
더 정교한 네트워크 필터링을 위해 자체 프록시를 사용할 수 있습니다:
# mitmproxy로 트래픽 검사
mitmproxy -s custom_filter.py --listen-port 8888
이를 통해:
- 트래픽 검사 및 수정
- 복잡한 필터링 로직 구현
- 감사 로깅
가능합니다. 예를 들어, github.com을 허용하되 특정 API 호출만 필터링하여 데이터 유출을 방지할 수 있습니다.
개발하기
# 의존성 설치
npm install
# 프로젝트 빌드
npm run build
# seccomp 바이너리 빌드 (Docker 필요)
npm run build:seccomp
# 테스트 실행
npm test
# 통합 테스트
npm run test:integration
# 타입 체크
npm run typecheck
# 린트
npm run lint
# 포맷팅
npm run format
결론: 안전한 AI 에이전트의 기반
Anthropic Sandbox Runtime은 AI 에이전트를 안전하게 실행하기 위한 핵심 인프라입니다:
- 최소 권한 원칙: 기본적으로 모든 것을 차단하고 필요한 것만 허용
- OS 레벨 보안: 컨테이너 없이도 강력한 격리 제공
- 투명성: 실시간 위반 모니터링으로 무슨 일이 일어나는지 파악
- 유연성: CLI 도구와 라이브러리 모두 지원
- 실전 검증: Claude Code에서 실제 사용 중
이 도구는 단순히 샌드박스를 넘어, AI 에이전트를 기본적으로 안전하게 만들기 위한 에코시스템의 일부입니다.
참고 자료:
- GitHub: https://github.com/anthropic-experimental/sandbox-runtime
- Claude Code 샌드박싱 문서: https://docs.claude.com/en/docs/claude-code/sandboxing
- 블로그: "Beyond Permission Prompts: Making Claude Code More Secure and Autonomous"
이 글은 Anthropic의 실험적 프로젝트인 Sandbox Runtime의 공식 문서를 바탕으로 작성되었습니다.
'AI > Agent' 카테고리의 다른 글
| AI Models Need a Virtual Machine (2) | 2025.09.04 |
|---|---|
| Agent란 무엇일까? (4) | 2025.04.19 |
| 구글 A2A(Agent to Agent) 발표 (0) | 2025.04.12 |
| MCP 업데이트 (0) | 2025.03.29 |