OpenSandbox 해부: AI 에이전트를 내 인프라의 격리 상자에서 — execd·egress·Credential Vault·Firecracker FastSandbox와 Docker 없는 박스 검증

오늘(2026-11-10) GitHub Trending Python 일간 목록에 opensandbox-group/OpenSandbox가 올라왔습니다. 하루 168★, 누적 17,024★(수집 시점), 라이선스 Apache-2.0, 최신 안정 릴리스 release-1.2.0(2026-10-27), 현재 release-1.2.1-rc.1(11-04)이 후보로 나와 있습니다. 원래 Alibaba에서 시작해 지금은 Agentic AI Foundation(AAIF) 프로젝트로 옮겨 간 저장소이고, SDK 패키지 이름(com.alibaba.opensandbox, @alibaba-group/opensandbox)에 그 흔적이 남아 있습니다.

한 줄로 요약하면 “AI 에이전트가 만든 코드·명령·브라우저 작업을 내 인프라 안의 격리된 상자에서 돌리는 범용 샌드박스 플랫폼”입니다. E2B·Daytona 같은 관리형 샌드박스를 직접 운영하고 싶은 팀, 코딩 에이전트 평가나 RL 롤아웃을 수백 개 상자에서 동시에 돌리는 팀이 주 대상입니다. 이 글은 입문용 소개가 아니라 실무자 기준 해부입니다. 제어 플레인과 데이터 플레인을 어떻게 나눴는지, 송신 트래픽과 비밀값은 어떻게 다루는지, Firecracker 기반 FastSandbox 수치를 어떻게 읽어야 하는지 정리하고, 마지막으로 Docker 데몬이 없는 박스에서 무엇이 실제로 돌았고 무엇이 막혔는지 그대로 적습니다.

OpenSandbox 한눈에: 클라이언트 → FastAPI lifecycle 서버 → Docker / Kubernetes(BatchSandbox·agent-sandbox·FastSandbox) 런타임
OpenSandbox 한눈에: 클라이언트 → FastAPI lifecycle 서버 → Docker / Kubernetes(BatchSandbox·agent-sandbox·FastSandbox) 런타임

1. 한눈에 보는 프로젝트 카드

