qosikz/andbo
GitHub: qosikz/andbo
Andbo 为 AI 编程代理提供隔离、受策略管控的一次性容器沙箱,防止代理泄露密钥或破坏宿主环境。
Stars: 1 | Forks: 1
# Andbo
**为 AI 编程 agent 提供的一次性沙箱 —— 并且是一个可以由你的 agent 框架驱动的沙箱。**
Andbo 在隔离、可复现且受策略控制的工作区中运行 AI 编程 agent(Claude Code、Codex、Gemini、Goose、OpenCode,或者
**任何自定义 shell agent**)—— 这样 agent 就可以编辑真实的代码仓库,而无需不受控地访问
你的密钥、网络、宿主机文件系统或 MCP 工具。每次运行都会留下一份
可审计的会话记录。
它支持**双向**工作:将 Andbo 指向一个 agent,**或者**让一个
agent 框架 —— Claude Code、[OpenClaw](#use-andbo-from-your-agent-harness-integration)、
Hermes Agent,或任何兼容 MCP/skill 的框架 —— 将 Andbo 作为其*安全
沙箱*来调用,以测试高风险命令、验证生成的代码,并在信任
新工具或子 agent 之前对其进行审查。可通过 `andbo exec`、MCP server 或
跨框架 skill 来实现。
```
andbo run "fix failing tests"
```
```
Andbo session started
Repository: .
Agent: custom
Runtime: docker
Network: deny
Policy: andbo.yaml
✓ Workspace created
✓ Policy applied
✓ Secrets protected
✓ Agent completed
✓ Diff generated
✓ Session saved
```
## 将 Andbo 添加到你的 agent 框架
在约 30 秒内为你的 agent 提供一个沙箱。[安装 Andbo](#install),然后
将该 skill 放入你使用的框架中 —— 它会教会 agent *何时*使用
沙箱以及*如何*调用 Andbo:
```
andbo skill install --target claude-project
# targets: claude-project | claude-user | openclaw | hermes | agents
```
框架会自动发现 `SKILL.md`。现在 agent 可以在隔离的 container 中
运行任何高风险操作,而不是在你的宿主机上,并读取
退出码、diff 和输出:
```
andbo exec "npm install && npm test" # host untouched; recorded as a session
```
更喜欢结构化工具而不是 shell 调用?改为通过 MCP 暴露 Andbo:
```
claude mcp add andbo -- andbo mcp serve # also: openclaw · codex · gemini
```
适用于 Claude Code、**OpenClaw** (`~/.openclaw/workspace/skills`)、**Hermes
Agent** (`~/.hermes/skills`) 以及任何兼容 agentskills.io 的框架
(`~/.agents/skills`)。不安全的模式永远无法通过 skill 或
MCP server 访问,因此框架无法越权突破你的 `andbo.yaml` 限制。
→ [完整指南](#use-andbo-from-your-agent-harness-integration)。
## 为什么需要
AI 编程 agent 可以阅读代码、运行命令、安装依赖项、打开 PR,并
调用 MCP 工具。如果直接在你的机器上运行,它们可能会泄露 `.env` 文件、SSH
密钥和云凭证,访问任何网络 endpoint,并运行破坏性
命令。Andbo 为它们提供了确定性的防护栏:
- **密钥** — 宿主机环境(包括 `PATH` 和 `HOME`)永远不会被
转发;container 获取的是标准的 `PATH`,`HOME` 设置为工作区,
`LANG`/`TERM`,以及仅显式允许的密钥。类似密钥格式的
值会从日志中进行脱敏处理。
- **文件系统** — 敏感路径(`.env`、`~/.ssh`、`~/.aws`、`~/.kube`、
Docker socket)默认被排除在工作区之外。
- **网络** — 默认拒绝。`allowlist` 在 container
运行时会被**强制执行**:agent 的唯一接口是一个按运行隔离的网络,其唯一的
出口是一个仅限于你 `network.allow` 域名的 egress proxy —— 任何
其他请求都会安全失效,并且每个允许/拒绝决定都会被记录在会话中。`open`
需要明确的不安全确认。
- **运行时** — container 以非 root 用户身份运行,带有 `--cap-drop ALL` 和
`--security-opt no-new-privileges`;从不使用特权模式,也从不使用 Docker socket。
支持 Docker 或 Podman。
- **MCP** — 静态扫描器会在你信任危险的 MCP server 能力之前对其进行标记。
- **审计** — 每次运行都会记录在 `.andbo/sessions/
/` 下。
另一个约 60 秒的演示单独介绍了强制 egress 机制 ——
将一个域名加入白名单,DNS 失效,其他一切都会安全失效,全部被审计。可以通过
[`demo/egress-demo.sh`](demo/egress-demo.sh) 进行记录([所有演示](demo/))。
Andbo 不会奇迹般地让一个不安全的 agent 变得安全。它创建防护栏,并且
对于它执行和不执行的操作非常诚实。
## 安装
**预编译二进制文件:**
从
[GitHub Releases](https://github.com/qosikz/andbo/releases) 下载适合你平台的二进制文件(针对
每个 `v*` 标签发布;`checksums.txt` 包含 SHA-256 校验和),使其可执行,并
将其放在你的 `PATH` 中。
**从源码构建:**
```
git clone https://github.com/qosikz/andbo.git
cd andbo
make build # produces ./bin/andbo with embedded version/commit/date
./bin/andbo version
```
**使用 `go install`:**
```
go install github.com/qosikz/andbo/cmd/andbo@latest
```
从源码构建需要 Go 1.23+。Docker 或 Podman 是可选的,并且仅在
进行真实(非 dry-run)的 container 执行时才需要。
## 快速开始
在你的项目内部(一个 git 仓库 —— 这就是 Andbo 捕获 diff 的方式):
```
# 1. 创建策略和 session 目录
andbo init
# 2. 真正验证 sandbox — 在隔离的 container 中运行。默认
# image 自动拉取;无需 API key,无需构建,host 不受影响。
andbo exec "whoami && uname -m && echo sandboxed > proof.txt"
# 3. 查看确切发生了什么
andbo session show latest
```
第一次运行就是十秒钟内的完整演示。`session show` 会报告:
```
Changed files
proof.txt
Commands
[exit 0] whoami && uname -m && echo sandboxed > proof.txt
Policy events
BLOCKED outbound network access (network=deny)
```
你以**非 root** 用户身份在一个一次性 container 内运行了命令,
网络**默认被拒绝**,更改仅落在一次性副本中
(你的仓库未被改动),并且整个过程都**记录了 diff 和
审计日志** —— 无需任何设置。
```
# 4. 验证/检查策略,规划 agent 运行,扫描 MCP server
andbo policy check
andbo run "fix failing tests" --dry-run # plan only; no Docker needed
andbo mcp scan ./path-to-mcp-server # exit 2 if unsafe
```
`andbo doctor` 会检查你的本地设置(Docker、git、gh、已知 agent)。
### 两种启动方式
- **沙箱机制 —— 现成可用,零设置。** 默认的运行时镜像和
`andbo exec` 证明了其核心:container 隔离、非 root 执行、
网络拒绝、会话记录、密钥脱敏,以及每次
更改的 diff/审计。无需 API key,也无需构建镜像。*(默认的 `run` agent 是一个空操作
`echo`,因此单纯的 `andbo run` 会执行完整的 pipeline 但不进行任何
编辑 —— 这是故意的:第一次运行是安全且免费的。)*
- **由真正的 AI agent 进行编辑 —— 可选的下一步。** 将 `custom`
适配器指向任何 agent CLI(本地模式),或者将 agent 打包到运行时镜像中,
以进行完全 container 化的运行。请参阅
[运行完全 container 化的 agent](#run-an-agent-fully-containerized-baked-in-agents)。
## 工作原理
每次运行都会让 agent 通过一个单向漏斗:你的仓库副本、一个加固的
container,以及一个经过过滤的单一出口。边界内的所有内容都是按
运行创建的,并在之后销毁;唯一的出路是前往你加入白名单的域名(默认
在 80/443 端口上)。
```
Agent harness (Claude Code · OpenClaw · Hermes · any MCP/skill host)
│
│ andbo exec · MCP server · installed skill
▼
┌── policy trust boundary ───────────────────────────────────────────────
│
│ ① Disposable workspace copy-on-run; repo never mounted wholesale
│ │ (.env, ~/.ssh, ~/.aws, Docker socket excluded)
│ ▼
│ ② Container runtime non-root · --cap-drop ALL · no-new-privileges;
│ │ only secrets.allow keys injected, redacted in logs
│ ▼
│ ③ Egress proxy per-run internal network · DNS sunk · fail closed
│ │
└────────────┼───────────────────────────────────────────────────────────
▼
Allowlisted domains only e.g. your model API — everything else denied
```
本地模式(`--runtime local --unsafe`)跳过 container 和 egress proxy:它
转发最小化的环境并在宿主机上运行,而且会明确说明这一点。**Container 模式是
默认模式,也是唯一能强制执行网络边界的模式。**
## 命令
| Command | Description |
|---|---|
| `andbo init` | 创建 `andbo.yaml` 和 `.andbo/` |
| `andbo run ""` | 在隔离、受策略控制的工作区中运行 agent |
| `andbo exec ""` | 在隔离的工作区中运行命令(退出码会传递) |
| `andbo policy check [--json]` | 验证策略;显示有效配置、不安全选项、真实的限制 |
| `andbo mcp scan [--json]` | 静态扫描 MCP server(如果不安全则退出码为 2) |
| `andbo mcp serve` | 通过 MCP (stdio) 向 agent 框架提供沙箱工具 |
| `andbo skill install` | 将 Andbo skill 安装到框架中(Claude Code、OpenClaw、Hermes 等) |
| `andbo session list / show [id] / replay [id]` | 检查记录的会话 |
| `andbo doctor` | 诊断本地设置 |
| `andbo version` | 打印版本 |
大多数命令支持 `--json` 并使用稳定的退出码:成功为 `0`,
策略/不安全阻止为 `2`(例如在危险 server 上执行 `mcp scan`),其他情况为非零
失败码 —— `run`/`exec` 会传递 agent 自身的退出码。
### 有用的 `run` 标志
```
--dry-run Plan only; do not execute the agent (no Docker required)
--agent custom | claude | codex | gemini | goose | opencode
--policy Policy file (default: andbo.yaml)
--network deny|allowlist|open
--engine docker|podman Container engine (default: policy runtime.engine)
--write Add a writable path (repeatable)
--commit Commit the agent's changes on a new branch
--open-pr Open a pull request (requires the gh CLI)
--runtime local --unsafe Run on the host without a container (unsafe)
--yes-unsafe Acknowledge unsafe mode non-interactively (CI)
```
### 示例:真实的 agent (Claude Code)
```
andbo run "fix the failing test" --agent claude --runtime local --yes-unsafe --commit
```
内置适配器:`custom`、`claude`、`codex`、`gemini`、`goose`、`opencode`。
`custom` 适配器可以运行**任何** CLI agent —— 将 `agent.custom.command` 指向
你的二进制文件,Andbo 会将任务替换进 `{{ task }}` 中,因此你永远
不会局限于内置功能。Andbo 在一次性
工作区副本中运行 agent,重新运行你的测试命令,捕获 diff,并(使用
`--commit`)将分支传播回你的仓库。本地模式
仅转发 `PATH`、`HOME`、`USER`、`LOGNAME`、`LANG`、`LC_ALL`、`TERM` 和
明确允许的密钥。对于 container 运行,agent CLI 必须存在于
你的运行时镜像中,并且其 API key 必须在 `secrets.allow` 中获得允许;
keychain/OAuth 登录(如 `claude` 的登录)仅在本地模式下有效。
### 运行完全 container 化的 agent(内置 agent)
这是**可选的下一步**,而不是第一次运行。默认的运行时镜像
已经证明了沙箱机制(请参阅[两种启动方式](#two-ways-to-start));
仅当你希望 AI 在 container *内部*进行编辑时,才将 agent 打包进去。
为此,**将其 CLI 打包进运行时镜像**,并让 Andbo 在
策略下运行它。agent 二进制文件存在于镜像中,而不是
在你的宿主机上 —— Andbo 通过探测镜像来对其进行预检,因此即使你本地从未
安装过该内置 agent,它依然能运行。
```
# 构建一个内置 agent CLI 的 image(示例见 examples/agents/):
docker build -t andbo/codex:latest -f examples/agents/codex.Dockerfile examples/agents
# 在运行时注入 key(切勿内置到 image 中)并运行。
# (示例说明 — Codex 的 auth/sandbox 细节取决于版本;下方的 stub
# 是已验证的路径。`codex exec` 会读取 CODEX_API_KEY。)
export CODEX_API_KEY=sk-...
andbo run "add a test for parseConfig" --policy examples/andbo.codex.yaml
# (无 unsafe flag:强制执行的 allowlist 仅覆盖 api.openai.com)
```
- **API key 永远不会出现在镜像中。** 镜像层是不可变的,并且会
通过 `docker history` / `docker save` / 推送到 registry 泄露内置的密钥。
Andbo 从你的宿主机环境中读取 key,仅当
`secrets.allow` 列出它(且 `secrets.deny` 未列出)时才将其注入 container,并将其
值从日志、diff 和会话元数据中脱敏。
- **网络:** 真正的 agent 通过**强制白名单**
访问其模型 API —— 将 `network.mode` 设置为 `allowlist` 以及你的提供商的域名
(例如 `api.openai.com`),agent 就只能调用该 API 而无法访问其他内容。
无需不安全确认;不再需要 `network: open`。
注意事项(诚实说明):默认情况下,只有 80/443 端口可以出站,因此像 SSH 这样的非 HTTP 协议
无法退出(安全失效)—— 尽管你可以使用
`network.ports` 放宽此限制(这允许向你加入白名单的 host:port 进行任意的 TCP 连接);
本地(`--runtime local`)运行完全没有网络强制限制;强制限制需要
已发布二进制文件中内置的 egress proxy(`andbo doctor` 会显示
`egress-proxy`)。
使用捆绑的 **stub agent** 免费验证整个路径 —— 无需 key,无需
网络,无需花费:
```
docker build -t andbo/stub-agent:latest -f examples/agents/stub.Dockerfile examples/agents
ANDBO_FAKE_API_KEY=dummy-not-a-real-key \
andbo run "prove the path" --policy examples/andbo.stub.yaml
```
stub 确认注入的 key 已到达 container 并写入一个文件;
保存的会话将虚拟 key 仅显示为 `[REDACTED:ANDBO_FAKE_API_KEY]`。
完整指南请参见 [examples/agents/README.md](examples/agents/README.md)。
## 通过你的 agent 使用 Andbo(框架集成)
这是 Andbo 大放异彩的地方。你机器上的 agent 框架 —— **Claude
Code、OpenClaw、Hermes Agent**、Codex CLI、Gemini CLI、Goose、OpenCode,或者
任何支持 MCP 或读取 markdown skill 的工具 —— 都可以将 Andbo 作为其
**安全沙箱**调用。框架*本身就是* agent;Andbo 是无论它想尝试什么
都能提供保护的防爆盾:
- 在真实的Workspace中信任**新的子 agent 或工具之前进行测试**。
- **运行生成的代码 / 高风险命令**(迁移、安装、`rm`)并读取
退出码、diff 和输出 —— 而无需触碰宿主机。
- 在接入 MCP server **之前审查其**危险能力。
每个实验都是隔离的、受策略控制的、经过密钥脱敏的,并且被记录
为可审计的会话。无法这些
接口访问不安全的模式,因此框架永远无法越权突破你的 `andbo.yaml`。可通过以下三种方式
进行接入:
**1. 沙箱原语** — `andbo exec` 在隔离的
工作区中运行任何命令,并传递该命令的退出码:
```
andbo exec "go test ./..." --json # exit_code, stdout, changed_files, session_dir
andbo exec --dry-run "rm -rf build" # preview the sandbox without executing
```
**2. Skill** — 教你的框架何时使用沙箱:
```
andbo skill install --target claude-project # ./.claude/skills/ (this repo)
andbo skill install --target openclaw # ~/.openclaw/workspace/skills/
andbo skill install --target hermes # ~/.hermes/skills/
andbo skill install --target agents # ~/.agents/skills/ (cross-agent standard)
```
**3. MCP server** — 为任何兼容 MCP 的框架提供结构化工具(`sandbox_exec`、`sandbox_run`、
`scan_mcp`、`session_list`、`session_show`):
```
claude mcp add andbo -- andbo mcp serve
openclaw mcp add andbo --command andbo --arg mcp --arg serve
codex mcp add andbo -- andbo mcp serve
gemini mcp add andbo andbo mcp serve
```
## 实践方案
分步指南位于 [`recipes/`](recipes/) 中 —— 每一个都由
上述功能构建而成,没有引入新概念:
| Recipe | What it does |
|--------|--------------|
| [**安全的 Claude Code 工作流**](recipes/claude-code.md) | 将 Claude Code 作为 agent 运行(本地 OAuth),将更改落在一个分支上,并记录。 |
| [**Container 化的 Codex agent**](recipes/codex-container.md) | 将 agent 打包进镜像;在运行时注入 key;egress 加入白名单。 |
| [**MCP server 隔离**](recipes/mcp-quarantine.md) | 在你信任工具之前,`andbo mcp scan` 会标记危险的 MCP 能力(退出码 2)。 |
| [**针对不受信任 PR 的 CI dry-run**](recipes/github-actions-untrusted-pr.md) | 在不执行和不使用写入 token 的情况下规划 fork PR。 |
| **针对模型 API 的 egress 白名单** | `network.mode: allowlist` + 你的提供商域名 —— agent 只能访问其 API 而无法访问其他内容。参见 [工作原理](#how-it-works) · [`examples/andbo.codex.yaml`](examples/andbo.codex.yaml)。 |
## 策略
`andbo init` 会写入一个带有注释并拥有安全默认配置的 `andbo.yaml`。请参阅
[示例](examples/)(`andbo.yaml`、`andbo.strict.yaml`),并运行
`andbo policy check` 以查看有效的配置。
关键规则:拒绝优先于允许;除非你通过明确的不安全标志
选择加入,否则敏感路径总是被拒绝;网络默认为 `deny`;除非在
`secrets.allow` 中指名,否则不会传递任何密钥。
一些值得了解的运行时调节项:
- `runtime.engine: docker | podman` 选择 container 引擎(或者在
每次运行时使用 `--engine`)。
- `budget.max_runtime_minutes` 在真实运行时作为硬性截止时间执行 ——
agent 会在到期时停止(dry-run 不受影响)。
- `runtime.cleanup` 会被执行:一次性工作区副本将在
运行后被移除;设置 `cleanup: false` 以便在调试时保留它。`.andbo/sessions/` 下的会话工件
会被永久保留。
## 运行时镜像
真实的 container 运行会在 container 镜像(Docker 或
Podman)内执行 agent。默认策略引用了已发布的、多架构的
`ghcr.io/qosikz/andbo/runtime:latest`,Docker/Podman 会在首次运行时**自动
拉取**该镜像 —— 因此 `andbo run` 开箱即用,无需
构建任何镜像。该镜像是一个带有 `ca-certificates` 和
`git` 的最小化 Debian 基础环境,以非 root 用户身份运行;它已签名并具有 SLSA 构建来源(请参阅
[验证发布版本](#verifying-releases))。
需要额外的工具链(node、python、go、你的测试依赖项)?从
示例构建你自己的镜像,并将你的策略指向它:
```
docker build -t my/andbo-runtime:latest -f examples/runtime.Dockerfile examples/
# 然后在 andbo.yaml 中设置 runtime.image: my/andbo-runtime:latest
andbo run "fix tests"
```
根本不想运行 container?使用 `--dry-run`(受支持的预览
路径)或 `--runtime local --unsafe` 在宿主机上运行。
## 会话
每次运行都会记录在 `.andbo/sessions//` 下:
```
session.json report.md logs.txt diff.patch
policy-events.json test-results.txt metadata.json
```
日志和报告在写入之前会经过密钥脱敏处理。
## GitHub Action
一个复合 action 位于 [`.github/actions/andbo`](.github/actions/andbo);
一个安全的示例工作流位于
[`examples/github-action-andbo.yml`](examples/github-action-andbo.yml) 中。
该示例默认使用 `--dry-run` 并将会话作为 artifact 上传。对于 fork
pull request,请保持 dry-run 状态,并避免暴露写入 token。
## 安全
请参阅 [SECURITY.md](SECURITY.md)。安全验收测试位于
`internal/cli/security_test.go` 中。
## 验证发布版本
发布工件由固定的 GitHub Actions 工作流构建,并使用
[Sigstore](https://www.sigstore.dev/) 无密钥签名进行签名 —— 没有长期有效的密钥,
签名身份就是工作流本身。每个版本都带有 SPDX **SBOM**
(`andbo.spdx.json`) 和 **SLSA 构建来源**证明。
验证二进制文件(签名覆盖了 `checksums.txt`,后者通过 SHA-256 覆盖了每个
二进制文件):
```
# 1. checksums 由 release workflow 签名(无密钥 / Sigstore)。
# bundle 包含 signature、certificate 和 transparency-log 条目。
cosign verify-blob \
--bundle checksums.txt.cosign.bundle \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp '^https://github.com/qosikz/andbo/\.github/workflows/release\.yml@' \
checksums.txt
# 2. 你下载的 binary 与已签名的 checksum 匹配
shasum -a 256 -c checksums.txt --ignore-missing
# 3. (替代方案)GitHub 原生构建来源
gh attestation verify andbo_linux_amd64 --repo qosikz/andbo
```
验证运行时镜像(通过摘要签名,来源被推送到 GHCR):
```
cosign verify ghcr.io/qosikz/andbo/runtime:latest \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp '^https://github.com/qosikz/andbo/\.github/workflows/publish-image\.yml@'
gh attestation verify oci://ghcr.io/qosikz/andbo/runtime:latest --repo qosikz/andbo
```
## MVP 限制(诚实说明)
- `network: allowlist` 仅针对 **container** 运行强制执行 —— egress
proxy 默认允许端口 80/443(设置 `network.ports` 以允许其他端口,
这会将 egress 扩展到向你加入白名单的 host:port 进行任意 TCP 连接);
其他所有情况都会安全失效。本地运行完全没有网络强制限制。
DNS 隧道在结构上是封闭的 —— agent 的 DNS 被下沉处理
(`--dns 0.0.0.0`) 并且 proxy 会解析白名单中的名称 —— 因此它不
依赖于 Docker 版本的内部网络 DNS 行为。
- `commands.deny` 是尽力而为的,无法阻止通过间接方式生成 shell 的 agent。
- `budget` token/USD 上限取决于适配器支持,否则将报告为 `unknown`
(`max_runtime_minutes` 会被强制执行)。
- 已发布的默认运行时镜像是最小化基础(Debian + `git` +
`ca-certificates`);需要其他工具链的 agent 需要自定义镜像。
- 密钥脱敏是尽力而为的,可能会漏掉未知的格式。
## 开发
```
make fmt
make lint
make test
make build
```
## 许可证
[Apache-2.0](LICENSE)。标签:AI编程代理, EVTX分析, Go语言, SOC Prime, 安全沙箱, 容器隔离, 开发工具, 日志审计, 程序破解, 网络流量控制, 请求拦截