본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 08. 13:42

BoxAgnts 도구 시스템 (1) — 설계 동기 및 아키텍처 개요

요약

BoxAgnts는 기존 AI 에이전트 프레임워크의 사후 보안 방식(샌드박스) 한계를 극복하기 위해 WebAssembly(WASM)를 활용한 런타임 수준의 격리 경계를 구축합니다. Rust로 구현된 이 시스템은 도구가 호스트 OS를 볼 수 없도록 설계되어 보안 위협을 근본적으로 차단합니다.

핵심 포인트

  • 기존 프레임워크의 소급적 보안 방식(syscall 가로채기) 한계 지적
  • WASM 기반의 런타임 수준 격리 경계 구축
  • Rust를 사용한 제로 외부 의존성 에이전트 런타임 구현
  • 역량 기반(Capability-based) 보안 모델 적용

AI 에이전트 (AI Agent) 프레임워크 지형은 상당히 과포화된 상태에 도달했습니다. Python 생태계에는 LangChain, CrewAI, AutoGen이 있고, TypeScript는 Vercel AI SDK를 제공하며, Go에는 langchaingo가 있습니다. 하지만 이 모든 프레임워크는 동일한 곤경을 공유하고 있습니다: 이들은 도구를 신뢰할 수 없는 환경에서 실행되는 신뢰할 수 있는 코드로 정의한 다음, 사후에 샌드박스 (sandbox)로 그 간극을 메웁니다.

BoxAgnts는 반대의 접근 방식을 취합니다. 이 방식은 더 어려운 길을 선택합니다: 사후에 시스템 호출 (syscall)을 가로채는 대신, 도구 실행이 시작되기 전에 보안 제약을 강제하기 위해 WebAssembly 샌드박스를 사용하여 런타임 (runtime) 수준에서 처음부터 격리 경계 (isolation boundary)를 구축하는 것입니다. 전체 시스템은 Rust로 밑바닥부터 구현되었습니다 — 12개의 크레이트 (crates), 외부 의존성이 없는 제로-외부-의존성 (zero-external-dependency) 에이전트 런타임, 그리고 12개의 AI 모델 제공업체와 직접 인터페이스하는 스트리밍 쿼리 엔진으로 구성됩니다.

도구 시스템의 "불가능한 삼각형"

LangChain 스타일의 도구 시스템은 깊게 뿌리박힌 가정을 바탕으로 합니다: 도구 코드와 에이전트 런타임이 동일한 프로세스에서 실행된다는 점입니다. Python의 exec(), subprocess.run(), Node의 child_process.spawn()은 모두 도구 실행 시점에 권한 확인을 수행하며, 이를 "소급적 (retrospective)" 방식으로 수행한다는 특징을 공유합니다 (알려진 위험한 시스템 호출을 가로채거나, 특정 파일 경로를 차단하는 등).

이 모델은 구조적인 문제를 가지고 있습니다. 새로운 "위험한 작업" 카테고리가 나타날 때마다 보안 인터셉터 (security interceptor)에 또 다른 규칙을 추가해야 하며, 이는 끝이 없는 군비 경쟁과 같습니다. rm -rf /가 차단되면 공격자는 dd if=/dev/zero of=/dev/sda를 시도합니다. 이것도 차단되면 포크 폭탄 (fork bomb)을 시도합니다. 알려진 모든 위험한 패턴을 차단할 수는 있지만, 공격 표면 (attack surface)은 운영 체제의 전체 시스템 호출 테이블로 남아 있습니다.

더 미묘한 문제는 도구 조합 (tool composition)입니다. file-read는 단독으로는 읽기 전용이며, web-fetch 또한 읽기 전용입니다. 하지만 AI가 먼저 file-read를 사용하여 ~/.ssh/id_rsa를 유출한 다음, web-fetch를 사용하여 이를 외부 서버로 POST 전송한다면, 단일 지점 검사 (single-point check)로는 이러한 도구 간 데이터 유출 (cross-tool data leak)을 잡아낼 수 없습니다.

이 문제에 대한 BoxAgnts의 대응책은 다음과 같습니다: 도구가 호스트 운영 체제 (host operating system)를 볼 수 없게 만드는 것입니다.

이것이 WASM 샌드박스 (WASM sandbox)와 전통적인 샌드박스 (traditional sandbox) 사이의 근본적인 차이점입니다. 전통적인 샌드박스 (seccomp, AppArmor, Docker seccomp profiles)는 OS 수준에서 "권한을 축소 (shrink permissions)"합니다. 반면 WASM 샌드박스는 권한 자체가 애초에 존재하지 않는 런타임 (runtime) 수준에서 작동합니다. WASM 프로그램은 기본적으로 open()이 무엇인지조차 알지 못하며, 오직 호스트가 WASI 인터페이스를 통해 명시적으로 주입한 디렉토리 핸들 (directory handles)에만 접근할 수 있습니다.

