지식 요소의 가공과 분석, 그리고 여러가지 도구의 활용에 관한 내용

Docker sbx tui

Docker를 통한 Agentic Coding의 Sandbox화

최근 ChatGPT의 Codex/Work를 통해 다양한 개인 프로젝트를 진행하고 있었습니다만, 여기에서 생성하고 수행하는 스크립트 코드들에 대한 보안상의 우려로, 수행 환경의 분리를 고려하기 시작했습니다. 기본적으로 고려한 방법은 Docker의 활용, Ubuntu Multipass의 활용, 혹은 맥 자체의 User account를 활용하는 방법들이 떠오르게 되었는데, 이 뒤의 두가지는 Docker환경을 기본적으로 고려할 수 있습니다. 최근에는 Docker에서 microVM을 이용해 sandbox화 하는 프로토콜이 나옴으로써, 일반적인 Docker Container를 사용하는 것 보다 훨씬 강한 Sandbox를 달성할 수 있게 되었습니다. 사실 이 시점에 Ubuntu Multipass도 고려했었는데, Docker의 Sandbox (sbx)가 microVM으로 구동되는 것을 보고 편의를 위해 이쪽으로 선회한 것도 있습니다.

일단 개인 사용자 환경인 Macbook을 기반으로 만들어져 있고, 서버를 둔 여러 사용자 환경 등은 고려하지 않습니다. 개인 사용자로서, Docker를 이용한 filesystem을 구분하는 것을 목표로 두고 있고, network에 관한 보안은 아직까지 크게 고려하지는 않았습니다. 향후 Ubuntu Multipass등을 활용하여 더욱 강력한 filesystem기반의 sandbox로 넘어갈 수 있을것이라 생각합니다만, 결국 이 역시 Docker Container를 통해서 진행할 수 있을 것이라 기대합니다.

들어가기 앞서 라이센스쪽을 먼저 검토했는데, 적어도 제가 파악한 바로는 (+ChatGPT와의 의논 결과에서는) Docker CLI를 통한 sbx (sandbox) 패키지를 로컬에서 사용하는 것은 상업용 이용을 포함해서도 무료로 이용할 수 있습니다.

  1. Sandbox의 권한

기본적으로 Sandbox화한다는 것은 시스템에서 자원을 사용할 권리를 제한한다는 점입니다. 네트워크가 될 수도 있고, 메모리나 CPU의 사용량 등의 부분도 있지만, 제가 원했던 것은 “파일에 대한 권한”을 분리하고 코드등의 실행시 그 파급효과를 “제한”하는 것이 가장 큰 목적이었습니다. 기본적으로 Docker Sandbox를 보면 Filesystem 권한, Codex의 승인 권한, Network에 관한 권한 등에 직접적인 제어를 할 수 있게 되고요, 물론 MCP 등을 통해 다른 접근 경로를 추가할 수도 있습니다. 다만, 저 역시 본격적인 활용을 하면서 배워 나가는 입장이므로, 기본적으로 direct mount를 통해서 완벽한 Filesystem 분할까지는 하지 않지만 1차적인 저지선은 되는 수준에서 구성해 보았습니다.

