qosikz/andbo

GitHub: qosikz/andbo

Andbo 为 AI 编程代理提供隔离、受策略管控的一次性容器沙箱,防止代理泄露密钥或破坏宿主环境。

Stars: 1 | Forks: 1

Andbo — Disposable sandboxes for AI coding agents: secure sandboxing, policy-controlled execution, controlled network egress, secrets protection, auditability & observability

# Andbo

Latest release CI Go version License: Apache-2.0 Signed releases with SBOM and SLSA provenance GHCR runtime image

**为 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 来实现。

A sandboxed agent holds a live API key but cannot leak it — the attacker host is refused at the egress proxy (fail closed), and even when the agent dumps the key into its own output the saved audit record redacts it

``` 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, 安全沙箱, 容器隔离, 开发工具, 日志审计, 程序破解, 网络流量控制, 请求拦截