stacklok/brood-box
GitHub: stacklok/brood-box
Brood Box 是一款在硬件隔离的 microVM 中运行 AI coding agent 的 CLI 工具,通过写时复制快照和逐文件审查机制保护开发者的工作区安全。
Stars: 43 | Forks: 9
# Brood Box
在硬件隔离的 microVM 中运行 coding agent。在每一次更改触及您的工作区之前进行审查。
[](LICENSE)
[](https://github.com/stacklok/brood-box/actions/workflows/ci.yaml)
[](https://goreportcard.com/report/github.com/stacklok/brood-box)
[](https://www.repostatus.org/#experimental)
## 目录
- [为什么?](#why)
- [功能](#features)
- [快速开始](#quick-start)
- [用法](#usage)
- [配置](#configuration)
- [Egress 防火墙](#egress-firewall)
- [支持的 Agent](#supported-agents)
- [工作原理](#how-it-works)
- [安全模型](#security-model)
- [文档](#documentation)
- [从源码构建](#building-from-source)
- [贡献](#contributing)
- [License](#license)
## 为什么?
Coding agent 非常强大,但它们需要访问您的工作区、您的 API key,以及执行任意代码的能力。这需要交付极大的信任。
容器能起到一定作用,但它们共享主机内核。只要一次逃逸,您就全盘皆输。
于是 **Brood Box** 应运而生。它通过 [libkrun](https://github.com/containers/libkrun) 和 KVM 启动轻量级的 microVM,挂载您工作区的写时复制 (COW) 快照,仅转发您指定的 secret,并允许您在每项文件更改落地前进行审查。硬件隔离,同时具备本地终端般的体验。
```
bbox claude-code
```
就这样。您将获得一个在 VM 中运行 Claude Code 的完整交互式会话。当 agent 退出时,您可以审查 diff 并接受或拒绝每个文件。
## 功能
- **硬件隔离的 microVM** -- 通过 libkrun 支持 KVM (Linux) 和 Hypervisor.framework (macOS) 作为底层 VM,而不仅仅是容器
- **工作区快照与审查** -- COW 快照确保 agent 绝不触碰您的真实文件;完成后提供带有 unified diff 的交互式单文件审查
- **多 agent 支持** -- 开箱即用支持 Claude Code、Codex 和 OpenCode,并可通过配置支持自定义 agent
- **感知 DNS 的 egress 防火墙** -- 三种配置文件(permissive、standard、locked)控制 VM 可以访问的范围
- **MCP 工具代理** -- 自动发现 [ToolHive](https://github.com/stacklok/toolhive) MCP server 并将其代理到 VM 中
- **Git 集成** -- 转发 token 和 SSH agent 以便在 VM 内执行 git 操作
- **临时安全** -- 每个会话使用独立的 SSH key,仅限 localhost 连接,针对敏感文件设有不可覆盖的安全模式
- **零持久状态** -- 每个会话都是完全临时的;清理后不会残留任何数据
## 快速开始
### 前置条件
- 支持 KVM 的 Linux(必须能访问 `/dev/kvm`),或支持 Hypervisor.framework 的 macOS (Apple Silicon)
- [Go 1.26+](https://go.dev/dl/)
- [Task](https://taskfile.dev/) (任务运行器)
- [GitHub CLI (`gh`)](https://cli.github.com/)(用于下载预构建的 runtime artifact)
- 您的 agent 所需的 API key(例如 Claude Code 的 `ANTHROPIC_API_KEY`)
### 从 Release 安装
从 [GitHub Releases](https://github.com/stacklok/brood-box/releases) 下载预构建的二进制文件:
```
# Linux amd64 示例
tar xzf bbox-linux-amd64.tar.gz
sudo mv bbox /usr/local/bin/
```
Release 二进制文件是独立的,不需要 `libkrun-devel` 或任何系统库。
### 从源码构建
```
task build
```
这将下载预构建的 go-microvm runtime artifact,并将它们嵌入到独立的 `bbox` 二进制文件中(纯 Go,无 CGO)。不需要系统级的 `libkrun-devel`。二进制文件位于 `bin/` 目录下。
固件 (`libkrunfw`) 未被嵌入。它会在运行时下载并缓存在 `~/.cache/broodbox/firmware/` 下,如果下载不可用,则有系统回退机制。
### 运行
```
export ANTHROPIC_API_KEY="sk-ant-..."
bbox claude-code
```
工作流程:
1. 创建当前目录的 COW 快照
2. 使用 Claude Code 镜像启动 microVM
3. 将您带入交互式终端会话
4. 当您退出时,显示单文件 diff 审查
5. 接受的更改将被回写到您的工作区
## 用法
```
# 使用特定 agent 运行
bbox claude-code
bbox codex
bbox opencode
bbox gemini
# 覆盖资源
bbox claude-code --cpus 4 --memory 4096
# 使用不同的 workspace
bbox claude-code --workspace /path/to/project
# 启用逐文件交互式审查(仅限 snapshot 模式)
bbox claude-code --review
# 从 snapshot 中排除文件
bbox claude-code --exclude "*.log" --exclude "tmp/"
# 完全跳过 snapshot 隔离:agent 直接写入你的 workspace
# (无审查,无撤销)。首次运行需要 --yes。
bbox claude-code --workspace-mode=direct --yes
# 将 egress 锁定为仅限 LLM provider
bbox claude-code --egress-profile locked
# 允许额外的 egress 主机(仅限 DNS 主机名,不支持 IP 地址)
bbox claude-code --allow-host "internal-api.example.com:443"
# 禁用 MCP proxy
bbox claude-code --no-mcp
# 禁用固件下载(仅使用系统 libkrunfw)
bbox claude-code --no-firmware-download
# 为 MCP servers 使用特定的 ToolHive group
bbox claude-code --mcp-group "coding-tools"
# 传递特定于 agent 的参数(在 -- 之后)
bbox claude-code -- --help
# 列出可用的 agent
bbox list
```
### 工作区模式
默认情况下,bbox 会在您工作区的写时复制 (COW) 快照上运行 agent,并在 agent 退出时将更改回写。没有经过 diff 引擎的任何写入都不会落入您的真实文件中。添加 `--review` 可交互式地批准每个文件。
对于快速的、受信任的编辑(此时您正在逐步引导 agent,且快照的开销并不划算),请传入 `--workspace-mode=direct`。VM 将以读写方式挂载您的工作区,写入操作会立即生效。在 direct 模式下,`--review` 和 `--exclude` 会被拒绝(它们仅适用于快照),并且会跳过 git 凭据脱敏。工作区级别的 `.broodbox.yaml` 无法启用 direct 模式;只有操作者才能全局或通过 CLI 启用,并且首次使用时必须提供 `--yes`。当您本来就信任 agent 可以使用非沙盒化的 shell 时,请使用 direct 模式。否则,请保持使用 snapshot 模式(默认)。
## 配置
Brood Box 使用三级配置系统:CLI flag > 工作区级别 > 全局级别。CLI flag 始终具有最高优先级。
### 全局配置
`~/.config/broodbox/config.yaml`:
```
defaults:
cpus: 4
memory: 4096
egress_profile: "permissive"
workspace:
mode: "snapshot" # snapshot (default) or direct
review:
enabled: true
exclude_patterns:
- "*.log"
- "build/"
mcp:
enabled: true
group: "default"
port: 4483
session_ttl: "12h" # idle eviction timeout for host MCP sessions
git:
forward_token: true
forward_ssh_agent: true
runtime:
firmware_download: true
agents:
claude-code:
env_forward:
- ANTHROPIC_API_KEY
- CLAUDE_*
- GITHUB_TOKEN
```
### 工作区级别配置
位于项目根目录的 `.broodbox.yaml`:
```
defaults:
cpus: 8
memory: 8192
review:
exclude_patterns:
- "data/"
```
请注意,出于安全考虑,在工作区级别配置中 `review.enabled` 会被**忽略**。不受信任的 repo 无法代表您禁用审查。
来自工作区级别配置的 `workspace.mode: direct` 也会被忽略。不受信任的 repo 无法关闭快照隔离。但允许在 `.broodbox.yaml` 中设置 `workspace.mode: snapshot`(仅收紧:即使全局配置启用了 direct,repo 也可以强制要求使用 snapshot)。
同样地,工作区级别配置中的 `egress_profile` 无法放宽全局配置文件的策略。
### 排除模式
位于项目根目录的 `.broodboxignore` 使用 gitignore 语法:
```
# 排除构建产物
build/
dist/
# 但包含 config
!dist/config.json
```
安全敏感模式(`.env*`、`*.pem`、`.ssh/`、`.aws/` 等)**始终被排除**,且不能被反向覆盖。
## Egress 防火墙
每个 agent 都带有感知 DNS 的 egress 策略。提供三种配置文件:
| 配置文件 | 允许的操作 |
|---|---|
| `permissive`(默认) | 所有出站流量,无限制 |
| `standard` | LLM provider + 常见开发基础设施(GitHub、npm、PyPI、Go proxy、Docker Hub、GHCR) |
| `locked` | 仅限 LLM provider(例如 Claude Code 的 `api.anthropic.com`) |
```
# 将其锁定
bbox claude-code --egress-profile locked
# 或者将其开放
bbox claude-code --egress-profile permissive
# 向标准 profile 添加特定主机(仅限 DNS 主机名,不支持 IP 地址)
bbox claude-code --allow-host "my-registry.example.com:443"
```
## 支持的 Agent
| Agent | 命令 | 镜像 | 默认资源 |
|---|---|---|---|
| Claude Code | `bbox claude-code` | `ghcr.io/stacklok/brood-box/claude-code` | 2 vCPUs, 4 GiB RAM |
| Codex | `bbox codex` | `ghcr.io/stacklok/brood-box/codex` | 2 vCPUs, 4 GiB RAM |
| OpenCode | `bbox opencode` | `ghcr.io/stacklok/brood-box/opencode` | 2 vCPUs, 4 GiB RAM |
| Hermes | `bbox hermes` | `ghcr.io/stacklok/brood-box/hermes` | 2 vCPUs, 4 GiB RAM |
| Gemini CLI | `bbox gemini` | `ghcr.io/stacklok/brood-box/gemini` | 2 vCPUs, 4 GiB RAM |
您也可以在配置中定义自定义 agent:
```
agents:
my-agent:
image: "ghcr.io/my-org/my-agent:latest"
command: ["my-agent-binary"]
cpus: 4
memory: 4096
env_forward:
- MY_API_KEY
- MY_AGENT_*
```
## 工作原理
```
bbox claude-code
│
▼
Create COW snapshot of workspace
│
▼
Pull OCI image, extract rootfs, inject init binary + SSH keys
│
▼
Boot microVM (libkrun/KVM) with virtio-fs workspace mount
│
▼
Guest boots (bbox-init as PID 1):
→ Mount filesystems, configure networking
→ Start embedded SSH server
→ Wait for connection
│
▼
Interactive SSH session:
source /etc/sandbox-env && cd /workspace && exec claude
│
▼
Agent exits → VM stopped
│
▼
SHA-256 diff → Interactive per-file review → Flush accepted changes
│
▼
Cleanup snapshot
```
客户机 VM 运行一个自定义的 Go init 二进制文件 (`bbox-init`) 作为 PID 1。没有 shell 脚本,没有外部的 sshd,也没有 iproute2。客户机所需的一切都被编译进一个单一的二进制文件中,负责处理启动、网络连接、工作区挂载以及内嵌的 SSH server。
工作区快照在 Linux 上使用 FICLONE,在 macOS 上使用 `clonefile(2)`,实现近乎瞬时的写时复制克隆。
当 agent 完成工作时,基于 SHA-256 的差异检测器会发现更改,并且审查 UI 会为每个文件显示 unified diff。接受的更改在回写时会再次进行哈希重新验证,以防止 TOCTOU 攻击。VM 会在审查开始前被显式停止,因此 agent 无法在您审查期间修改文件。
## 安全模型
Brood Box 的隔离建立在多个层级之上:
- **KVM 硬件虚拟化** -- Agent 在真正的 VM 中运行,而不是在共享内核的容器中
- **临时 SSH key** -- 每次会话生成 ECDSA P-256 key,退出时销毁
- **仅限 Localhost 的网络** -- SSH 端口转发仅绑定到 127.0.0.1
- **不可覆盖的安全模式** -- 诸如 `.env`、`*.pem`、`.ssh/`、`.aws/` 等文件始终被排除在快照之外,即使 `.broodboxignore` 试图取消排除它们也无济于事
- **Shell 转义的环境变量注入** -- 所有转发的值都经过单引号转义处理
- **审查前停止 VM** -- 防止 agent 在您审查时修改文件
- **回写时的哈希验证** -- 文件在 diff 和回写之间会重新进行哈希计算,以捕获任何修改
- **权限剥离** -- 回写更改时会剥离 setuid、setgid 和 sticky bit
- **路径遍历保护** -- 复制前会在边界内验证 symlink
- **工作区级别配置限制** -- `.broodbox.yaml` 中的 `review.enabled` 和 egress 扩展将被忽略
## 文档
详细的文档位于 [`docs/`](docs/) 目录中:
| 文档 | 描述 |
|----------|-------------|
| [用户指南](docs/USER_GUIDE.md) | 完整的 CLI 参考、配置、快照隔离、egress 防火墙、MCP 代理和故障排除 |
| [架构](docs/ARCHITECTURE.md) | DDD 分层、依赖注入、VM 生命周期、客户机环境和安全模型 |
| [开发指南](docs/DEVELOPMENT.md) | 前置条件、task 命令、添加 agent、编写测试和代码约定 |
| [macOS 支持](docs/MACOS.md) | Apple Silicon 设置、使用 Homebrew libkrun 构建以及针对 macOS 的故障排除 |
## 从源码构建
```
# 构建独立 bbox(下载并嵌入 go-microvm runtime)
task build
# 从系统 libkrun 构建 bbox + go-microvm-runner(需要 libkrun-devel)
task build-dev-system
# 构建 guest init 二进制文件
task build-init
# 运行测试
task test
# Lint
task lint
# 格式化 + lint + 测试
task verify
# 构建 guest VM 镜像(需要 docker 或 podman)
task image-all
```
始终使用 `task` 进行构建、测试和 linting。Taskfile 设置了关键的 flag、ldflags 和环境变量,这些是原生 `go` 命令所遗漏的。
请参阅[开发指南](docs/DEVELOPMENT.md)获取完整的命令参考。
## 许可证
[Apache-2.0](LICENSE)
Copyright 2025 [Stacklok, Inc.](https://stacklok.com)
标签:AI编程助手, EVTX分析, SOC Prime, 代码安全审计, 内存分配, 容器隔离, 开发工具, 微虚拟机, 日志审计, 沙箱环境