AI 에이전트에게 코드 작성 권한을 주는 것과, 그 코드를 실행하도록 허용하는 것은 다른 결정이다. 많은 조직이 전자는 신중하게 검토하면서 후자는 벤더의 "안전한 샌드박스"라는 말을 믿고 넘어간다. 문제는 그 말이 계약서나 아키텍처 문서 어딘가에 한 번 적혀 있을 뿐, 실제 실행이 얼마나 격리된 환경에서 일어났는지 매번 확인할 수단이 없다는 데 있다.
요구사항 단계에서 격리 수준을 명시하지 않으면, 나중에 "우리 벤더는 안전하다고 했다"는 말 외에 남는 것이 없다.
격리 수준이란 무엇이고, 왜 단계가 있는가
샌드박스라는 단어는 여러 기술을 하나로 묶어 부르는 편의 표현이다. 실제 격리 강도는 무엇을 경계로 삼느냐에 따라 크게 네 단계로 나뉜다.
가장 약한 단계는 프로세스 격리다. 운영체제의 프로세스 경계만 이용하므로, 같은 커널을 공유하는 다른 프로세스와 시스템 콜 경로가 겹친다. 그다음은 컨테이너 격리로, 네임스페이스와 cgroup으로 파일시스템과 네트워크를 분리하지만 여전히 호스트 커널을 함께 쓴다. 커널 격리는 사용자 공간 커널을 별도로 두거나 seccomp 정책으로 시스템 콜 자체를 제한한다. 가장 강한 단계는 VM 격리로, 하이퍼바이저가 하드웨어 경계를 만든다.
컨테이너가 프로세스보다 강하고, VM이 컨테이너보다 강하다. 이 차이는 공격 표면의 차이이기도 하다. 컨테이너 탈출 취약점은 실제로 발견되며, 그 경우 호스트 커널로 접근이 이어질 수 있다. VM 탈출은 훨씬 어렵지만 성능 비용이 따른다. 어느 단계가 적절한지는 실행되는 코드의 신뢰도와 접근 가능한 자원에 따라 달라진다.
요구사항을 작성할 때 "샌드박스 환경에서 실행한다"고 쓰면 네 단계 중 어디든 해당한다. 이것은 요구사항이 아니라 희망이다.
벤더 마케팅이 숨기는 것
벤더 문서가 "안전한 격리 환경"이나 "엔터프라이즈급 보안"을 이야기할 때, 그 문장이 가리키는 기술 경계가 무엇인지 확인하는 팀은 생각보다 적다. 확인이 어려운 이유가 있다. 격리 수준을 마케팅 문서에 단계로 표기하는 벤더는 드물고, 설령 표기하더라도 그것이 모든 실행에 동일하게 적용되는지는 별개의 문제다.
실제로 격리 수준은 인프라 상태에 따라 달라질 수 있다. 부하가 높을 때 컨테이너 격리로 폴백하도록 설계된 시스템이라면, 평소 테스트 환경에서 확인한 VM 격리가 프로덕션 트래픽 피크에서도 보장되지 않을 수 있다. 벤더가 "VM 격리를 지원한다"고 말하는 것과 "모든 실행이 VM 격리에서 일어났음을 실행마다 보고한다"는 것은 다르다.
후자를 요구하지 않는다면, 벤더 선정 단계에서 이 차이를 구분할 기준이 없다.
요구사항에 격리 수준을 적는 방법
격리 수준을 요구사항화하는 것은 생각보다 구체적인 작업이다. 다음 세 가지를 명시해야 한다.
첫째, 최소 격리 단계를 지정한다. 어떤 코드를 어느 격리 단계 이상에서만 실행할 것인지 결정한다. 외부 API 자격증명에 접근하거나 데이터베이스를 조회하는 코드라면 컨테이너 격리 이상을 요구하는 것이 합리적이다. 에이전트가 완전히 임의로 작성한 코드라면 커널 격리나 VM 격리를 최솟값으로 설정할 수 있다. 여기서 중요한 점은, 요구 단계보다 낮은 격리에서 실행을 아예 거부해야 한다는 것이다. "가능하면 강하게"는 요구사항이 아니다.
둘째, 실행 결과에 격리 단계를 포함하도록 요구한다. 실행이 끝난 후 반환되는 결과 객체에 실제로 어느 격리 단계에서 실행됐는지 기록되어야 한다. 이것은 마케팅 문서의 선언이 아니라, 해당 실행의 인프라 상태와 설정을 기반으로 수집된 값이어야 한다. 이를 확인할 수 없다면, 격리 수준은 사후에 검증할 방법이 없다.
셋째, 미달 시 거부 동작을 정의한다. 격리 수준이 요구 기준에 미치지 못할 경우 코드가 아예 실행되지 않아야 하고, 그 거부 이유가 명시적으로 반환되어야 한다. 실행이 일어난 후에 "이번엔 격리가 약했다"고 알려주는 것은 격리가 아니다.
자격증명과 네트워크 접근을 어떻게 설계할 것인가
격리 수준과 별개로, 에이전트가 작성한 코드가 자격증명이나 네트워크에 어떻게 접근하는지도 요구사항 단계에서 정해야 한다.
에이전트 코드가 API 키를 직접 가지고 실행되는 구조와, 코드 자체는 자격증명을 모르고 외부 브로커가 검증 후 대신 호출하는 구조는 보안 모델이 근본적으로 다르다. 전자는 코드가 탈출하거나 로그를 통해 유출될 경우 자격증명이 함께 노출된다. 후자는 코드가 어떤 경로로 접근하려 해도 브로커가 허용된 경로만 통과시킨다.
어느 구조를 선택하든, 요구사항에는 다음을 포함해야 한다. 코드가 네트워크에 직접 접근할 수 있는지, 자격증명이 샌드박스 내부에 전달되는지, 허용되지 않은 경로로 호출을 시도할 경우 어떻게 차단되는지. 이 세 가지가 명확하지 않으면 벤더 비교 자체가 불가능하다.
벤더 평가에서 확인해야 할 질문
아래 질문에 대해 벤더가 문서나 API 응답으로 답할 수 없다면, 해당 항목은 요구사항 미달로 처리하는 것이 낫다.
격리 단계를 네 수준 이상으로 구분하는가, 아니면 "샌드박스"라는 단어만 사용하는가. 각 실행 결과에 실제 격리 단계가 포함되어 반환되는가. 요구 격리 수준을 충족하지 못할 경우 실행 자체를 거부하고 이유를 명시적으로 반환하는가. 에이전트 코드가 자격증명에 직접 접근하지 못하도록 구조적으로 막혀 있는가. 격리 수준은 런타임에 수집된 값인가, 아니면 설정 파일의 선언인가.
마지막 질문이 핵심이다. 격리 수준이 데이터시트의 약속이 아니라 실행마다 측정된 값이어야, 인프라 상태가 변해도 그 변화를 추적할 수 있다.
검증 가능성과 암호학적 증명 사이의 간격
"매 실행마다 격리 수준을 보고한다"는 것과 "하드웨어 수준에서 암호학적으로 증명한다"는 것은 다르다. 전자는 실행 환경의 설정과 상태를 기반으로 수집한 값이고, 후자는 TEE(신뢰 실행 환경)나 원격 증명 기술이 뒷받침되어야 한다.
현재 상용 샌드박스 서비스 대부분은 전자에 해당하며, 이것이 의미 없다는 뜻은 아니다. 실행 설정에서 수집된 격리 단계는 감사 로그로 기능하고, 격리 수준을 충족하지 못한 실행의 거부 이력을 남긴다. 다만 이것은 하드웨어 수준의 암호학적 보장이 아니므로, 규제 요건이나 보안 정책이 그 수준을 요구한다면 별도로 명시해야 한다.
어느 수준의 검증이 조직에 충분한지를 요구사항 단계에서 결정하지 않으면, 벤더가 제공하는 수준이 자동으로 "충분한 것"이 된다.