여기서 direct mount는 로컬에 위치한 프로젝트 폴더를 sandbox화 시킬때 이를 host와 sandbox가 공유하는 형태입니다. 즉, 제가 local_test/test.org 파일을 수정한다고 했을 때, 이는 호스트 파일에도 영향을 줍니다. 그렇기 때문에 완전한 권한 분리가 이루어지지 않지만, 해당 폴더를 넘어서는 권한은 가지기 힘든 관계로 1차적인 보안은 된다는 이야기입니다 (마운트 되지 않은 다른 호스트 디렉터리에는 원칙적으로 접근할 수 없습니다). Host 저장소의 수정을 보호하기 위해서는 --clone 옵션을 사용하여 git clone을 생성하여 작업하는 방법이 있습니다.
사실 OpenAI Codex/Work를 최근에 많이 사용하면서 가장 자주 느꼈던 부분 중 하나가 local project를 진행하다 보면 각종 권한을 우리가 명시적으로 승인해 주는 형태로 최소한의 보안은 설정합니다만, 문제는 그 짧은 정보를 가지고 코드의 여파가 어디까지 미치는지를 알기 힘들다는 것입니다. 그래서 본격적으로 터미널 인터페이스를 바탕으로 OpenAI Codex 프로젝트 폴더를 디자인하면서는 Sandbox 정책에 대한 허용을 어디까지 해야 될 것인지에 대한 고민이 필요했습니다.
동시에, 가끔 사용량 최적화 등을 위해서, 생성한 Python 코드를 제가 직접 시행할때도 있는데, 사실 제 전문작업들을 제외하고, 다양한 취미활동에 사용되는 코드들을 그런 전문적인 수준으로 리뷰하지는 않습니다. 이게 단순히 OpenAI를 믿고 넘어간다고 하기에는 마음이 많이 간질간질한 부분이 있지요. 그래서 최소한의 isolation을 통해서, 만약 문제가 생기더라도 그 파급효과를 1차적으로 제한하자는 목적으로 sandbox를 고려한 것입니다.
여기에 하나 덧붙이자면, 최근에 Agent AI를 이용한 취미 활동 등을 하고 있습니다. 실제로 예전에 시도해 보려던 유사우주 프로젝트인데요 (https://story.edamyrepo.com/유사우주-프로젝트-설정집/), 이를 제법 상시적으로 돌리려고 하다 보니까 조금 더 일반적인 영역까지 고려해 보려는 노력이 필요하게 되더라고요. 여기에 대해서는, 나중에 글타래를 열어서 자료구조와 Time/Space Complexity를 어느 정도 제한하는 시스템 등까지 어떻게 고려했는지에 대해 정리를 해 볼 예정입니다.

  1. MacOS에서 Docker Sandboxes 설치 및 기본적인 운영

간만에 Docker 문서 (https://docs.docker.com/ai/sandboxes/install/) 에 접속해 보니, 이러한 sandbox환경을 위한 설정이 이미 제공되는 것을 알 수 있었습니다. 역시 Docker CLI처럼 무료로 사용할 수 있게 제공되고 있습니다.

설명에 따라 Homebrew를 통해 docker/tap/sbx를 설치해 주고, 기본적인 환경을 설정해 봅니다.
>> brew trust docker/tap
>> brew install docker/tap/sbx

이제 Docker계정으로 통한 login을 시도합니다.
>> sbx login

  1. OpenAI Codex 활용을 위한 계정 연결

저는 OpenAI Codex를 활용하기 위한 목표로 인증 절차를 진행합니다. 제가 파악하기로는, 인증 토큰은 sandbox 외부에 위치하게 됨으로 실제로 내부에서 인증토큰 자체에 접근하는 형태는 아닌것으로 알고 있습니다. 물론, Sandbox 내부에서 외부와의 communication이 가능한 형태로 이루어진다면, Sandbox 밖에 영향을 미칠 수 있으므로 주의가 필요합니다.
>> sbx secret set openai --oauth
ChatGPT와의 토론에서 중요한 사항이 하나 지적되었는데, “Sandbox가 인증 토큰을 직접 읽을 수 없다는 사실과, 해당 인증 토큰을 이용한 API 요청을 수행할 수 있다는 사실은 양립합니다”라고 합니다.
이제 Codex를 Docker sbx내에서 이용하게 되면, 제 계정에 있는 사용량을 소진하는 구조로 바뀝니다. 일반적으로 Plus계정의 경우에는, 뭔가 좀 테스트 하면 순식간에 5시간 한도가 모두 소진되므로, 처음 테스트 할때는 리셋 쿠폰을 좀 모아두고 시작하는것을 추천합니다.

  1. Sandbox내에서 OpenAI Codex활용

예를 들어 local_test라는 local folder를 활용하여 다음처럼 Docker로 “test”라는 Sandbox를 제공할 수 있습니다.
>> sbx run --name test codex local_test
한 번 생성한 Sandbox는 다음 명령어로 다시 연결할 수 있습니다.
>> sbx run --name test
다만, 이것이 Codex의 이전 대화를 복원하지는 않습니다. 종료 시 OpenAI Codex가 session ID를 제공한다면 아래 “–last”부분을 session ID로 바꾸어도 됩니다. 그렇지 않으면 일반적으로 다음 정도의 명령어로 마지막 상태로 재접속이 가능합니다.
>> sbx run --name test -- --dangerously-bypass-approvals-and-sandbox resume --last
약간의 설정을 거치고 난다면 다음의 화면을 볼 수 있습니다.

Docker sbx codex


Sandbox 내에서 codex를 사용할 때 실제로 --dangerously-bypass-approvals-and-sandbox 옵션으로 구동됩니다. 이는 Codex 상태창에서 YOLO 모드로 확인할 수 있는데, 이는 기본적으로 sandbox화되어 있으므로 오히려 Codex 자체의 실행 승인과 자체의 Sandbox 제약을 우회할 수 있도록 되어 있습니다. 즉, Docker Sandbox의 설정을 믿고 그 내부에서 돌아가는 Codex에게는 큰 자유가 주어집니다. 즉, 여전히 microVM이 제공하는 접근 경계는 그대로 유지됩니다.

현재 돌아가는 sbx 전체는 다음과 같이 확인할 수 있습니다.
>> sbx ls
조금 전체 full-down 메뉴를 좋아하시는 분들에게는 다음 정도가 좋겠네요.
>> sbx tui

Docker >> sbx tui


  1. Sandbox내에서 Python code의 활용

중요한 점은, 지금과 같은 설정에서 그냥 >> python3 test.py 을 수행하면, 그대로 호스트에서 진행됩니다. 그러므로 sandbox 내에서 다음과 같이 시행해야 합니다.
>> sbx exec test python3 test.py
만약 현재 Codex interface에서 바로 bash script를 수행하고 싶다면 iPython (Jupyter등에서 사용되듯이) shell escape인 “!”를 사용하면 됩니다. 즉 다음을 사용할 수 있습니다.
>> !pwd
>> !python3 test.py
여기서 direct mount의 경우에는 전체 경로를 인지하는 것을 알 수 있지만, 상위 디렉토리에는 권한을 주지 않습니다. 예로 들어 다음과 같은 경우가 나옵니다.

Permission denied with direct mount
  1. Sandbox 종료시 가끔 생기는 오류들

Ctrl+C로 종료시킨 다음에 보면 기존 process들이 제대로 정지되지 않은 경우가 있습니다. 먼저 다음을 확인해보는게 좋습니다.
>> sbx ls
>> sbx stop test

만약 데몬 자체가 비정상적이면 재시작 하는게 좋습니다.
>> sbx daemon restart
혹은 다음과 같이 진단을 시도해볼수 있습니다.
>> sbx diagnose
주의: >> sbx reset 은 단순한 재시작이 아니라 로컬 설정을 완전히 리셋하는 경우에 해당되므로, 확신이 없다면 시행하지 않는게 맞습니다.
저의 경우에는 위의 방법들이 깔끔하게 되지 않아서 결국 process를 찾아내서 직접 kill해줄 필요가 있었습니다 (아래에서 23423은 예시로 넣은 번호입니다):
>> pgrep -fl 'sandboxd|containerd-shim|nerdbox|sbx'
23423 sandboxd
>> sudo kill -KILL 23423


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *