Docker가 원하는 에이전트의 벽을 출시했다. 기본적으로 비활성화되어 있다.
요약
Docker가 새로운 `docker agent` 명령어를 통해 AI 에이전트를 구축하고 실행하는 기능을 기본적으로 제공합니다. 이 기능은 선언적 YAML 구성을 사용하여 OpenAI, Anthropic 등 다양한 모델과 연결되며, '허용되는 것'을 명시하여 안전한 런타임을 구현했습니다.
핵심 포인트
- Docker가 `docker agent`를 통해 AI 에이전트 기능을 기본 탑재함.
- YAML 기반의 선언적 구성으로 에이전트의 도구(toolset)를 정의합니다.
- 샌드박스 모드를 제공하여 에이전트 실행 환경을 안전하게 격리합니다.
- OpenAI, Anthropic 등 다양한 LLM과의 연동성을 확보했습니다.
Docker Desktop을 최근에 업데이트했다면(버전 4.63 이상), 이미 새로운 명령인 docker agent가 시스템에 설치되어 있습니다. 별도의 설정이나 공지사항을 읽을 필요조차 없었습니다. 리포지토리는 이 기능을 "선언적 YAML 구성(declarative YAML config)을 사용하여 AI 에이전트를 구축, 실행 및 공유하는 방법"이라고 설명하며, OpenAI, Anthropic, Gemini, Bedrock, Mistral, xAI, 그리고 Docker 자체의 모델 런너에 이르기까지 다양한 곳과 관련됩니다. 이 기능은 "모든 MCP 서버(로컬, 원격 또는 Docker 기반)"를 처리할 수 있으며, 기본적으로 설치되어 제공됩니다. Docker는 자신을 구축하는 데 이 기능을 사용한다고 밝히고 있습니다. 이는 수백만 대의 개발 장비가 자동 업데이트되는 과정에서 조용히 에이전트 런타임을 확보하고 있다는 의미입니다.
저는 또 다른 프레임워크 분석 글을 작성하는 대신, 하루 저녁 시간을 리포지토리와 문서에 할애했습니다. 왜냐하면 이 프로젝트는 제가 계속해서 돌아오는 근본적인 경계(fault line)의 바로 위에 놓여 있기 때문입니다: 즉, 에이전트가 읽을 수 있는 것과 에이전트가 수행하도록 허용된 것 사이의 격차입니다. 2년 전만 해도 그 격차가 저의 문제였습니다. 저는 자체 코딩 에이전트를 위한 안전벨트 후크(seatbelt hook)를 작성하고, 이를 공격적으로 테스트했으며, 유일하게 버틸 수 있는 벽인 운영체제(operating system)에서 글을 마무리했습니다. Docker가 방금 그 '벽'의 제품화된 버전을 출시한 것입니다. 이 엔지니어링은 정말 훌륭합니다. 기본 설정이 바로 이야기입니다.
실제로 구현된 기능
모델은 Claude Code를 YAML로 변환하여 사용합니다: 코드가 아닌 구성(config)으로서의 에이전트가 핵심입니다. toolsets 블록을 통해 에이전트가 얻게 될 것이 무엇인지 선언합니다—예를 들어, type: filesystem, type: shell, 그리고 Docker의 MCP 카탈로그에서 가져온 모든 것을 위한 type: mcp (문서에 따르면 '수백 개의 MCP 서버'가 ref: 라인을 통해 연결 가능). 권한 페이지, 비밀(secrets) 가이드, OpenTelemetry 트레이싱 기능까지 갖추어져 있습니다. README 파일에는 익명 텔레메트리 보고와 Apache-2.0 라이선스가 명시되어 있으며, 10,000개 이상의 커밋 기록이 존재합니다.
이를 긍정적인 정책(positive policy)으로 해석한다면, toolset 블록은 올바른 아이디어입니다. 이는 제가 만든 안전벨트의 두 번째 버전이 거쳤던 것과 같은 역전(inversion) 과정입니다: 금지된 것을 나열하는 대신, 허용되는 것을 선언하고, 명시되지 않은 것은 실패 처리(fail closed)하도록 하는 것입니다. 툴 표면(tool surface)이 변경 가능한 YAML 파일인 런타임은 풀 리퀘스트(pull request)에서 검토할 수 있는 런타임입니다. 마땅히 인정해야 할 부분에 경의를 표합니다.
문서화된 벽
sandbox 모드 문서에서는 제가 다루기에는 너무 높은 수준의 훅 스크립트(hook scripts)에 대해 설명합니다. 이를 활성화하면 에이전트는 일반 컨테이너가 아닌, 전용 샌드박스 CLI를 중심으로 하는 오케스트레이터 내 Docker Sandbox VM 안에서 실행됩니다. 마운트 테이블은 명확합니다: 작업 디렉토리는 읽기-쓰기(read-write); 에이전트 설정 및 키트 디렉토리는 읽기 전용(read-only); 그 외 모든 것은 보이지 않습니다 — "다른 호스트 파일은 에이전트에게 보이지 않는다." VM은 자체 $HOME을 갖습니다.
네트워크 이야기는 제가 요청했고 예상하지 못했던 부분입니다: 기본적으로 거부하는 아웃바운드 프록시(default-deny egress proxy)가 있으며, 모델 게이트웨이와 패키지 레지스트리를 포함하는 실행별 허용 목록(per-run allowlist)을 갖습니다. 이는 선언된 호스트(runtime.network_allowlist) 또는 영구 저장되는 docker agent sandbox allow를 통해서만 확장할 수 있습니다. 기본적으로 거부하는 아웃바운드 방출은 실제로 프롬프트 주입 에이전트를 가두는 통제 장치입니다. 왜냐하면 모델이 무엇을 결정하든 상관없이, 탈취 경로(exfiltration path)가 프록시에서 막히기 때문입니다. 클라우드 모드는 샌드박스를 구현하며 호스트 API 키를 업로드하는 것을 거부합니다.
이것이 바로 벽입니다. 제가 임시로 조립한 어떤 것보다도 더 잘 설계되었으며, 저는 이것을 사용하고 싶습니다.
발견 사항
--sandbox는 기본값이 false입니다.
dokcs의 자체 문구를 읽어보세요: 실행별로 활성화(docker agent run --sandbox), YAML에 포함하거나(runtime: sandbox: true), 별칭(alias)에 연결하세요. 모든 경로는 선택적 참여(opt-in)입니다. 기본적으로, docker agent run agent.yaml은 호스트에서 실행됩니다 — 여기서 type: shell과 type: filesystem은 노트북에서 항상 의미했던 것을 의미합니다: 사용자의 계정이 폭발 반경(blast radius)입니다. 읽기 전용 마운트와 기본 거부 프록시를 갖춘 샌드박스는 문서화되어 있고, 잘 구축되어 있지만 — 글로브박스 안에 있습니다.
기본값은 정책입니다. 안전 모드를 플래그 뒤에 탑재하는 모든 주요 하네스는 사용자들이 문서를 읽을 것이라고 베팅해 왔으며, 그 베팅의 기록은 '내 에이전트가 데이터베이스를 삭제했다'라는 게시물 전체 장르로 나타납니다. dev.to에는 인접한 툴체인에 대한 글이 이미 있습니다 — MCP(Machine Context Provider) 툴 권한을 통해 기계의 모든 컨테이너를 삭제하는 에이전트가 등장했는데, Docker의 MCP 카탈로그는 이러한 강력한 기능을 원클릭으로 YAML 선언적 편의성으로 연결합니다. 편리함은 취약점이 아닙니다. 편리함이야말로 그 취약점이 실제로 발휘될지 여부를 결정하는 것입니다.
문이 열려 있는 곳
샌드박스를 켜더라도, 세 개의 문은 닫히지 않으며, 문서에서는 적어도 하나에 대해서는 솔직하게 언급합니다:
툴 공급망(tool supply chain)은 컨텍스트 공급망입니다. 격리는 코드가 무엇을 하는지를 포함하지만, 툴 오염 공격은 모델이 무엇을 읽는지를 공격합니다. 완벽한 VM 내부의 MCP 서버는 여전히 지침을 담고 있는 툴 설명을 반환합니다 — 모델은 이를 컨텍스트로 소비하며, 어떤 마운트 테이블도 텍스트를 필터링하지 못합니다. 카탈로그의 원클릭 첨부는 제 안전벨트 게시물에서 언급된 새로운 블록리스트 문제와 같은 선상에 있습니다: 신뢰 결정이 쉘 명령어에서 툴 정의로 이동했으며, 에이전트 YAML에 대한 대부분의 검토는 툴셋 이름에서 멈춥니다.
비밀 정보 마스킹(Secret redaction)은 최선의 노력입니다. Docker 자체 문서에서도 언급하듯이, 자동 키트 마스킹은 난독화된 토큰이 새어 나올 수 있게 할 수 있습니다. 여기에 '이전 샌드박스는 자동으로 삭제되지 않는다'는 점이 결합되면, 토큰이 중지된 샌드박스 상태에 지속될 수 있다는 의미입니다 — 문서는 제거를 위해 sbx rm --force가 필요하며, 중지된 샌드박스가 여전히 스토리지 요금을 발생시킬 수 있다고 상기시킵니다. 민감한 작업에는 호스트 키 업로드가 없는 클라우드 모드의 규칙이 필요하거나, 아예 아무것도 없어야 합니다.
변경 가능한 태그(Mutable tags)는 재현성을 깨뜨립니다. 따라서 문서는 원격 키트와 이미지를 다이제스트(digest)로 고정하라고 말합니다. 올바른 조언이지만, 기본값은 아닙니다.
그리고 완전히 빠져 있는 레이어가 하나 더 있습니다. 바로 OpenTelemetry 트레이싱을 제공하는 문서입니다. 이는 '무슨 일이 일어났는지'를 사용자가 통제하는 컬렉터로, 수정할 수 없는 형식으로 기록합니다. Docker의 누구도 그들의 위협 모델에 '운영자가 나중에 기록을 편집한다'는 시나리오는 포함하지 않았는데, 이것은 그들에게는 공정하지만 프로덕션 환경에서 에이전트를 실행하는 모든 사람에게는 잘못된 것입니다. 트레이스는 디버깅 이야기입니다. 감사는 절대로 수정되지 않았음을 증명할 수 있는 기록이 필요합니다. 이 레이어는 여기(Docker)에서도, 아직 주류 시장 어느 곳에서도 제공되지 않습니다.
훔쳐낼 것들
# 안전벨트는 계속 착용되어야 합니다 — 안전 순서에 따른 모든 사격실험 실행 경로:
docker agent run --sandbox agent.yaml # 실행당, 명시적
...
여기에 YAML이 표현할 수 없는 두 가지 규칙이 더 있습니다. 검토하지 않은 기본 설정에서 type: shell과 type: filesystem을 함께 사용하도록 절대 허용해서는 안 되며, MCP 서버의 도구 정의를 코드처럼 읽어야 합니다. 왜냐하면 그것들이 이제 코드가 되었기 때문입니다.
두 가지 솔직한 한계점
이것은 출처 기반 분석이며 테스트가 아닙니다. 저는 이 글을 위해 docker-agent를 실행하지 않았습니다. 샌드박스에 대한 모든 주장은 README와 문서에서 가져온 것이며, 이는 문서의 정확성이 제가 빌려주는 가정임을 의미합니다. 샌드박스의 문서화 내용과 실제 동작 사이의 간극에서 저는 저 자신의 후크(hook)를 통해 네 가지 우회 경로를 발견했으므로, 제 평가를 '설계는 맞지만 벽이 버틴다'가 아니라 '설계 자체가 올바르다'로 받아들여 주십시오.
그리고 비판에는 유효 기간이 있습니다. 만 번의 커밋과 사전 설치된 배포판을 고려할 때, Docker는 한 번의 릴리스만으로 샌드박스 기본 설정을 바꿀 수 있습니다. 이는 이 글의 헤드라인을 가장 좋은 방식으로 구식화시킬 것입니다. 저는 화요일까지 틀렸다고 인정하는 편이 진심으로 나을 것 같습니다.
당신 차례입니다
당신의 Docker Desktop은 이미 docker agent를 포함하고 있습니까? 이 글을 읽기 전 또는 후에 샌드박스를 활성화했습니까 — 그리고 두 가지 방식으로 모두 실행해 보았다면, 호스트(host)에서 실행했을 때 무엇이 가능했을지 샌드박스가 무엇을 차단했는지 알려주십시오. 안전벨트 스레드는 댓글에서 계속됩니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기