沙箱代码执行

adk-sandbox crate 为 ADK agent 提供隔离的代码执行环境,具有两个级别的隔离:

  1. 进程隔离 — 具有环境隔离和超时强制执行功能的子进程
  2. 操作系统级沙箱配置文件 — 对文件系统、网络和进程生成施加内核级限制

后端

后端隔离级别语言功能标志
ProcessBackend环境 + 超时Rust、Python、JS、TS、命令process(默认)
ProcessBackend + sandbox内核级别同上process + sandbox-native
WasmBackend完整(内存、文件系统、网络)仅 WASMwasm

你使用的是哪种隔离?

ProcessBackend::isolation() 会报告该信息,因此不能从 crate 名称推断这一点:

结果含义
IsolationClass::SubprocessOnly一个环境已清除、具有超时设置并拥有自己的进程组的子进程。操作系统不施加任何进一步限制:代码可以读取主机文件系统并访问网络。这就是 ProcessBackend::default() 为你提供的内容。
IsolationClass::OsEnforced已附加执行器策略,因此操作系统会限制该子进程。

了解进程后端时,有两点值得注意:

  • 环境清除前会解析程序。 系统会在调用方的 PATH 中查找裸 python3noderustc,并将其作为绝对路径传递给子进程。这意味着子进程启动时不需要自己的 PATH —— 过去调用方必须将 PATH 放入 ExecRequest::env,这也使执行的代码能够在其中生成其他任意内容。
  • 编译与执行经过相同的边界。 过去,Rust 源代码由在共享路径之外构建的命令进行编译,因此编译过程没有强制执行器包装器、超时机制或进程组。这一点很重要,因为编译并非无副作用:include_str! 会读取文件,而过程宏会在生成的二进制文件存在之前运行任意代码。编译阶段会接收特定于平台的工具链允许列表;在 Windows 上,如果调用方尚未处于 Developer shell 中,该列表还包括从已安装工具链中发现的 MSVC 和 Windows SDK 路径。编译使用 Rust 工具链的 rust-lld 链接器,因此不会选择 PATH 中较早出现的无关 link.exe。OS 强制执行器负责限制这一阶段。

环境优先级

SandboxPolicy::env 为每次执行提供默认值,而 ExecRequest::env 按调用覆盖这些默认值。此前,策略中的变量会被完全忽略。

OS 沙箱配置

OS 级沙箱强制执行会在内核层面限制子进程。这超出了环境隔离的范畴——OS 本身会阻止未经授权的文件系统访问、网络连接和进程生成。

平台支持

平台强制执行器工作原理
macOSSeatbelt (sandbox-exec)系统调用级规则:“默认允许,拒绝危险操作”——拒绝写入、网络和 fork;读取不受限制
Linuxbubblewrap (bwrap)文件系统命名空间隔离(白名单挂载)
WindowsAppContainer未实现 — 强制器报告自身不可用

快速开始

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 特有的系统调用类别。

**Linux(bubblewrap):**采用基于命名空间的白名单方式——默认情况下不存在任何内容,仅挂载所需内容。使用 apt install bubblewrapdnf install bubblewrap 安装。

**Windows(AppContainer):**尚未实现。其设计基于令牌 ACL——使用默认无访问权限的受限 SID,然后针对特定路径授予 ACL——但容器创建、ACL、功能以及作业对象清理均未实现,因此 probe() 返回 EnforcerUnavailable。在 Windows 上运行时不使用强制器,或使用 macOS 或 Linux,在这些系统上强制执行功能可用。

示例

请参阅 examples/sandbox_agent/,了解完整的 LLM 驱动示例,该示例在沙箱环境中执行 Python 代码,并由操作系统内核阻止网络访问。