AI 코딩 에이전트가 만든 코드를 서버에서 바로 실행해도 될까요? 핵심 질문은 “컨테이너 안에서 실행했는가”가 아니라 “실행 코드가 호스트, 내부망, 자격 증명에 어디까지 닿을 수 있는가”입니다.

이번 글에서는 GeekNews의 OpenSandbox 소개를 발견 경로로 삼고, 사실 확인은 OpenSandbox 공식 저장소와 공식 보안 문서로 한정했습니다. 직접 확인한 버전은 opensandbox-server 0.2.2, 서버의 Docker 예제 설정이 지정한 opensandbox/execd:v1.0.21입니다.

먼저 실제 배포판부터 확인했다

PyPI 메타데이터와 CLI 진입점을 격리 실행 도구 uvx로 확인했습니다.

curl -fsS https://pypi.org/pypi/opensandbox-server/json \
  | jq -r '.info.version, .info.requires_python'
uvx --from opensandbox-server opensandbox-server --help

확인 시점의 응답은 서버 버전 0.2.2, 요구 Python 버전 >=3.10이었습니다. CLI에는 서버 실행뿐 아니라 Docker·Kubernetes 예제 설정을 만드는 init-config가 포함돼 있었습니다.

Docker 예제 설정도 파일에 저장하지 않고 표준 출력으로 확인했습니다.

uvx --from opensandbox-server opensandbox-server \
  init-config /dev/stdout --example docker --force

예제는 위험한 capability를 제거하고 no_new_privileges = true, PID 상한을 설정합니다. 여기까지는 좋은 출발점입니다. 하지만 같은 설정에서 다음 세 가지를 함께 발견했습니다.

  • API 키가 비어 있으면 비대화형 실행에서 명시적인 insecure 승인 값이 필요합니다.
  • 호스트 bind mount 허용 경로가 빈 배열이면 모든 호스트 경로가 허용된다고 주석에 명시돼 있습니다.
  • 강한 격리 런타임은 별도 설정이며, 기본 Docker 경로만으로 자동 활성화되지 않습니다.

따라서 “예제 설정으로 서버가 뜬다”와 “불특정 사용자의 AI 코드를 안전하게 받는다”는 다른 완료 조건입니다.

Apple Silicon에서 공식 이미지도 직접 확인했다

예제 설정이 가리키는 execd:v1.0.21의 OCI 인덱스를 조회했습니다.

docker buildx imagetools inspect opensandbox/execd:v1.0.21
docker run --rm --platform linux/arm64 \
  opensandbox/execd:v1.0.21 --help

이미지 인덱스 digest는 sha256:1dc98c7de10b9a73450ac75aa0f200ad7972f2c40f5225f6a8998e166b45d6dd였고, linux/amd64linux/arm64 manifest가 모두 있었습니다. M1 호스트에서는 arm64 이미지가 내려받아졌고 컨테이너가 docker/execd/v1.0.21 배너를 출력했습니다.

이 검증은 “공식 예제에 적힌 이미지가 실제로 존재하고 현재 호스트 아키텍처에서 시작된다”는 사실만 증명합니다. 컨테이너가 시작됐다는 사실이 멀티테넌트 격리, 비밀 보호, 네트워크 차단을 자동으로 증명하지는 않습니다.

운영에서는 세 개의 경계를 따로 닫아야 한다

1. 실행 격리: runc와 강한 격리는 같은 말이 아니다

공식 Secure Container Runtime 가이드는 기본 runc를 프로세스·cgroup 수준 격리로 분류하고, 신뢰할 수 없는 코드에는 gVisor나 Kata Containers 같은 선택지를 제시합니다. OpenSandbox는 서버 수준에서 gVisor, Kata, Firecracker 계열 런타임을 지정할 수 있지만, 해당 런타임을 호스트에 설치해 주지는 않습니다.

즉 운영자는 다음을 별도로 검증해야 합니다.

  • 서버가 지정한 OCI runtime 또는 Kubernetes RuntimeClass가 실제 노드에 있는가
  • 모든 샌드박스에 그 runtime이 강제되는가
  • syscall, GPU, systemd, 네트워크 정책 등 워크로드 호환성이 유지되는가
  • 실패 시 일반 runc로 조용히 내려가지 않고 서버가 시작을 거부하는가