항목 내용 (2026-11-10 KST 확인)
저장소 github.com/opensandbox-group/OpenSandbox (2025-12-17 생성, 기본 브랜치 main, 확인한 HEAD 383e84f)
라이선스 Apache-2.0 (코드). 문서 라이선스는 CONTRIBUTING.md에 따로 명시
버전 안정 release-1.2.0(10-27) · 후보 release-1.2.1-rc.1(11-04) · PyPI opensandbox-server / opensandbox-cli 1.2.0
인기 17,024★ · 1,607 forks · Trending Python 일간 +168★
주요 언어 Python(서버·SDK)과 Go(execd·egress·ingress·K8s 컨트롤러)가 거의 같은 비중, 그다음 Kotlin·C#·TypeScript SDK
거버넌스 AAIF 프로젝트. CHARTER·GOVERNANCE·MAINTAINERS, 설계 제안서 oseps/(OSEP), OpenSSF Best Practices 배지
진입점 SDK 5종(Python·JS/TS·Java/Kotlin·C#·Go), osb CLI, MCP 서버, OpenAPI 스펙 specs/
GitHub 공식 Open Graph 카드 — opensandbox-group/OpenSandbox (2026-11-10 수집)
GitHub 공식 Open Graph 카드 — opensandbox-group/OpenSandbox (2026-11-10 수집)

2. 왜 지금 ‘셀프호스트 샌드박스’가 다시 뜨는가

코딩 에이전트가 IDE 플러그인 수준을 넘어 저장소를 클론하고, 패키지를 설치하고, 테스트를 돌리고, 브라우저를 조작하게 되면서 문제는 “모델이 똑똑한가”에서 “모델이 만든 명령을 어디서, 어떤 권한으로, 어떤 네트워크로 실행하는가”로 옮겨 갔습니다. 개발자 노트북에서 바로 돌리면 사고 반경이 너무 넓고, 관리형 SaaS 샌드박스는 데이터 주권·비용·사내망 접근 때문에 막히는 조직이 많습니다. 평가와 RL 쪽은 더 급합니다. SWE 계열 벤치마크 한 번에 수백~수천 개 격리 환경이 필요하고, 각 환경은 몇 분만 살다 사라집니다.

OpenSandbox가 내세우는 답은 세 가지입니다. ① 로컬 Docker에서 시작해 Kubernetes로 넘어가도 같은 lifecycle API를 쓴다. ② 실행 트래픽은 제어 플레인을 거치지 않고 상자 안의 execd에 직접 붙는다. ③ 송신 트래픽은 egress 사이드카가 막고, 비밀값은 상자 밖에 둔다. 1.2.0에서 Credential Vault와 FastSandbox auto-pause/wake-on-access가 “end to end”로 들어온 것이 이번 주목의 직접적인 계기로 보입니다.

3. 아키텍처: 여섯 개의 면, 세 개의 경로

공식 문서(docs/architecture/index.md)는 시스템을 여섯 개의 면(surface)으로 나눕니다. 실무에서 기억할 것은 경로가 세 개라는 점입니다. Lifecycle(주황)은 생성·조회·연장·일시정지·재개·삭제와 스냅샷·템플릿 관리입니다. Execution(파랑)은 명령·파일·PTY·Jupyter 실행과 사용자 서비스 포트 접근입니다. Outbound(초록)는 상자에서 외부 API로 나가는 트래픽입니다.

공식 아키텍처 다이어그램: Lifecycle(주황) · Execution(파랑) · Outbound(초록) 세 경로 (docs/public/images/architecture-overview.png)
공식 아키텍처 다이어그램: Lifecycle(주황) · Execution(파랑) · Outbound(초록) 세 경로 (docs/public/images/architecture-overview.png)
면 위치 책임
Client sdks/, cli/, sdks/mcp/ 생성된 OpenAPI 클라이언트 + 손으로 쓴 어댑터(스트리밍·에러 매핑·전송 수명주기)
Protocol specs/ lifecycle(/v1)·diagnostics·execd·egress OpenAPI 계약이 “단일 진실 공급원”
Lifecycle control plane server/ (FastAPI) API key 인증, 설정 검증, 메타데이터 저장(SQLite 기본/PostgreSQL), 런타임 서비스로 위임
Runtime backends server/.../services/, kubernetes/ Docker / Kubernetes(BatchSandbox·Pool 또는 kubernetes-sigs/agent-sandbox) + FastSandbox 어댑터
Data plane components/execd, components/nodeagent 상자 안 Go 데몬: 명령(SSE)·세션·PTY(WebSocket)·파일·Jupyter·메트릭
Network & security components/ingress, components/egress 헤더/URI 라우팅 게이트웨이, DNS·nftables 정책, Credential Vault, secureAccess

설계 원칙도 이 분리를 그대로 따릅니다. 서버는 오케스트레이션과 검증만 하고, 플랫폼별 리소스 생성은 런타임 프로바이더가, 상자 안에서 일어나는 일은 execd와 egress가 맡습니다. 그래서 명령 실행 트래픽이 lifecycle 서버를 지나지 않습니다. 클라이언트는 GET /v1/sandboxes/{id}/endpoints/{port}로 주소를 받은 뒤 execd에 직접 연결하고, 필요하면 X-EXECD-ACCESS-TOKEN 헤더를 붙입니다. 서버가 실행 데이터 경로의 병목이나 단일 장애점이 되지 않는다는 뜻이지만, 대신 네트워크 도달성을 운영자가 따로 설계해야 합니다. 직접 연결이 막힌 환경을 위해 서버 프록시(--use-server-proxy)와 Kubernetes ingress 게이트웨이를 대안 경로로 제공합니다.

3-1. 런타임 선택 로직: ID 접두사가 곧 디스패처

[runtime].type은 docker와 kubernetes 두 값만 받습니다. Kubernetes 모드에서는 CompositeSandboxService가 생성 요청을 살펴, templateId가 있으면 FastSandbox로, image/snapshotId가 있으면 컨테이너 프로바이더로 보냅니다. 이미 만든 상자에 대한 작업은 ID 접두사(fsb-)로 라우팅합니다. 상자별 백엔드를 기록하는 별도 저장소가 없으니 단순하고, SDK는 백엔드가 바뀌어도 그대로 동작합니다. 대신 기능 매트릭스는 백엔드마다 다릅니다(아래 표).

기능 Docker K8s BatchSandbox K8s FastSandbox (Firecracker)
생성 입력 image / snapshotId image / snapshotId, extensions.poolRef templateId(골든 이미지)
execd 주입 서버가 execd_image에서 바이너리 스테이징 + bootstrap init container가 emptyDir로 복사 템플릿 빌드 시 게스트 이미지에 포함
pause/resume 컨테이너 freeze (사이드카 순서 보장) rootfs를 OCI 이미지로 commit 후 재생성, 또는 QEMU VM-state FastPath 체크포인트(메모리+디스크 보존)
공개 스냅샷 API 로컬 이미지 commit SandboxSnapshot CR → OCI 레지스트리 push 별도 경로(OverlayBD OCI, 1.2.0)
볼륨(host/pvc/ossfs) 지원 지원 어댑터가 현재 거부
egress 상자별 사이드카(bridge 네트워크 필요) 파드에 사이드카 추가, 메인 컨테이너 NET_ADMIN 제거 Fastlet 파드당 공유 egress 프로세스

4. 데이터 플레인의 핵심, execd

execd는 Gin 기반 Go 데몬이고 기본 포트는 44772입니다. 스펙(specs/execd-api.yaml)을 보면 /ping, /command(SSE 스트리밍, 포그라운드/백그라운드), /command/status/{id}, /command/{id}/logs, /session(지속 bash), /pty(WebSocket), /files/*·/directories, /code/*(Jupyter 커널), /metrics·/metrics/watch가 있습니다. 여기에 /v1/isolated/session/* 계열이 추가되어 상자 안에서 다시 격리된 세션을 만들고 diff/commit할 수 있습니다. 에이전트가 파일을 고친 결과를 커밋 전에 검토하는 흐름을 API 수준에서 지원하는 셈입니다.

/command 요청은 셸 문자열(command)과 네이티브 인자 배열(argv) 중 정확히 하나를 받습니다. 프롬프트 인젝션으로 만들어진 문자열을 셸 확장 없이 넘기고 싶다면 argv를 쓰는 편이 안전합니다. timeout(ms), uid/gid, envs, cwd도 지정할 수 있습니다. 응답 스트림 이벤트는 init(명령 ID) → ping → stdout/stderr → execution_complete 또는 error 순서로 옵니다. 아래 박스 실측에서 이 순서를 그대로 확인했습니다.

# execd API 직접 호출 예 (SDK가 내부적으로 하는 일)
curl -N -X POST http://<endpoint>/command \
  -H 'X-EXECD-ACCESS-TOKEN: <token>' -H 'content-type: application/json' \
  -d '{"argv":["python3","-c","print(1+1)"],"timeout":30000}'

운영 관점에서 짚을 부분이 두 가지 있습니다. 첫째, 명령 핸들러는 스트림을 닫기 전에 기본 200 ms grace를 둡니다(--graceful-shutdown-timeout). 그래서 echo 한 줄도 왕복 약 200 ms가 걸립니다. 공식 성능 문서도 commands.run('echo') p50 202.8 ms를 “셸 기동 시간이 아니다”라고 따로 설명합니다. 짧은 명령을 수천 번 쏘는 RL 루프라면 세션 API로 묶거나 grace 값을 조정하는 것이 좋습니다. 둘째, execd README에는 execd-ebpf 관찰 변형이 이미지에 들어 있지만 서버 쪽 선택 로직이 아직 연결되지 않았다는 Known issue가 적혀 있습니다. 운영에서 eBPF 관찰을 전제로 설계하면 안 됩니다.

5. 송신 통제와 Credential Vault: 비밀값은 상자 밖에

egress 사이드카의 DNS·nftables 정책과 Credential Vault 헤더 주입 흐름 (egress.md · credential-vault.md 재구성)
egress 사이드카의 DNS·nftables 정책과 Credential Vault 헤더 주입 흐름 (egress.md · credential-vault.md 재구성)

에이전트 샌드박스에서 가장 위험한 순간은 상자 안 코드가 외부로 나갈 때입니다. 패키지 설치나 모델 API 호출은 허용해야 하지만, 임의 호스트로 데이터를 빼돌리는 것은 막아야 합니다. OpenSandbox의 egress 컴포넌트는 두 층으로 동작합니다.

모드/기능 동작 한계·주의
dns FQDN·와일드카드 allow/deny로 DNS 응답을 필터링 이름만 막음. 직접 IP 연결은 우회 가능(예제 config 기본값이 dns)
dns+nft nftables default-deny + DNS로 학습한 IP에 한시적 lease UDP/QUIC은 DNS lease 타이밍에만 의존. 연결 유지 중엔 lease 만료까지 유효
플랫폼 overlay deny.always > allow.always > 사용자 정책, 1분마다 hot-reload overlay는 사이드카 이미지 안에 들어감 → 이미지 공급망 관리 필요
포트 floor reachable.ports.cap로 TCP 포트 화이트리스트를 강제 TCP만 적용. 가로챈 포트도 화이트리스트 안에 있어야 함
암호화 DNS DoT(853) 항상 차단, DoH(443) 차단은 스위치 하나 DoH는 기본 허용일 수 있어 운영자가 명시적으로 켜야 함
Credential Vault 투명 MITM(80/443) → binding 정확히 1개가 맞을 때만 인증 헤더 주입 dns+nft 필수, default-deny 권장. Istio 같은 다른 투명 사이드카와 공존 불가

Credential Vault의 흐름은 이렇습니다. 호스트 쪽 SDK가 실제 키와 binding(스킴·호스트·포트·메서드·경로)을 사이드카의 /credential-vault에 씁니다. 상자 안 프로세스는 가짜 또는 빈 환경변수만 받습니다. Claude Code나 git, curl이 허용된 HTTPS 호스트로 나가면 사이드카가 요청 메타데이터를 보고, binding이 정확히 하나 맞을 때만 헤더를 끼워 넣습니다. 응답과 vault 조회 결과에서는 비밀값이 가려집니다. 프롬프트 인젝션으로 env를 덤프당해도 진짜 키가 상자 안에 없으니 새지 않는다는 것이 핵심입니다.

문서에 적힌 운영상 함정도 꽤 구체적입니다. ① 사이드카 프로필에서 vault는 프로세스 메모리에만 있습니다. Kubernetes pause는 스냅샷 후 파드를 지우므로 resume하면 vault가 비어 있고, 다시 써 넣어야 합니다(Docker pause/unpause는 유지). ② active-vault 소켓은 가로챈 모든 트래픽의 하드 의존성입니다. 타임아웃·5xx·잘못된 ETag가 나면 fail-closed로 요청을 막습니다. 안전 쪽으로 실패하는 설계지만, 장애가 나면 상자의 외부 통신 전체가 멈춥니다. ③ 1.2.0에서 FastSandbox용 vault가 들어오면서 MITM CA를 풀 단위로 고정해 egress 재시작 때 신뢰 앵커가 바뀌는 문제를 막았습니다. 동적 헤더 해석(exchange credentials)은 1.2.1 이상이 필요하고 Kotlin·C# SDK 지원은 후속 작업입니다.

6. FastSandbox: Firecracker를 ‘골든 이미지 + 사전 예열’로 쓰는 법

Kubernetes 위에서 컨테이너 상자를 하나 만들려면 스케줄러, watch 전파, kubelet, 이미지 풀, 컨테이너 기동을 모두 거쳐야 합니다. 보통 초 단위가 걸립니다. FastSandbox는 이 경로를 생성 hot path에서 걷어냅니다. 미리 띄워 둔 Fastlet 파드(파드 하나에 슬롯 여러 개)에 Firecracker microVM을 넣고, 커널을 부팅하는 대신 템플릿 스냅샷을 복원합니다. 변경과 실시간 조작은 gRPC FastPath v2 제어 플레인이 맡고, 지속 상태는 sandbox.fast.io CRD에 남깁니다. FastPath가 재시작해도 CR에서 다시 수렴하게 하려는 구조입니다. 노드 간 아티팩트 전달은 P2P(DART)로 하고, 실패한 작업의 잔해는 Janitor가 치웁니다. FastPath와 런타임 자체는 별도 저장소(opensandbox-group/fast-sandbox) 소관이고, 이 저장소에는 어댑터와 엔드포인트 통합만 있습니다.

FastSandbox 공식 측정(ACK 2노드, 2026-10-08): 생성 지연과 동시 20 실패, pause/resume 분 단위
FastSandbox 공식 측정(ACK 2노드, 2026-10-08): 생성 지연과 동시 20 실패, pause/resume 분 단위
측정(ACK 2노드, 2026-10-08) 성공 p50 p99
SDK 생성, 직렬 기준선 100/100 64.0 ms 108.3 ms
SDK 생성, 동시 10 100/100 102.7 ms 125.4 ms
SDK 생성, 동시 20 51/100 136.7 ms 197.0 ms
warm /ping (게이트웨이 경유) 100/100 0.92 ms 5.91 ms
pause → durable Paused 3 샘플 61.14 s —
같은 노드 resume → guest /ping 200 3 샘플 62.66 s —

README 첫 줄의 “64 ms P50 / 125.4 ms P99″는 위 표의 직렬 p50과 동시 10 p99를 함께 쓴 것입니다. 이 수치를 읽을 때 조건이 붙습니다. ① warm 경로입니다. 템플릿 아티팩트가 두 노드에 이미 캐시되어 있고 Fastlet 슬롯 20개가 준비된 상태였으며, 첫 사용 시 아티팩트 전달 비용은 빠져 있습니다. ② 클라이언트가 readiness를 10 ms마다 폴링했습니다(SDK 기본값은 200 ms). ③ 동시 20에서는 48건이 HTTP 429(CapacityRejected), 1건이 readiness timeout으로 실패했습니다. 문서도 “20-way 수용이나 지속 가능한 RPS를 입증하지 않는다”고 스스로 적었습니다. ④ pause/resume은 2 GiB rootfs와 2 GiB 메모리를 아티팩트 저장소에 올렸다 내리는 데 시간이 대부분 들어 분 단위입니다. 런타임 생성 자체는 35 ms 수준이지만 체감 재개 시간은 약 1분입니다. 정리하면 “에피소드마다 새 상자를 띄우는 RL·평가”에는 생성 지연이 매력적이고, “사용자 세션을 재우고 깨우는 IDE형 워크로드”는 1.2.0의 auto-pause(lifecycle.idlePolicy, idleTimeoutSeconds 30–86400, wakeOnAccess)를 쓰더라도 분 단위 깨움을 UX에서 감당해야 합니다.

7. 설치와 실행: 로컬 Docker에서 클러스터까지

# 1) 서버: 예제 설정 생성 후 기동 (Docker 데몬 필요)
uvx opensandbox-server init-config ~/.sandbox.toml --example docker
uvx opensandbox-server            # api_key가 비어 있으면 TTY에서 YES 입력 또는 OPENSANDBOX_INSECURE_SERVER=YES

# 2) SDK
uv pip install opensandbox         # Python
npm install @alibaba-group/opensandbox

# 3) CLI
uv tool install opensandbox-cli
osb config set connection.domain localhost:8080
osb sandbox create --image python:3.12 --timeout 30m -o json
osb command run <sandbox-id> -o raw -- python -c "print(1 + 1)"

# 4) MCP (Claude Code·Cursor 등)
pip install opensandbox-mcp
opensandbox-mcp --domain localhost:8080 --protocol http   # --transport stdio|streamable-http

--example docker로 만든 설정에는 보안 기본값이 꽤 들어 있습니다. drop_capabilities로 NET_ADMIN·NET_RAW·SYS_ADMIN·SYS_PTRACE 등을 빼고, no_new_privileges = true, pids_limit = 4096, 서버 바인드 127.0.0.1:8080을 씁니다. 반대로 반드시 손봐야 할 곳도 있습니다. api_key는 주석 처리되어 있습니다. allowed_host_paths = []는 “모든 호스트 경로 허용”이라는 뜻이라 운영에서는 반드시 좁혀야 합니다. publish_host가 주석이면 상자 포트가 0.0.0.0에 열립니다. egress 기본 모드는 dns라 Credential Vault를 쓰려면 dns+nft로 바꿔야 합니다. 브리지 모드에서는 상자 하나가 호스트 포트를 2~3개 쓰니 포트 범위(기본 40000–60000)와 방화벽 정책도 같이 계산해야 합니다.

설정 키 (예제 docker) 예제 값 운영 권장
[server].api_key 주석(비어 있음) 필수 설정. 비우면 INSECURE 확인을 요구
[storage].allowed_host_paths [] = 전부 허용 전용 디렉터리 접두사만 허용
[docker].publish_host 주석 → 0.0.0.0 127.0.0.1 또는 브리지 게이트웨이
[egress].mode dns dns+nft (Vault 전제조건)
[runtime].execd_image / [egress].image execd v1.1.0 / egress v1.1.7 태그 digest로 고정. umbrella 릴리스는 서명·provenance 공백이 이슈 #2463으로 추적 중
[store] SQLite ~/.opensandbox/opensandbox.db 다중 사용자면 PostgreSQL(DB당 서버 프로세스 1개)

저장소의 examples/에는 디렉터리가 30개 있습니다. Claude Code·Codex CLI·Gemini CLI·Qwen Code·Kimi CLI·OpenCode·GitHub Copilot CLI 같은 코딩 에이전트, LangGraph·Google ADK·Microsoft Agent Framework·DeerFlow·deep-agents 같은 프레임워크, Playwright·Chrome·Desktop·VS Code, Harbor 평가, AKS+Kata, 각종 볼륨 마운트 예제가 들어 있어 “우리 에이전트를 상자에 넣는 법”의 레퍼런스로 쓰기 좋습니다.

8. 박스 스모크 테스트: Docker 없이 어디까지 확인되나

박스 실측(2026-11-10 16:55–16:57 KST, Docker 없음): execd 소스 빌드 후 API 계약 검증, 서버 기동은 Docker 부재로 막힘
박스 실측(2026-11-10 16:55–16:57 KST, Docker 없음): execd 소스 빌드 후 API 계약 검증, 서버 기동은 Docker 부재로 막힘

2026-11-10 16:55–16:57 KST, Grok Bot 작업 박스(Linux x64, Go 1.27.2, Python 3.13, Docker 데몬 없음)에서 HEAD 383e84f로 직접 돌린 결과입니다. 상자를 띄우는 전체 경로는 Docker가 없어 막혔습니다. 그래서 데이터 플레인의 핵심인 execd를 소스에서 빌드해 호스트 프로세스로 띄우고, 스펙에 적힌 계약을 하나씩 호출했습니다. 이 방식은 격리 없이 호스트에서 명령을 실행하므로 검증용으로만 의미가 있습니다.

단계 실측 결과 판정
uvx --from opensandbox-server==1.2.0 opensandbox-server -h 61개 패키지 설치, 2.2 s, init-config/migrate-snapshots 서브커맨드 OK
init-config ./sandbox.toml --example docker “Wrote example config (docker)”, 위 표의 기본값 확인 OK
서버 기동 (OPENSANDBOX_INSECURE_SERVER=YES) 503 DOCKER::INITIALIZATION_ERROR “Docker daemon seems unavailable (unix socket not found)”, exit 1 막힘(환경)
go build ./components/execd 37 MB 바이너리, real 16.8 s OK
GET /ping (토큰 없음) 200, 1.4 ms (헬스체크는 인증 예외) OK
POST /command (토큰 없음) 401 “invalid or missing header X-EXECD-ACCESS-TOKEN” OK
POST /command 셸 문자열 init → ping → stdout “Hello OpenSandbox”, “2+2=4” → stderr “err” → execution_complete exit 0, 총 204 ms OK
POST /command argv python3 -c → “3.13.5”, execution_time 13 ms, 왕복 215 ms OK
timeout 1000 ms + sleep 5 1.20 s 만에 error 이벤트, “signal: killed”, exit_code -1 OK
/files/upload → download → 실행 metadata를 일반 폼 필드로 보내면 400 “metadata file is missing”. 파일 파트로 보내야 200, mode 755 반영, 실행 결과 “Hello OpenSandbox / 2 + 2 = 4” OK(주의)
background + status + logs status running=false, exit 0. logs는 tick1~3 반환. ?cursor=2는 “ck1…”부터 반환 주의
osb --version / opensandbox-mcp --help “opensandbox, version 1.2.0”, 서브커맨드 12종(credential-vault·egress·snapshot·template 포함). MCP는 stdio/streamable-http 전송 OK

눈에 띈 점이 셋 있습니다. ① SSE 왕복이 약 204 ms로, 문서가 설명한 200 ms grace와 정확히 맞습니다. 실제 실행 시간(execution_time 1~13 ms)과 체감 지연은 별개로 봐야 합니다. ② 백그라운드 로그의 cursor를 스펙은 “0-based line cursor”라고 설명하지만, 이번 빌드에서 cursor=2는 두 번째 바이트부터 잘라 반환했습니다. 구현(SeekBackgroundCommandOutput)도 파일 크기와 비교하는 바이트 오프셋 방식입니다. 직접 API를 호출하는 클라이언트라면 응답에 담긴 커서 값을 그대로 다음 요청에 넘기는 방식만 쓰는 것이 안전합니다. ③ 호스트에서 띄운 execd의 /metrics는 호스트 전체(8 CPU, 16 GiB)를 보고했습니다. 1.2.0 릴리스 노트가 “샌드박스 범위 CPU/메모리·OOM 보고”를 강조한 이유가 여기 있습니다. 컨테이너·cgroup 안에서 돌 때와 값의 의미가 다릅니다.

9. 비슷한 도구와 비교

항목 OpenSandbox E2B Daytona kubernetes-sigs/agent-sandbox NVIDIA OpenShell
성격 셀프호스트 플랫폼(서버+런타임+SDK) 관리형 클라우드 중심, SDK 오픈소스(Apache-2.0) AI 코드 실행 인프라(관리형+셀프호스트) K8s CRD/컨트롤러 프리미티브(Apache-2.0) 에이전트 런타임·정책 감독자(Apache-2.0, Rust)
격리 단위 컨테이너 / K8s 파드 / Firecracker microVM, Kata·gVisor RuntimeClass Firecracker microVM 격리 샌드박스(런타임 세부는 배포 방식별 확인) 파드(RuntimeClass로 강화) 호스트·컨테이너 위 정책 감독
API 계층 lifecycle /v1 + execd + egress OpenAPI, SDK 5종·CLI·MCP SDK(Python/JS) 중심 SDK·CLI·API K8s 리소스(별도 실행 API 없음) CLI·정책 파일
송신/비밀 처리 DNS+nft 정책, 플랫폼 overlay, 투명 MITM Credential Vault 플랫폼 제공 네트워크 제어 플랫폼 제공 네트워크 제어 NetworkPolicy 등 클러스터 도구에 위임 자격 증명 주입·정책 감독이 핵심 기능
관계 — 대체재(관리형 vs 셀프호스트) 대체재 OpenSandbox가 워크로드 프로바이더로 사용 가능 보완재(상자 안 에이전트 감독)
적합한 팀 자체 K8s·데이터 주권·대량 평가/RL 빨리 붙이고 운영은 맡기고 싶은 팀 개발 환경+에이전트 실행 통합 플랫폼 팀이 직접 조립 에이전트 행동 통제 우선

비교표의 다른 도구 항목은 각 프로젝트의 공개 설명 수준으로만 요약한 것입니다. 세부 기능·가격·라이선스는 도입 시점에 각 저장소에서 다시 확인하시기 바랍니다. 정리하면 OpenSandbox는 “agent-sandbox 같은 K8s 프리미티브 위에 lifecycle API·실행 데몬·송신 통제·SDK를 얹은 완성형 플랫폼” 쪽에 가깝고, E2B·Daytona의 셀프호스트 대안으로 비교 대상에 오를 만합니다.

10. 도입 전 체크리스트와 트레이드오프

고려사항 내용 권장 조치
격리 강도 Docker 기본은 일반 컨테이너(커널 공유). 신뢰할 수 없는 코드라면 부족 gVisor/Kata RuntimeClass 또는 FastSandbox(Firecracker) 사용, seccomp·AppArmor 지정
공급망 umbrella 릴리스 이미지의 서명·provenance 공백이 공개 이슈(#2463)로 추적 중 digest 고정, 사내 레지스트리 미러링, 자체 스캔
서버 재시작 Docker 런타임은 기동 시 만료 타이머를 복원. Docker 오류가 나면 서버 기동 자체가 실패 systemd Restart=on-failure 같은 감독자 아래 실행
네트워크 설계 실행 트래픽은 execd 직결. 클라이언트에서 상자 주소로 도달해야 함 ingress 게이트웨이 + secureAccess, 또는 server proxy
Vault 가용성 active-vault 장애 시 가로챈 트래픽 전체가 fail-closed. K8s pause 후 vault 초기화 resume 훅에서 vault 재주입, 원본은 시크릿 매니저에 보관
FastSandbox 용량 슬롯이 차면 429(CapacityRejected). 공식 측정에서도 20-way 수용은 입증되지 않음 클라이언트 재시도·백오프, Pool 크기를 피크 동시성 이상으로
API 호환성 빠른 릴리스 주기(1.1.0 9/21 → 1.2.0 10/27). 1.x에서 deprecated 키는 2.0에서 제거 예정 SDK·서버·이미지 버전을 같은 릴리스로 맞춰 고정

결론적으로 OpenSandbox는 “Docker로 5분 만에 시작”할 수 있는 장난감이면서, 동시에 Firecracker·CRD·MITM 프록시까지 다루는 꽤 무거운 플랫폼입니다. 장점은 계약 우선(specs/) 설계와 제어/실행/송신 경로 분리, 그리고 문서가 자기 한계를 솔직하게 적는다는 점입니다. 동시 20 실패, 서명 공백, eBPF 미연결 같은 내용을 스스로 공개합니다. 약점은 같은 이유로 생기는 운영 표면적입니다. 단일 팀의 코딩 에이전트 하나를 격리하는 데 쓰기엔 과하고, 플랫폼 팀이 여러 에이전트·평가 파이프라인의 공용 실행 기반을 만들 때 진가가 나옵니다. 도입한다면 로컬 Docker에서 execd 계약(SSE 이벤트, 타임아웃, 파일 API)을 먼저 익히고, egress를 dns+nft·default-deny로 바꾼 뒤 Credential Vault를 붙이고, 마지막에 Kubernetes·FastSandbox로 넘어가는 순서를 권합니다.