샌드박스 처리된 코드 실행

adk-sandbox 크레이트는 ADK 에이전트를 위한 격리된 코드 실행을 제공하며, 두 가지 격리 수준을 지원합니다.

  1. 프로세스 격리 — 환경 격리 및 시간 초과 적용을 사용하는 자식 프로세스
  2. OS 수준 샌드박스 프로필 — 파일 시스템, 네트워크 및 프로세스 생성을 제한하는 커널 수준의 제약

백엔드

백엔드격리 수준언어기능 플래그
ProcessBackend환경 + 시간 제한Rust, Python, JS, TS, Commandprocess (기본값)
ProcessBackend + 샌드박스커널 수준위와 동일process + sandbox-native
WasmBackend전체 (메모리, 파일 시스템, 네트워크)WASM만wasm

어떤 격리를 사용하고 있나요?

ProcessBackend::isolation()이 이를 보고하므로, 크레이트 이름만으로 추론할 수 있는 내용이 아닙니다:

결과의미
IsolationClass::SubprocessOnly환경이 초기화되고, 시간 제한과 자체 프로세스 그룹이 설정된 자식 프로세스입니다. OS는 추가 제한을 적용하지 않으므로 코드가 호스트 파일 시스템을 읽고 네트워크에 연결할 수 있습니다. 이것이 ProcessBackend::default()이 제공하는 기능입니다.
IsolationClass::OsEnforced강제 적용기 정책이 연결되어 있으므로 OS가 자식 프로세스를 제한합니다.

프로세스 백엔드와 관련해 알아 두어야 할 두 가지 사항:

  • 환경이 삭제되기 전에 프로그램이 확인됩니다. 이름만 지정된 python3, node 또는 rustc은 호출자의 PATH에서 조회되어 자식 프로세스에 절대 경로로 전달됩니다. 따라서 자식 프로세스는 시작할 때 자체 PATH가 필요하지 않습니다. 이전에는 호출자가 PATHExecRequest::env에 넣어야 했으며, 이로 인해 실행된 코드가 그 경로에 있는 다른 어떤 것이든 생성할 수 있었습니다.
  • 컴파일은 실행과 동일한 경계를 거칩니다. Rust 소스는 이전에 공유 경로 외부에서 빌드된 명령으로 컴파일되었으므로, 컴파일에는 enforcer 래퍼, 시간 제한, 프로세스 그룹이 없었습니다. 이는 컴파일이 무해한 작업이 아니기 때문에 중요합니다. include_str!은 파일을 읽고, procedural macro는 생성된 바이너리가 존재하기 전에 임의의 코드를 실행합니다. 컴파일 단계에는 플랫폼별 도구 모음 허용 목록이 적용됩니다. Windows에서는 호출자가 이미 Developer 셸에 있지 않은 경우 설치된 도구 모음에서 검색한 MSVC 및 Windows SDK 경로가 여기에 포함됩니다. 컴파일에는 Rust 도구 모음의 rust-lld linker가 사용되므로 PATH에서 더 앞에 있는 관련 없는 link.exe을 선택할 수 없습니다. 이 단계를 제한하는 것은 OS enforcer입니다.

환경 우선순위

SandboxPolicy::env은 모든 실행에 대한 기본값을 제공하고 ExecRequest::env은 호출별로 이를 재정의합니다. 이전에는 정책의 변수가 완전히 무시되었습니다.

OS 샌드박스 프로필

OS 수준의 샌드박스 적용은 커널 수준에서 자식 프로세스를 제한합니다. 이는 환경 격리를 넘어서는 기능으로, OS 자체가 승인되지 않은 파일 시스템 액세스, 네트워크 연결 및 프로세스 생성을 차단합니다.

플랫폼 지원

플랫폼적용 도구작동 방식
macOSSeatbelt (sandbox-exec)시스템 호출 수준 규칙: "기본적으로 허용하고 위험한 작업은 거부" — 쓰기, 네트워크 및 fork를 거부하며 읽기는 제한되지 않음
Linuxbubblewrap (bwrap)파일 시스템 네임스페이스 격리(허용 목록 마운트)
WindowsAppContainer구현되지 않음 — enforcer가 사용할 수 없다고 보고함

빠른 시작

use adk_sandbox::{
    ProcessBackend, ProcessConfig, SandboxBackend,
    SandboxPolicyBuilder, get_enforcer,
};

// 1. Define what the sandboxed process can do
let policy = SandboxPolicyBuilder::new()
    .allow_read("/usr")           // Read system libraries
    .allow_read_write("/tmp/work") // Write to work directory
    .allow_process_spawn()         // Python needs to exec
    // Network is denied by default
    .env("PATH", "/usr/bin:/usr/local/bin")
    .build();

// 2. Get the platform-appropriate enforcer
let enforcer = get_enforcer()?;

// 3. Create a sandboxed backend
let backend = ProcessBackend::with_sandbox(
    ProcessConfig::default(),
    enforcer,
    policy,
);

// 4. Execute code — network is blocked, writes restricted
let result = backend.execute(request).await?;

기능 플래그

[dependencies]
# Auto-detect platform enforcer
adk-sandbox = { version = "2.1.0", features = ["process", "sandbox-native"] }

# Or pick a specific platform
adk-sandbox = { version = "2.1.0", features = ["process", "sandbox-macos"] }
adk-sandbox = { version = "2.1.0", features = ["process", "sandbox-linux"] }

SandboxPolicy

정책은 샌드박스 처리된 프로세스가 수행할 수 있는 작업을 정의합니다:

필드기본값설명
allowed_paths[] (모두 거부)읽기 전용 또는 읽기-쓰기 액세스가 허용된 파일 시스템 경로
allow_networkfalse네트워크 액세스 허용 여부
allow_process_spawnfalse자식 프로세스 생성을 허용할지 여부
env{}샌드박스 처리된 프로세스의 환경 변수

플랫폼 차이

macOS (Seatbelt): "기본적으로 허용하고 위험한 작업은 거부" 방식을 사용합니다. 전체 액세스로 시작한 다음 네트워크, 파일 쓰기 및 프로세스 생성을 차단합니다. Python은 시작 시 수십 개의 macOS별 syscall 카테고리를 필요로 하므로, 순수한 허용 목록 방식은 작동하지 않습니다.

Linux (bubblewrap): 네임스페이스 기반 허용 목록을 사용합니다. 기본적으로 아무것도 존재하지 않으며, 필요한 항목만 마운트합니다. apt install bubblewrap 또는 dnf install bubblewrap을 사용하여 설치합니다.

Windows (AppContainer): 구현되지 않았습니다. 설계는 토큰 기반 ACL입니다. 기본적으로 액세스 권한이 없는 제한된 SID를 사용한 다음 특정 경로에 ACL을 부여합니다. 하지만 컨테이너 생성, ACL, 기능 및 작업 개체 정리가 구현되어 있지 않으므로 probe()은(는) EnforcerUnavailable을 반환합니다. Windows에서는 강제 적용기 없이 실행하거나, 실제 강제 적용이 가능한 macOS 또는 Linux를 사용하세요.

예시

OS 커널에 의해 네트워크 액세스가 차단된 샌드박스 환경에서 Python 코드를 실행하는 전체 LLM-에이전트 기반 예시는 examples/sandbox_agent/를 참조하세요.