저는 이 설계를 **"역량 기반 (Capability-based)" 대 "권한 축소 (Permission-reduction)"**라고 부릅니다. 후자의 보안 경계는 "당신이 할 수 있는 모든 것에서 내가 금지한 것을 제외한 것"입니다. 전자의 보안 경계는 "내가 명시적으로 허용한 것만 가능하며, 그 외의 모든 것은 존재하지 않는다"입니다.

이는 상대적으로 낮은 엔지니어링 비용으로 강력한 보안 보장 (security guarantees)을 달성할 수 있음을 의미합니다. 이제 아키텍처를 살펴보겠습니다.

12개 크레이트 (Crates)의 계층적 설계

BoxAgnts의 Rust 측은 하단에서 상단으로 5개의 계층으로 구성된 12개의 크레이트 (crates)로 이루어져 있습니다.

계층 1: 런타임 (Runtime) (wasm-sandbox + wasm-tools)

wasm-sandbox는 Wasmtime의 컴포넌트 런타임 (component runtime)을 래핑 (wrap)하여 상위 계층에 통합된 execute() 인터페이스를 노출합니다. WASM 도구들은 wasm32-wasip2 타겟으로 컴파일되며 WASI 컴포넌트로 로드됩니다. 각 호출 시, 호스트는 작업 디렉토리를 게스트 (Guest)의 루트 파일 시스템으로 매핑하고, 허용된 외부 도메인 목록을 네트워크 계층에 주입하며, 실행 시간 제한 및 메모리 상한 (memory caps)을 설정한 후 — 그제서야 컴포넌트를 실행합니다.

wasm-tools는 도구 메타데이터 추출을 처리합니다. 이 방식은 "설정 파일 (configuration file)" 경로를 따르지 않습니다. 대신, WASM 도구를 직접 실행하여 --help 출력을 캡처하고, 정규 표현식 (regex)을 사용하여 파라미터 목록, 타입 및 설명을 파싱합니다. 이러한 자기 기술적 (self-describing) 파싱 메커니즘은 BoxAgnts의 "무설정 (zero-configuration)" 등록의 기반이며, 이에 대한 자세한 내용은 도구 등록 문서에서 다룹니다.

계층 2: 핵심 추상화 (tools + tools-manager + core)

core는 시스템 전체에서 사용되는 공유 데이터 타입인 Message, ContentBlock, ToolDefinition, UsageInfo를 정의합니다. 이 모듈은 수백 줄 정도로 가볍지만, 그 정확성이 모든 상위 계층 모듈에 직접적인 영향을 미칩니다.

tools는 전체 도구 시스템의 "공용 언어"인 Tool 트레이트 (trait)를 정의합니다. Rust 내장 도구이든 WASM 확장 도구이든 관계없이 모든 도구는 반드시 다음 메서드들을 구현해야 합니다:

pub trait Tool: Send + Sync {
    fn name(&self) -> &'static str;
    fn description(&self) -> &'static str;
...

tools-manager는 도구 등록 및 발견 센터입니다. 전역 도구 테이블을 유지 관리하고, 확장 디렉토리의 파일 변경 사항을 감시하며, 핫 리로딩 (hot-reloading)을 지원합니다.

계층 3: API 게이트웨이 (api + gateway)

api는 모든 주요 AI 모델의 통합 로직을 캡슐화합니다. 단일 LlmProvider 트레이트는 Transformer 패턴을 사용하여 양방향 메시지 형식 변환을 수행하며, Anthropic Messages API, OpenAI Chat Completions, Google Gemini, Cohere, MiniMax를 포함한 12개의 인터페이스를 통합합니다.

gateway는 비즈니스 오케스트레이션 (orchestration)을 제공합니다: 세션 관리, 도구 목록 구축, 모델 선택, 권한 필터링, Cron 작업 스케줄링 및 정적 사이트 배포가 이에 해당합니다.

계층 4: 에이전트 루프 (query)

query는 에이전트의 "심박수"입니다. run_query_loop() 함수는 전체 도구 호출 사이클을 구현합니다:

