AI 생성 코드를 안전하게 실행하는 방법 — 실무적인 샌드박싱 체크리스트
요약
AI 에이전트가 생성한 코드를 프로덕션 환경에서 안전하게 실행하기 위한 실무적인 샌드박싱 가이드를 제공합니다. 모든 AI 생성 코드를 잠재적 위협으로 간주하고, 실행 후 즉시 파괴되는 일회용 샌드박스 환경 구축을 핵심 원칙으로 제시합니다.
핵심 포인트
- 모든 AI 생성 코드를 적대적인 것으로 간주하고 설계할 것
- 실행당 하나의 일회용 샌드박스를 사용하고 재사용을 금지할 것
- gVisor나 Firecracker 같은 microVM을 통한 강력한 격리 경계 구축
- 네트워크 송신 기본 거부(default-deny) 및 읽기 전용 파일 시스템 적용
- CPU, 메모리, 실행 시간 등 리소스 제한 및 최소 권한 원칙 준수
교차 게시. 원문: stellarbytecapital.com/blog/how-to-run-ai-generated-code-safely
AI 에이전트(AI agent)를 구축하고 있다면, 머지않아 에이전트가 코드를 작성할 것이고 당신은 그 코드를 _실행_해야 할 것입니다. 실행하는 순간, 당신은 어떤 인간도 당신의 인프라(infrastructure)에 맞춰 검토하지 않은 무언가를 실행하게 됩니다. 이것은 이를 안전하게 수행하기 위한 실무적인 체크리스트이며, 우리가 프로덕션(production) 환경에서 사용하는 제어 수단들을 중요도 순서대로 나열한 것입니다.
요약하자면: 모든 AI 생성 코드를 적대적인 것으로 간주하고, 런타임(runtime)이 완전히 침해되더라도 공격자가 얻을 수 있는 것이 없도록 설계하십시오.
첫째, 위협 모델 (threat model)
제어 수단을 마련하기 전에, 신뢰할 수 없는 코드를 실행할 때 무엇이 잘못될 수 있는지에 대해 솔직해져야 합니다:
- 동일한 호스트(host)에 있는 다른 사용자의 데이터를 읽거나 유출(exfiltrate)합니다.
- 데이터를 유출하거나 페이로드(payload)를 가져오기 위해 네트워크에 접속합니다.
- 상태(state)를 남깁니다 — 임시 파일, 변형된 환경 변수(env), 백그라운드 스레드(background threads) 등 — 이는 다음 실행을 오염시킵니다.
- CPU, 메모리 또는 디스크를 고갈시켜 공유 서비스를 중단시킵니다.
- 커널(kernel) 또는 런타임 버그를 통해 샌드박스(sandbox)를 완전히 탈출합니다.
"아마 모델이 그런 짓은 안 하겠지"라는 생각은 제어 수단이 아닙니다. 실제로 그런 일이 발생할 경우를 대비해 설계하십시오.
핵심 패턴: 실행당 하나의 일회용 샌드박스
가장 영향력이 큰 결정: 모든 실행을 각각의 새로운 샌드박스에서 실행하고, 실행 후에는 이를 파괴하십시오. 절대 재사용하지 마십시오.
재사용은 대부분의 버그와 공격이 발생하는 지점입니다 — 유출된 파일 디스크립터(file descriptors), 남겨진 임시 파일, 변형된 전역 변수(globals), 지난 실행에서 남은 백그라운드 스레드 등이 해당됩니다. 아무것도 재사용되지 않는다면, 이러한 부류의 문제들은 완전히 사라집니다. 속도를 유지하려면, 준비된 샌드박스의 _웜 풀(warm pool)_을 유지하고 각 샌드박스가 소비될 때마다 새로 채워 넣으십시오.
체크리스트
- 격리 경계 (Isolation boundary) — 언어 수준의 "안전한 eval (safe eval)"이 아닌 실제 경계를 사용하십시오. 컨테이너 (Container)가 기본이며, 커널 탈출 (kernel escapes)에 대해서는 microVM (
gVisor,Firecracker)이 더 강력합니다. - 네트워크 송신 (Network egress): 기본 거부 (default-deny) — 기본적으로 외부 네트워크로의 연결을 허용하지 마십시오. 인터넷에 접속할 수 없는 탈출된 에이전트는 데이터를 보낼 곳이 없습니다.
- 파일 시스템 (Filesystem): 읽기 전용 (read-only) + 휘발성 (ephemeral) — 입력값은 읽기 전용으로 마운트(mount)하고, 샌드박스와 함께 소멸되는 임시 공간 (scratch space)을 제공하십시오.
- 리소스 제한 (Resource limits) — 실행당 CPU, 메모리, PID, 그리고 실제 실행 시간 (wall-clock time)을 제한하십시오.
- 사용자별 할당량 (Per-user quotas) — 특정 시간 범위 내 사용자당 실행 횟수를 제한하여, 남용 및 무한 루프 (runaway loops)를 방지하십시오.
- 최소 권한 (Least privilege) — 비루트 (non-root), 권한 삭제 (dropped capabilities), Docker 소켓 사용 금지, 호스트 장치 접근 금지를 준수하십시오.
- 비밀 정보 격리 (Secrets stay out) — 생성된 코드가 실행되는 샌드박스에 API 키를 절대 마운트하지 마십시오. 인증이 필요한 호출은 신뢰할 수 있는 계층을 통해 프록시 (proxy) 처리하십시오.
- 모든 항목 감사 (Audit everything) — 모든 생명주기 단계와 모든 네트워크 호출에 대해 이벤트를 생성하십시오.
흔한 실수 (Common mistakes)
- 시작 시간을 아끼기 위해 수명이 긴 인터프리터 (interpreter)를 재사용하는 것 — 밀리초(ms)를 아끼려다 영구적인 상태 유출 (state-leak) 표면을 제공하게 됩니다.
- "작업에 필요할 수도 있다"는 이유로 전체 네트워크 송신을 허용하는 것. 기본 거부 (Default-deny)를 적용한 후 화이트리스트 (allowlist) 방식으로 허용하십시오.
- 모델이 범위를 벗어나지 않을 것이라고 믿는 것. 프롬프트로 요청하지 말고 샌드박스 동작을 통해 강제하십시오.
- 개발 단계에서 편의를 위해 컨테이너 내부에서 루트 (root) 권한으로 실행하는 것.
컨테이너인가 microVM인가?
대부분의 내부 도구의 경우, 기본 거부 송신이 적용된 강화된 일회성 컨테이너 (one-shot container)가 합리적인 기준점입니다. 멀티 테넌트 (multi-tenant) 환경이거나 적대적인 코드 (adversarial code)를 실행하는 경우, gVisor 또는 Firecracker로 격상하십시오. 더 강력한 격리를 제공하면서도 웜 풀 (warm pool)을 통해 여전히 저렴하게 운영할 수 있습니다.
핵심은 **조합 (combination)**입니다: 일회용 샌드박스, 송신 차단, 읽기 전용 파일 시스템, 제한된 리소스, 할당량, 최소 권한, 비밀 정보 격리, 그리고 완전한 감사입니다.
저희는 Xingyao Byte입니다 — 보안 AI 실행 계층, 퀀트 트레이딩 (quant trading) 시스템, 그리고 결제 플랫폼을 구축하고 있습니다. 원격 근무 및 비동기 우선 방식 → stellarbytecapital.com
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기