clawkwork/clawk

GitHub: clawkwork/clawk

clawk 为 AI 编码 agent 提供一次性、网络隔离的 Linux 虚拟机沙箱,让 agent 在安全隔离的环境中全速执行开发任务而不影响宿主机。

Stars: 767 | Forks: 25

clawk *给编码 agent 它自己的一次性 Linux 机器,而不是你的。* [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/99/993938d8ce5e902ccfb9d6747725c320d855dea3235ed9a304cedf0d94c9321f.svg)](https://github.com/clawkwork/clawk/actions/workflows/ci.yml) [![License: Apache 2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) [![Go 1.26+](https://img.shields.io/badge/Go-1.26%2B-00ADD8?logo=go&logoColor=white)](go.mod) ![Platform: macOS · Linux (experimental)](https://img.shields.io/badge/platform-macOS%20%C2%B7%20Linux%20(experimental)-lightgrey) **[安装](#install)** · **[快速开始](#quickstart)** · **[为什么用 VM?](#why-a-vm)** · **[工作原理](#how-it-works)** · **[对比](#compared-to)** · **[FAQ](#faq)** · **[文档](docs/)**
只有当你让编码 agent 真正去*做*事情时,它才有用:安装软件包,运行它写的代码,启动服务器,使用网络。在你自己的机器上,这留下了两个糟糕的选择。你要么批准每一条命令(每隔几秒钟就得盯着一个 prompt),要么运行 `--dangerously-skip-permissions`,然后祈祷重要的东西不会因为一个 `rm -rf` 或一个泄露的 token 而丢失。 clawk 提供了第三种选择。`cd` 进入一个 repo,输入 `clawk`,Claude Code(或者 Codex,或者一个 shell)就会在一个一次性的 Linux VM 中工作(你的代码被挂载进去,在 guest 中拥有 root 权限,没有权限弹窗),而你的文件、你的 keychain 以及你机器的其余部分都处于不可触及的范围之外。**agent 拥有了它自己的机器,而不是你的。**

clawk demo: clawk boots a VM and attaches claude; a blocked attempt to send data to an unknown server shows up in clawk network denials; clawk attach resumes the sandbox later
One command to a working agent; an attempt to send data to an unknown server, blocked by the network allow-list; clawk attach resumes the session later.

这个边界并不是 prompt 中的一条规则,agent 可能会被说服而放弃它。这是一台独立的机器,唯一的入口是你挂载的目录。从沙箱内的一个 shell 中: ``` $ curl https://tracker.evil.example # not on the allow-list: blocked curl: (7) Failed to connect to tracker.evil.example port 443 after 2 ms: Connection refused $ cat ~/.ssh/id_rsa # your keys never entered the VM cat: /home/agent/.ssh/id_rsa: No such file or directory $ git push # ...yet this works: ssh-agent is forwarded Enumerating objects: 5, done. ``` 坦白说,关于它的限制,白名单拦截的是对*未知*服务器的连接,而不是你已允许的服务器:github.com 已被预先允许,并且转发的 ssh-agent 可以进行 push,因此,请将 agent 能够读取的任何内容都视为它可以发布的内容。[安全模型](#security-model-and-its-limits) 对此进行了详细说明。 如果 agent 把 VM 搞崩溃了,运行 `clawk destroy && clawk`:这将获得一个全新的 VM,相同的 repo,并且 `--resume` 会恢复之前的对话。 ## 核心亮点 - **让 agent 做任何事。** 它在一个带有受限网络的 VM 中运行,因此 `rm -rf`、软件包安装和不受信任的代码都无法触及你的 host、你的文件或任何你没有明确共享的内容。 - **一条命令即可工作。** `cd` 进入一个 repo 并运行 `clawk`。不需要 Dockerfile、devcontainer 或设置文件。首次启动会根据你的 image 构建 rootfs;此后的每次启动只需要几秒钟。 - **随意折腾而不丢失任何东西。** 自由地销毁和重建;你的代码和 agent 的对话都保存在 host 上。丢失的只有那个一次性的 VM 磁盘。 - **一个真正的 Linux 主机,你的工具链。** 任何 OCI image 都是 rootfs:一个完整的操作系统,配备了你的项目所需的确切工具。无需 Docker daemon。 - **机密信息保留在你的机器上。** 出站流量受白名单限制,并且你的 ssh-agent 被转发,因此无需密钥进入 VM 即可执行 `git push`。 - **每个项目或工单一个沙箱。** 可同时运行多个沙箱;对于多 repo 工单,每个 repo 都有一个 git worktree,并支持协同的 PR。闲置的 VM 会自动释放内存并挂起到磁盘,因此被遗忘的沙箱(几乎)没有任何成本。 ## 为什么用 VM? clawk 是一个用于自主编码 agent 的通用本地环境。VM 是关键所在:它是 agent 可以拥有的一整台机器,而不是你正在使用的机器上被策略包裹的一个进程。 - **独立的内核。** Guest 运行自己的 Linux 内核,因此 host 的文件系统并不是隐藏在拒绝规则背后;它压根就没有被挂载。 - **传统的 Linux 环境。** 标准的内核,标准的 userland,符合 `/dev/kvm` 的期望,因此工具的行为会与其文档描述一致,没有 syscall 过滤带来的意外。 - **Guest 中的 root 权限。** 安装系统软件包,编辑 `/etc`,加载模块,绑定特权端口。这是 agent 可以随意重新配置的主机。 - **一次性生命周期。** 破坏成本很低,重建速度很快;一个崩溃的 VM 只需要一条 `clawk destroy && clawk` 命令就能恢复,而你的 repo 和对话在 host 上原封不动。 - **与 host 更强的隔离。** 隔离依赖于 hypervisor 边界,而不是依赖于完美配置的进程沙箱策略。 这种组合能够运行那些受限的进程沙箱通常会阻碍的工作负载: - 安装软件包和原生依赖; - 运行后台服务(数据库、队列、开发服务器); - 全速执行不受信任的构建和测试; - 使用期望存在真实机器的系统级 Linux 工具; - 此外,在支持的硬件上启用了 KVM 的 guest 内核,还可以在沙箱*内部*运行容器和 Kubernetes 开发工作流,例如 Docker 或 Kind。这是可选的并且受硬件限制;有关确切要求,请参阅 [镜像](docs/images.md#guest-kernel-override)。 这些都不是*产品*本身;clawk 是为一般的本地 agent 工作而生的。Docker 和 Kubernetes 只是“需要一台真正的机器,而不是沙箱进程”的最尖锐的例子。 ## 安装说明 在 Apple silicon 上需要 macOS 14+。(Linux 通过 firecracker 支持,目前处于实验阶段;有关差异,请参阅 [VM providers](docs/commands.md#vm-providers)。本 README 优先针对 macOS。) ``` brew install clawkwork/tap/clawk ``` **从源码构建**(贡献者,或者如果你不使用 Homebrew),需要 Go 1.26+: ``` git clone https://github.com/clawkwork/clawk && cd clawk make install ``` 无论哪种方式,都不需要额外的 host 工具:没有 Docker,没有 qemu,没有 sudo。Hypervisor 是 Apple 的 Virtualization.framework,链接到了二进制文件中。首次运行会探测是否有缺失的内容,并主动提供修复建议。 **卸载:** 对你的沙箱执行 `clawk destroy`,`rm -rf ~/.clawk`,然后使用 `brew uninstall clawk` 移除二进制文件(如果是源码安装,则从 `$GOBIN` 中删除它)。没有安装任何其他东西:没有 launchd 任务;每个沙箱的 daemons 都是普通的进程,会随着它们的 VM 一起退出。 ## 快速开始 日常情况,为你当前所在的目录创建一个沙箱: ``` cd ~/code/my-project clawk # boot a sandbox for this dir + attach claude clawk run shell # drop into a shell in the same sandbox clawk run codex # or another agent: codex, opencode, shell clawk down # stop the VM (repo + agent state persist) clawk attach # come back later — boots if stopped, reattaches claude clawk destroy # remove the VM (conversation history is kept) ``` 常用选项: ``` clawk run claude -- --resume # pass args through to the agent clawk forward add my-project 3000 # expose a guest dev server on localhost:3000 clawk network allow my-project api.example.com ``` 正在处理一个跨越多个 repo 的工单?一条命令即可创建一个沙箱,其中包含每个 repo 在全新分支上的一个 git worktree,稍后执行 `clawk pr` 就会为所有更改打开交叉链接的 PR: ``` cd ~/code/my-workspace # contains a clawk.mod listing the repos clawk work INFRA-123 # one sandbox, a worktree per repo, claude attached clawk pr INFRA-123 # push branches + open one PR per repo ``` 完整的工单生命周期(状态、合并后的后续分支、rebase)在 **[docs/ticket-mode.md](docs/ticket-mode.md)** 中。 ## 生存规则 一条规则决定了持久化:*VM 是一次性的;所有你可能舍不得丢失的东西都保存在 host 上。* | | `clawk down` | `clawk destroy` | | --- | :---: | :---: | | 你的 repo(挂载的 worktree;commits,branches) | ✅ | ✅ | | Agent 状态(Claude/Codex 对话,memory) | ✅ | ✅ | | VM 磁盘(apt 安装,缓存,`$HOME`) | ❌ (每次启动*时全新重建) | ❌ (目的就在于此) | \* 两个例外:恢复 `clawk snapshot` 会将磁盘和内存完全恢复到挂起时的状态,而 Linux/firecracker provider 会保留其磁盘直到执行 destroy。每次启动都需要的工具应该放在 image 中(`vm ( image … )`);每次启动时的设置应该放在 `on up` hooks 中。 Agent 状态是按沙箱挂载到 host 的:guest 的 `~/.claude/projects/` 和 `~/.claude/memory/`(以及 codex 的 `~/.codex/`)位于 host 上的 `~/.clawk/namespaces/default/state//` 下,因此重建的沙箱可以通过 `--resume` 恢复其旧的对话。 ## 默认完全自主(以及 `--safe` 退出选项) Runners 以其“外部沙箱化”模式启动:claude 获得 `--dangerously-skip-permissions`,codex 获得 `--dangerously-bypass-approvals-and-sandbox`。在你自己的机器上,这些 flag 是鲁莽的;但在这里它们是核心意义所在:VM 边界和网络白名单提供了遏制,因此 agent 可以全速工作而无需逐个操作进行 prompt 确认。agent 只能影响你挂载和白名单允许的内容,仅此而已(见 [SECURITY.md](SECURITY.md))。 无论如何还是更喜欢确认弹窗?在任何 attach 中添加 `--safe`(`clawk --safe`,`clawk run claude --safe`),runner 就会在该会话中不带 bypass flag 启动。 ## 网络 出站流量默认被拒绝;每个沙箱都有自己的白名单。DNS 会解析所有内容;发往未列出 host 的 TCP、UDP(包括 QUIC)和 ICMP echo 都会被拒绝。常见的 registry(npm、PyPI、crates.io、GitHub、Anthropic 等)已预先允许,并且过滤器是 DNS-aware 的,因此即使 `example.com` 的 IP 轮换,允许该域名依然有效。 ``` clawk network allow my-project api.stripe.com '*.internal.mycorp.com' 10.0.0.5 clawk network denials my-project # what the agent tried that got blocked clawk forward add my-project 3000 # localhost:3000 → the guest's dev server ``` 拒绝记录是根据 *guest 解析的 hostname* 进行记录的,因此 `clawk network denials` 可以作为 agent 尝试访问的日志来读取。可重用的命名策略(包括订阅如 oisd 等外部 blocklist)以及分层应用它们的 `use` 链在 **[docs/networking.md](docs/networking.md)** 中。 ## 配置:`clawk.mod` 不需要配置文件;默认值很合理。当项目需要更多配置时,可以通过一个 `clawk.mod` 文件来描述它,采用类似 go.mod 的语法: ``` sandbox my-project ( vm ( cpu 4 memory 8GiB image golang:1.25 # any OCI image is the rootfs ) network ( allow api.example.com ) forwards ( 3000 ) env ( DATABASE_URL ) # names only; values come from your shell on create ( "go mod download" ) agent ( instructions "Ask before running destructive commands." ) ) ``` 该块是一个 *template*:在创建沙箱时进行快照,因此运行中的沙箱永远不会意外更改。完整的参考(shares、secret 文件、skills、agent memory seeding、多 repo workspace roots)在 **[docs/configuration.md](docs/configuration.md)** 中;images 和自定义 guest kernels(包括用于嵌套虚拟化的 KVM 启用内核)在 **[docs/images.md](docs/images.md)** 中。 ## 生命周期 ``` clawk list # all sandboxes clawk status [] # state, forwards, blocked hosts; --json for scripts clawk up / down # boot / stop clawk pause / resume # suspend / resume the running VM in memory clawk snapshot # save to disk: RAM freed, guest intact; resume restores it clawk destroy # remove the VM; host-side state persists ``` `clawk snapshot` 是沙箱的休眠模式:guest 的内存会连同其磁盘一起保存,下次启动时会完全恢复 guest 到挂起前的状态。后台进程和开发服务器会像什么都没发生一样继续运行,而 `clawk attach` 会把你带回到 agent 面前。完整的命令面、runner dispatch 和闲置管理机制(ballooning、准入控制、自动停止)在 **[docs/commands.md](docs/commands.md)** 中。 ## 工作原理 ``` you ──▶ clawk CLI ──▶ per-sandbox daemon (detached; owns the VM) ├─ gvproxy: in-process userspace TCP/IP stack — │ the DNS-aware outbound filter the guest can't reconfigure ├─ vsock bridge to the in-guest pty-agent (no sshd) ├─ ssh-agent proxy, macOS (signing stays on the host) └─ VM: Virtualization.framework (macOS) / firecracker (Linux) ├─ clawk-init, PID 1 (no systemd, no cloud-init) ├─ your repo, live-mounted over virtio-fs └─ claude / codex / shell on a PTY ``` 一些刻意的设计,简述如下: - **rootfs 是一个普通的 OCI image。** clawk 拉取它(无需 Docker daemon),展平层,并直接写入一个 ext4 磁盘,不需要 root 和 loop 设备。来自同一 image 的每个沙箱都是一个写时复制克隆(APFS `clonefile` / `FICLONE`),因此每个沙箱的磁盘成本仅仅是 guest 写入的内容。 - **网络在 guest 之下被过滤。** VM 的整个 L3(gateway、DHCP、DNS、NAT)是 daemon 进程内的一个用户空间栈。每个出站连接和 DNS 应答都会查询那里的白名单,即使是 guest 内部的 root 也无法更改它。不需要 host iptables,不需要 sudo。 - **唯一的入口。** 没有 sshd,没有 cloud-init:一个单一的 vsock agent 是进入 guest 的唯一控制路径,每次 attach 都是 container-exec 风格的:一个全新的进程,在断开连接时被销毁。 完整的图景(guest 栈、两个 providers、帧级别的网络)在 **[ARCHITECTURE.md](ARCHITECTURE.md)** 中,每个决策背后的理由在 **[DESIGN.md](DESIGN.md)** 中。 ## 对比 - **Containers & devcontainers。** 它们共享你的内核,并根据拒绝规则查看你的文件系统;一个单独的内核漏洞或一个错误的挂载就可能暴露 host。Devcontainer 设置通常绑定挂载 host Docker socket 来构建 image,从而将 host daemon 的控制权交给了 container;而 clawk 将 Docker 保留在 VM *内部*。而且不需要编写 `Dockerfile`/`devcontainer.json`:任何 OCI image 都是 rootfs。 - **OS级别的 agent 沙箱。** 像 Anthropic 的 sandbox-runtime 这样的工具在你的真实机器上应用进程级的防护:非常适合轻量级规则,但一个策略错误就会暴露一切(包括 keychain),而且要安全地允许安装、后台服务或嵌套 hypervisor 会很麻烦。clawk 将整个工作负载转移到了另一台机器上。 - **通用 VM 管理器(例如 Lima)。** Lima 给你一个 Linux VM;clawk 是在其之上的一个*工作流*:每个项目都有一个挂载了 repo 的 VM,连接并验证了一个 agent,默认对白名单外的出站流量进行拦截并记录拒绝日志,agent 对话在跨 destroy 后依然持久存在,并且有一个管理 worktree 和 PR 的工单模式。(在底层,两者都使用 Virtualization.framework。) - **云端沙箱。** 本地优先:你的代码永远不会离开你的机器,没有任何东西按小时计费,并且 agent 编辑的 worktree 就是你编辑器中的那个,在 macOS 上实时挂载(Linux provider 目前在创建时将其固化到镜像中;见 [路线图](#roadmap))。云端沙箱适合大型机群;clawk 是为你桌面上的那台机器准备的。 ## 安全模型(及其限制) 两个边界在发挥作用:VM(host 文件系统除了你挂载的内容外是不可见的)和出站白名单(在 guest 之下的用户空间强制执行,适用于所有可以离开它的协议)。clawk **不**防范的内容: - **你挂载或允许的任何内容都会被暴露。** Worktree 是可写的,因此 agent 可以提交糟糕的代码或将其 push 到你的转发 ssh-agent 能够访问的任何 repo。像审查陌生人的 PR 一样审查从沙箱出来的内容。 - **你 push 进去的机密是可见的。** `files ( … )` 和 `shares ( … )` 的内容、转发的 env vars 以及 Claude token 是 agent 可以读取的(并且,如果目标地址在白名单中,它也可以发送到那里)。请仅共享必要的内容。 - **Hypervisor 逃逸。** clawk 依赖于 Virtualization.framework/KVM 隔离;它不增加超出它们之外的防御。 如果你找到了打破边界的方法(guest 到 host 的逃逸、网络过滤器绕过、凭据泄露),请通过 [SECURITY.md](SECURITY.md) 私下报告。 ## 常见问题 **开销是多少?** 首次从 image 启动需要承担一次性的 rootfs 构建(pull → flatten → ext4)。此后,磁盘是写时复制的克隆,内核直接引导,无需 firmware 和安装程序。闲置的 VM 会将内存释放到约 1 GiB,在闲置 30 分钟后自动停止,并且可以快照到磁盘,因此它们只占用存储成本。 **在 Intel Macs 上能用吗? Windows 呢?** 不行。macOS 需要 Apple silicon(macOS 14+)。在 Linux 上,firecracker provider 可以工作,但处于实验阶段(见 [docs/commands.md](docs/commands.md#vm-providers))。不支持 Windows。 **我需要安装 Docker 吗?** 不需要。clawk 自己拉取 OCI images 并构建可引导磁盘。Docker *images* 是输入格式;不涉及 Docker engine。(在沙箱*内部*运行 Docker daemon 是一个单独的、可选的功能;有关硬件和内核要求,请参阅 [镜像](docs/images.md#guest-kernel-override))。 **为什么叫 "clawk"?** 这个标志是一只爪子;*clawkwork* 是对 *A Clockwork Orange*(发条橙)的谐音。一个你可以上发条、释放并且总能重置的 VM。 ## 路线图 接下来:运行数量超过你的 RAM 可同时容纳上限的沙箱。 - **快照闲置停止。** 作为 `clawk snapshot` / `clawk resume` 发布的手动挂起到磁盘;接下来,*自动*闲置停止也会使用它,因此开发服务器能够撑过停止,并且挂起的沙箱只需花费磁盘成本。 - **运行中 VM 的上限。** 当 RAM 被占用时,不是拒绝新的 VM,而是将最近最少使用的沙箱挂起到磁盘并启动新的沙箱。 - **Firecracker 功能对齐。** Linux 上的实时 worktree 传播和 host 文件 push。 ## 状态 处于 1.0 之前的阶段,正在积极开发中,并且演进迅速:预计发布版本之间会有破坏性变更。CLI 表面变化最小,内部变化最大,但在 1.0 之前没有任何东西是固定不变的。 ## 贡献 欢迎提交 Issues 和 PRs。请参阅 [CONTRIBUTING.md](CONTRIBUTING.md) 了解如何构建和测试,[ARCHITECTURE.md](ARCHITECTURE.md) 了解其构建方式,以及 [DESIGN.md](DESIGN.md) 了解其未来的发展方向。 ## 许可证 [Apache License 2.0](LICENSE)。clawk vendor 了两个具有各自许可证的第三方组件(gvisor-tap-vsock,Apache-2.0;一个 hcsshim ext4 writer,MIT);见 [NOTICE](NOTICE)。
标签:AI编程助手, EVTX分析, Go语言, 日志审计, 沙箱环境, 环境隔离, 生成式AI安全, 程序破解, 网络访问控制, 虚拟机