  1. 메시지 기록(message history)과 시스템 프롬프트(system Prompt)를 AI 모델로 전송
  2. SSE 스트림(SSE stream) 이벤트를 파싱하여 ToolUse 요청 감지
  3. 도구 테이블(tool table)에서 해당하는 도구 인스턴스를 찾아 권한 확인 수행
  4. tool.execute()를 호출하고 결과를 캡처
  5. 결과를 메시지 기록(message history)에 주입하고 1단계로 돌아감
  6. 모델이 end_turn을 반환하거나, 컨텍스트(context)가 소진되거나, 사용자가 취소하거나, 비용 제한(cost limit)을 초과할 때까지 반복

Layer 5: 웹 서비스 (Web Service, server)

최상위 계층은 REST API와 실시간 WebSocket 채팅 채널을 제공하는 Axum 기반의 HTTP/WebSocket 서버입니다. 프론트엔드는 Vue 3 + Vuetify 3 대시보드이며, 상태 관리를 위해 Pinia를, 코드 에디터를 위해 CodeMirror 6를 사용합니다.

이 아키텍처의 핵심적인 특징은 모든 계층이 명확한 책임 경계를 가지며, 암시적인 계층 간 의존성이 없다는 점입니다. query는 도구가 Rust 내장 도구인지 아니면 WASM 샌드박스(sandbox)인지 알지 못합니다. gateway는 AI 모델이 Anthropic의 것인지 OpenAI의 것인지 알지 못하며, tools-manager는 도구가 어떤 종류의 AI 대화에서 호출될지 알지 못합니다.

세 가지 핵심 설계 결정

1. 컨테이너(Containers) 대신 WASM 사용

많은 이들이 왜 단순히 Docker를 사용하지 않는지 묻습니다. 그 답은 시작 비용(startup cost)과 격리 입도(isolation granularity)에 있습니다.

WASM 컴포넌트를 실행하는 데는 마이크로초(microseconds)가 걸립니다. 이는 본질적으로 메모리에 로드되어 Wasmtime에 의해 실행되는 사전 컴파일된 바이너리입니다. 반면 Docker 컨테이너를 실행하는 데는 초(seconds) 단위가 걸리며, 웜 스타트(warm start)조차 수백 밀리초(milliseconds)가 소요됩니다. 에이전트(Agent) 대화에서의 도구 호출은 한 턴(turn) 내에서도 빠른 반환과 함께 여러 번 발생할 수 있는데, 이러한 시나리오에서 Docker의 시작 오버헤드는 용납할 수 없는 수준입니다.

격리 입도 측면에서 WASM은 컨테이너보다 더 세밀한 제어를 제공합니다. 컨테이너의 보안 경계는 파일 시스템, 네트워크, 프로세스와 같은 Linux 네임스페이스(namespaces) 및 cgroups입니다. 반면 WASM의 보안 경계는 함수 호출 단위 및 메모리 접근 단위로 설정될 수 있습니다. wasm_fuel과 같이

2. Python/TypeScript 대신 Rust 사용

Rust의 생태계 풍부함은 Python에 미치지 못하지만, BoxAgnts가 "고성능 WASM 런타임 (WASM runtime)"과 "보안 에이전트 런타임 (Agent runtime)" 사이의 깊은 통합을 필요로 한다는 점을 고려할 때, Rust의 제로 코스트 추상화 (zero-cost abstractions), 소유권 시스템 (ownership system), 그리고 네이티브 Wasmtime 지원은 결정적인 요소입니다.

구체적인 예로 태스크 간 ToolContext 전달을 들 수 있습니다. Python/TypeScript에서는 공유 상태를 보호하기 위해 일반적으로 락 (locks)이나 딥 카피 (deep copies)가 필요하며, 이러한 모든 보호 조치는 런타임 (runtime) 기반으로 이루어집니다. 반면 Rust에서는 Arc<AtomicUsize>, Arc<CostTracker>와 같이 이러한 공유 상태의 안전성이 컴파일 타임 (compile time)에 검증됩니다. execute() 메서드 시그니처에 있는 &ToolContext는 도구가 공유 컨텍스트를 수정할 수 없음을 보장합니다. 이 보장은 런타임 체크가 아닌 빌려오기 검사기 (borrow checker)로부터 나옵니다.

3. 명시적 설정 대신 자기 기술적 등록 (Self-Describing Registration)

대부분의 도구 시스템은 개발자가 코드나 설정 파일에 도구 스키마 (schema)를 선언하도록 요구합니다. 이는 두 가지 문제를 야기합니다. 첫째, 선언이 실제 동작과 일치하지 않을 수 있습니다 (예: 스키마에는 파라미터 타입이 string이라고 되어 있지만, 코드에서는 number로 처리하는 경우). 둘째, 개발 흐름이 끊깁니다. 코드를 작성한 후 별도의 스키마를 또 작성해야 하기 때문입니다.

BoxAgnts의 접근 방식은 도구의 --help를 직접 실행하고, 그 출력을 파싱하여 스키마를 자동으로 생성하는 것입니다. 도구가 표준 CLI 컨벤션 (clap, cobra, argparse 등의 라이브러리 사용)을 따른다면 추가 작업은 필요하지 않습니다. 스키마와 코드 동작은 동일한 소스에서 파생되므로 결코 서로 어긋날 수 없습니다.

유사 에이전트 도구 시스템과의 비교

이 섹션에서는 수평적 비교를 위해 네 가지 대표적인 에이전트 (Agent) 도구 시스템을 선정합니다: LangChain ("프레임워크" 접근 방식을 대표하는 가장 초기 AI 에이전트 프레임워크), Claude Code (Anthropic의 터미널 에이전트로, "벤더 종속 + 로컬 우선" 접근 방식을 대표), Codex CLI (OpenAI의 오픈 소스 터미널 에이전트로, "클라우드 샌드박스" 접근 방식을 대표), 그리고 OpenClaw (오픈 소스 자율 에이전트 게이트웨이로, "하트비트 기반" 접근 방식을 대표). 다음 표는 개요를 제공하며, 각 시스템에 대한 상세 분석은 아래에 기술합니다.

차원BoxAgntsClaude CodeCodex CLIOpenClawLangChain
언어RustTypeScript/NodeRust (97.6%)TypeScriptPython
...

Claude Code

Anthropic의 Claude Code는 터미널 에이전트 (Agent)의 기준점입니다. 이 시스템은 개발자의 로컬 머신에서 전체 셸 (shell) 권한을 가지고 실행되며, 단일 스레드 메인 루프(내부 코드명 "nO")를 사용하여 도구 호출 (tool calls)을 반복적으로 실행합니다. Claude Code는 2025년 10월에 OS 레벨의 샌드박싱 (sandboxing)을 위해 bubblewrap (Linux) 및 Seatbelt (macOS)를 추가하여, 파일 시스템과 네트워크 격리를 모두 지원합니다.

강점: CLAUDE.md 프로젝트 컨텍스트 (context) 시스템은 에이전트에게 프로젝트 컨벤션 (conventions)에 대한 깊은 이해를 제공합니다. SKILL.md 및 MCP 서버는 강력한 확장성을 제공하며, 서브 에이전트 (sub-agents: Explore, Plan, General-Purpose)는 격리된 컨텍스트를 통해 복잡한 작업을 분할할 수 있습니다.

한계: 샌드박스는 프로세스 레벨의 시스템 콜 (syscall) 가로채기 방식으로 작동하므로, OS 공격 표면 (attack surface)이 여전히 존재합니다. bubblewrap의 seccomp 필터는 근본적으로 블랙리스트 (blacklist) 모델입니다. Claude Code는 Claude 모델에 종속되어 있어 벤더 간 전환이 불가능하며, 폐쇄 소스 CLI로 인해 저수준 커스터마이징 (customization)이 제한됩니다. 도구 실행은 호스트 셸 환경의 실제 상태에 의존하므로, 환경적 차이로 인해 에이전트의 동작이 불안정해질 수 있습니다.

BoxAgnts와의 핵심적인 차이점: Claude Code의 보안 모델은 "모든 것을 허용하되, 위험한 작업만 가로챈다(allow everything, intercept dangerous operations)" 방식입니다. Bubblewrap을 사용하더라도 어떤 디렉토리와 도메인에 접근할 수 있는지 설정함으로써 경계를 정의합니다. 반면, BoxAgnts의 보안 모델은 "기본 거부(default-deny), 명시적으로 주입된 기능만 허용" 방식입니다. WASM(WebAssembly) 컴포넌트가 시작되는 순간부터, 해당 컴포넌트는 open() 함수가 무엇인지조차 알지 못합니다.

Codex CLI

OpenAI의 Codex CLI는 2025년 4월에 출시된 Apache 2.0 오픈 소스 프로젝트로, 코드베이스의 95% 이상이 Rust로 재작성되었습니다. 이는 BoxAgnts와 몇 가지 흥미로운 유사점을 공유합니다. 두 프로젝트 모두 시작 속도와 메모리 효율성을 위해 Rust를 사용하며, 샌드박스 격리(sandbox isolation)를 구현합니다. 하지만 샌드박스 전략 측면에서는 근본적으로 다릅니다.

강점: Codex CLI의 샌드박스는 OS 수준의 프리미티브(macOS Seatbelt, Linux Landlock + seccomp)를 사용하여 로컬 프로세스의 파일 접근 및 네트워크 호출에 대해 강력한 제어력을 제공합니다. Codex Cloud는 원격 컨테이너에서 실행되어 로컬 파일 시스템으로부터 완전히 격리됩니다. Rust로의 재작성을 통해 런타임 의존성이 없는 단일 바이너리를 제공합니다. codex exec 및 GitHub Action 지원을 통해 CI/CD 임베딩이 가능합니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0