공식 문서는 설정한 secure runtime을 찾지 못하면 서버가 시작을 거부한다고 설명합니다. 이 fail-closed 동작은 운영 점검표에 넣을 가치가 있습니다.

2. 네트워크 격리: 인터넷 접근 허용과 비밀 전달을 묶지 않는다

AI 에이전트는 패키지 설치나 API 호출 때문에 외부 통신이 필요할 수 있습니다. 그렇다고 전체 인터넷을 허용하면 프롬프트 인젝션이나 악성 코드가 내부 서비스와 메타데이터 엔드포인트를 탐색할 수 있습니다.

OpenSandbox의 Credential Vault 문서defaultAction="deny"와 필요한 호스트만 허용하는 정책을 권장합니다. 실제 비밀은 샌드박스 환경변수나 파일에 넣지 않고 egress sidecar가 허용된 HTTPS 요청에만 주입합니다.

여기에도 전제가 있습니다. Credential Vault는 DNS 전용 모드가 아니라 dns+nft 강제가 필요하고, 투명 프록시를 함께 쓰는 서비스 메시와는 현재 충돌할 수 있습니다. gVisor는 egress sidecar가 사용하는 nat 테이블과 호환되지 않는 제한도 공식 문서에 적혀 있습니다. 따라서 “gVisor + Credential Vault”를 체크박스 두 개처럼 단순 조합하면 안 됩니다.

3. 저장소와 자격 증명: 허용 목록은 비어 있지 않아야 한다

Docker 예제의 allowed_host_paths = []는 개발 환경에서는 편하지만 운영 기본값으로 위험합니다. 샌드박스가 마운트할 수 있는 호스트 경로를 작업 전용 디렉터리로 좁히고, Docker socket·SSH 키·클라우드 설정·배포 자격 증명은 범위 밖에 둬야 합니다.

비밀도 마찬가지입니다. 실제 API 키를 명령행, 환경변수, 샌드박스 파일에 넣지 말고 다음 세 조건을 함께 적용해야 합니다.

  1. 외부 통신은 기본 거부
  2. 호스트·메서드·경로 단위로 credential binding 제한
  3. 샌드박스 안에는 가짜 키만 두고 실제 키는 프록시에서 주입

도입 전 최소 점검표

  • 정확한 서버·SDK·execd·egress 버전을 함께 기록했는가
  • 이미지 태그뿐 아니라 digest를 고정하고 서명을 검증하는가
  • runc, gVisor, Kata 중 실제 위협 모델에 맞는 런타임을 선택했는가
  • runtime을 찾지 못할 때 작업을 거부하는지 시험했는가
  • API 인증 없이 서버를 시작하지 못하게 했는가
  • bind mount 허용 경로가 명시적인 최소 목록인가
  • egress가 기본 거부이며 내부망과 메타데이터 주소가 차단되는가
  • 실제 비밀이 샌드박스 환경·파일·로그에 남지 않는가
  • CPU, 메모리, PID, 실행 시간 제한과 종료 후 정리가 동작하는가

결론

OpenSandbox는 AI 코드 실행을 위한 공통 API, 다중 언어 SDK, Docker·Kubernetes 런타임과 보안 기능을 한 플랫폼에 모은 유용한 출발점입니다. 공식 arm64 이미지와 CLI 배포도 실제로 확인했습니다.

하지만 기본 Docker 예제를 실행했다는 이유만으로 “안전한 AI 샌드박스”가 완성되지는 않습니다. 개인 개발 환경에서는 빠른 실험 도구로 쓸 수 있지만, 신뢰할 수 없는 코드나 여러 사용자를 받는 운영 환경에서는 강한 런타임 격리, 기본 거부 egress, 자격 증명 프록시, 제한된 host mount를 하나의 위협 모델로 검증해야 합니다.

이번 확인에서는 전체 OpenSandbox 서버와 gVisor·Kata를 실제 운영 구성으로 띄우거나 탈출 공격을 수행하지 않았습니다. 따라서 결론은 제품의 완전한 보안 인증이 아니라, 공식 배포판과 설정에서 확인한 도입 전 경계입니다.