
clawk v0.4.0
给编码代理一个一次性的 Linux 虚拟机,而不是你的笔记本电脑
编码代理只有在你真正让它动手做事时才有用:安装包、运行它写的代码、启动服务器、使用网络。在你自己机器上,这只会留下两个糟糕的选择。要么你批准每一条命令(然后每隔几秒就盯着一个提示符),要么你运行 --dangerously-skip-permissions,然后祈祷没有什么是离一个 rm -rf 或一个泄露的令牌那么近。
clawk 是第三个选择。cd 进一个仓库,输入 clawk,Claude Code(或 Codex、pi、或一个 shell)就在一个一次性的 Linux 虚拟机里工作(你的代码挂载进去,来宾系统里是 root,没有权限提示),而你的文件、你的钥匙串、以及你机器的其余部分都够不着。代理得到的是它自己的机器,而不是你的。
一条命令就得到一个能工作的代理;一次向未知服务器发送数据的尝试,被网络允许列表阻止;clawk attach 稍后恢复会话。
边界不是提示词里一条可能被代理说服绕过的规则。它是一台独立的机器,唯一的开口就是你挂载的那些。从沙箱内的一个 shell 里:```console $ 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 可以推送,所以请把 agent 能读取的任何内容都视为它可能发布的内容。[安全模型](#security-model-and-its-limits)对此有详细说明。
如果 agent 弄坏了 VM,运行 `clawk destroy && clawk`:一个全新的 VM、同一个仓库,`--resume` 会恢复对话。
> [!IMPORTANT]
> **1.0 之前且快速迭代中。** 版本之间预计会有破坏性变更和偶尔的粗糙之处;事情可能而且一定会出问题。请提交 issue;这些反馈正在塑造 1.0。
## 亮点
- **让 agent 做任何事。** 它运行在一个网络受限的一次性 VM 中,所以 `rm -rf`、软件包安装和不受信任的代码都无法触及你的主机、你的文件,或任何你未明确共享的内容。
- **一条命令即可工作。** `cd` 进入仓库并运行 `clawk`。无需 Dockerfile、devcontainer 或配置文件。首次启动会从你的镜像构建 rootfs;之后的每次启动只需几秒。
- **弄坏它也不会丢失任何东西。** 随意销毁和重建;你的代码和 agent 的对话都保存在主机上。只有一次性 VM 磁盘会丢失。
- **一个真正的 Linux 机器,你的工具链。** 任何 OCI 镜像都是 rootfs:一个完整的操作系统,恰好包含你的项目所需的工具。无需 Docker 守护进程。
- **机密留在你的机器上。** 出站流量被允许列表限制,你的 ssh-agent 被转发,因此 `git push` 无需密钥进入 VM 即可工作。
- **每个项目或工单一个沙箱。** 可同时运行多个;多仓库工单会为每个仓库创建一个 git worktree,并协调 PR。空闲 VM 会自动释放内存并挂起到磁盘,因此被遗忘的沙箱几乎不花费任何成本。
## 为什么用 VM?
clawk 是一个面向自主编码 agent 的通用本地环境。VM 是关键:它是一个 agent 可以完全拥有的整台机器,而不是包裹在你正在使用的机器上的策略里的一个进程。
- **独立的内核。** 客户机运行自己的 Linux 内核,因此主机文件系统不是靠拒绝规则隐藏的;它从未被挂载过。
- **常规的 Linux 环境。** 标准内核、标准用户空间、符合 `/dev/kvm` 预期的行为,因此工具的行为与其文档一致,不会出现系统调用过滤的意外。
- **客户机中的 root 权限。** 安装系统软件包、编辑 `/etc`、加载模块、绑定特权端口。这是 agent 可以重新配置的机器。
- **一次性生命周期。** 弄坏成本低,重建速度快;一台损坏的 VM 只需 `clawk destroy && clawk` 即可恢复,你的仓库和对话在主机上不受影响。
- **与主机更强的隔离。** 隔离依赖于虚拟机监控程序边界,而不是依赖把进程沙箱策略做到完全正确。
这种组合可以运行受限进程沙箱往往难以支持的工作负载:
- 安装软件包和原生依赖;
- 运行后台服务(数据库、队列、开发服务器);
- 以全速执行不受信任的构建和测试;
- 使用期望真实机器的系统级 Linux 工具;
- 并且,在受支持的硬件上配合启用 KVM 的客户机内核,可以在沙箱*内部*运行容器和 Kubernetes 开发工作流,例如 Docker 或 Kind。这是可选的且受硬件限制;具体要求请参阅[镜像](https://github.com/clawkwork/clawk/blob/main/docs/images.md#guest-kernel-override)。
这些都不是*产品本身*;clawk 是用于一般性本地 agent 工作的。Docker 和 Kubernetes 只是“需要真实机器,而不是沙箱进程”的最典型例子。
## 安装
需要 macOS 14+ 且为 Apple silicon。(Linux 通过 firecracker 支持,目前处于实验阶段——请从 **[docs/linux-quickstart.md](https://github.com/clawkwork/clawk/blob/main/docs/linux-quickstart.md)** 开始,其中涵盖了设置、工作流程和差距。本 README 以 macOS 为主。)```sh
brew install clawkwork/tap/clawk
从源码构建(贡献者,或如果你不使用 Homebrew),需要 Go 1.26+:```sh git clone https://github.com/clawkwork/clawk && cd clawk make install
无论哪种方式,都不需要额外的主机工具:不需要 Docker、不需要 qemu、不需要 sudo。
虚拟机监控程序是 Apple 的 Virtualization.framework,已链接到二进制文件中,并且发布二进制文件已预构建了客户机内代理——因此只有在从源码构建时才需要 Go 工具链,而那时你本来就有。首次运行会检测缺失项并提供修复。
**卸载:** `clawk destroy` 销毁你的沙箱,`rm -rf ~/.clawk`,然后通过 `brew uninstall clawk` 移除二进制文件(如果是源码安装,则从 `$GOBIN` 中删除)。没有安装其他任何东西:没有 launchd 任务;每个沙箱的守护进程都是普通进程,会随其虚拟机一起退出。
## 快速开始
日常使用场景,为当前所在目录创建一个沙箱:```sh
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, pi, 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)
通用选项:```sh 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
处理一个跨多个仓库的工单?一条命令即可为每个仓库在全新分支上创建带 git worktree 的沙箱,之后 `clawk pr` 会为所有变更内容打开相互关联的 PR:```sh
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
完整的工单生命周期(状态、合并或变基后的后续分支)详见 docs/ticket-mode.md。
提示: 使用 Claude Code?运行一次
claude setup-token,然后运行clawk auth set-token,之后每个沙箱启动时都会自动登录, 无需/login,并行沙箱之间也不会出现登录冲突。详见 docs/claude-auth.md。
什么能保留,什么不能
一条规则决定持久性:虚拟机是一次性的;你不想丢失的一切都保存在宿主机上。
clawk down | clawk destroy | |
|---|---|---|
| 你的仓库(挂载的工作树;提交、分支) | ✅ | ✅ |
| 代理状态(Claude/Codex/pi/opencode 对话、记忆) | ✅ | ✅ |
虚拟机磁盘(apt 安装、缓存、$HOME) | ❌(每次启动时全新重建*) | ❌(这正是它的目的) |
* 两个例外:恢复 clawk snapshot 会按挂起时的状态精确还原磁盘和
内存;Linux/firecracker 提供程序会保留其磁盘直到执行 destroy。每次启动
都需要的工具应放入镜像(vm ( image … ));每次启动时的设置应放入
on up 钩子中。
代理状态按沙箱挂载在宿主机上:每个运行器的家目录——
claude 的 ~/.claude/、codex 的 ~/.codex/、pi 的 ~/.pi/、opencode 的两个 XDG
目录——位于宿主机上的
~/.clawk/namespaces/default/state/<name>/ 下,因此重建的
沙箱可以通过 --resume 恢复其旧对话。正是这个挂载让承诺成真:虚拟机磁盘本身
在每次启动时都会从镜像重新克隆,因此运行器在这些目录之外写入的任何内容
都会在下次 clawk up 时消失。
默认完全自主(以及 --safe 退出选项)
运行器以其“外部沙箱”模式启动:claude 使用
--dangerously-skip-permissions,codex 使用
--dangerously-bypass-approvals-and-sandbox,pi 使用 --approve(它没有
审批提示可绕过——它根本不附带沙箱——但它确实会将项目本地的 .pi/ 设置和
扩展置于信任提示之后),而
opencode 使用 --auto。在你自己的机器上,这些标志
会是鲁莽之举;但在这里它们正是关键:虚拟机边界和网络
允许列表提供了隔离,因此代理可以全速工作,无需逐操作提示。
代理只能影响你挂载和允许列表中的内容,仅此而已(见 SECURITY.md)。
还是更喜欢确认提示?在任何附加操作中添加 --safe
(clawk --safe、clawk run claude --safe),该会话中运行器将
不带其绕过标志启动。
网络
默认拒绝出站流量;每个沙箱都有自己的允许列表。
DNS 可解析所有内容;对未列入列表的主机的 TCP、UDP(包括 QUIC)和 ICMP 回显
均被拒绝。常见注册表(npm、PyPI、crates.io、GitHub、
Anthropic 等)已预先允许,并且过滤器是 DNS 感知的,因此允许
example.com 后,即使其 IP 轮换也能持续生效。```sh
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
clawk forward add-reverse my-project 63342 # and the other way: a service on YOUR
# localhost, reachable inside the guest
拒绝记录按*客户机解析出的主机名*进行,因此 `clawk network denials` 可读作代理尝试访问目标的日志。可复用的命名策略(包括订阅 oisd 等外部黑名单)以及将它们分层叠加的 `use` 链,详见
**[docs/networking.md](https://github.com/clawkwork/clawk/blob/main/docs/networking.md)**。
## 配置:`clawk.mod`
无需配置文件;默认设置已足够合理。当项目需要更多配置时,可使用 `clawk.mod` 文件以 go.mod 风格的语法进行描述:```text
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 ) # forward a host var; values come from your shell
# also: GH=${OTHER_NAME}, LOG=${LOG:-info} defaults, API=${API:?required}
mcp ( # MCP servers, ready on first boot
linear https://mcp.linear.app/mcp header "Authorization: Bearer ${LINEAR_TOKEN}"
)
on create ( "go mod download" )
agent (
instructions "Ask before running destructive commands."
)
)
该块是一个模板:在沙箱创建时被快照,因此运行中的沙箱永远不会意外变化。完整参考(共享、机密文件、技能、代理内存种子、多仓库工作区根目录)见 docs/configuration.md;MCP 服务器及其凭据如何不落盘见 docs/mcp.md;将 Mac 上的 USB 串口板放入沙箱以进行微控制器工作见 docs/serial.md;镜像和自定义客户机内核(包括用于嵌套虚拟化的 KVM 启用内核)见 docs/images.md。
生命周期```sh
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` 是沙箱的休眠机制:客户机的内存会与其磁盘一起保存,下次启动时会将客户机精确恢复到之前的状态。后台进程和开发服务器会像什么都没发生一样继续运行,而 `clawk attach` 会让你重新回到代理面前。完整的命令面、运行器调度以及空闲管理机制(内存回收、准入控制、自动停止)都记录在 **[docs/commands.md](https://github.com/clawkwork/clawk/blob/main/docs/commands.md)** 中。
## 工作原理```text
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 / pi / shell on a PTY
几个刻意的选择,简述如下:
- rootfs 是一个普通的 OCI 镜像。 clawk 拉取它(无需 Docker 守护进程),
展平各层,并直接写入一个 ext4 磁盘,无需 root 权限,也无需 loop 设备。
来自同一镜像的每个沙箱都是写时复制克隆(APFS
clonefile/FICLONE), 因此每个沙箱的磁盘成本就是客户机实际写入的量。 - 网络在客户机之下被过滤。 VM 的整个 L3 层(网关、DHCP、DNS、NAT) 是守护进程内部的一个用户态协议栈。每个出站连接和 DNS 应答都会在那里 查询允许列表,即使客户机内的 root 也无法更改它。无需主机 iptables,无需 sudo。
- 单一入口。 没有 sshd,没有 cloud-init:一个单一的 vsock 代理是进入 客户机的唯一控制路径,每次附加都是 container-exec 风格:一个全新的进程, 断开连接即被销毁。
完整图景(客户机栈、两个提供程序、帧级网络)见 ARCHITECTURE.md, 每个决策背后的理由见 DESIGN.md。
对比
- 容器与 devcontainer。 它们共享你的内核,并能在减去拒绝规则的情况下看到你的
文件系统;一个内核 bug 或一次错误的挂载就可能暴露主机。Devcontainer 设置通常
会绑定挂载主机 Docker 套接字来构建镜像,从而让容器控制主机守护进程;clawk 则
将 Docker 保留在 VM 内部。而且无需编写
Dockerfile/devcontainer.json: 任何 OCI 镜像都可以作为 rootfs。 - 操作系统级代理沙箱。 像 Anthropic 的 sandbox-runtime 这类工具会在你的真实 机器上应用进程级护栏:适合轻量级规则,但一次策略失误就会暴露一切(包括钥匙串), 而且安装、后台服务或嵌套虚拟机管理程序都难以安全地放行。clawk 将整个工作负载 移到了另一台机器上。
- 通用 VM 管理器(例如 Lima)。 Lima 给你一个 Linux VM;clawk 是在其之上 的一个工作流:每个项目一个 VM,挂载仓库,附加并认证代理,默认允许列表出站 并记录拒绝,代理对话在销毁后仍保留,以及一个管理 worktree 和 PR 的票据模式。 (底层两者都使用 Virtualization.framework。)
- 云沙箱。 本地优先:你的代码永远不会离开机器,没有按小时计费,代理编辑的 worktree 就是编辑器中的那个,在 macOS 上实时挂载(Linux 提供程序目前会在创建时 将其烘焙进去;见 Roadmap)。云沙箱适合集群;clawk 是为你桌面上的 机器而设计的。
安全模型(及其局限)
两个边界在起作用:VM(主机文件系统除了你挂载的内容外不可见)和出站允许列表 (在客户机之下的用户态强制执行,适用于所有可以离开它的协议)。clawk 不防护 以下情况:
- 你挂载或允许的内容都会暴露。 Worktree 是可写的,因此代理可以提交糟糕的 代码,或推送到你的转发 ssh-agent 能到达的任何仓库。像审查陌生人的 PR 一样 审查沙箱产出的内容。
- 你推入的机密是可见的。
files ( … )和shares ( … )的内容、转发的 环境变量以及 Claude 令牌,代理都可以读取(并且,如果某个目的地被允许列表 放行,还可以发送到那里)。分享最少的内容。 - 虚拟机管理程序逃逸。 clawk 依赖 Virtualization.framework/KVM 隔离; 它不会在这些之外增加防御。
如果你找到突破边界的方法(客户机到主机逃逸、网络过滤绕过、凭据泄露),请通过 SECURITY.md 私下报告。
常见问题
开销如何? 从镜像首次启动会支付一次性的 rootfs 构建成本(拉取 → 展平 → ext4)。之后, 磁盘是写时复制克隆,内核直接启动,无需固件,也无需安装程序。空闲 VM 会将内存 释放到约 1 GiB,空闲 30 分钟后自动停止,并且可以快照到磁盘,因此只占用存储。
支持 Intel Mac 吗?Windows 呢? 不支持。macOS 需要 Apple silicon(macOS 14+)。在 Linux 上,firecracker 提供程序可用但处于实验阶段(见 docs/commands.md)。 不支持 Windows。
需要安装 Docker 吗? 不需要。clawk 自己拉取 OCI 镜像并构建可启动磁盘。Docker 镜像是输入格式; Docker 引擎不参与。(在沙箱内部运行 Docker 守护进程是一个单独的、可选的功能; 硬件和内核要求见 Images。)
为什么叫 "clawk"? 标志是一个爪子;clawkwork 是对 发条橙(A Clockwork Orange)的戏仿。一个 你可以上紧发条、放出去、随时重置的 VM。
路线图
下一步:运行比你的 RAM 能同时容纳的更多的沙箱。
- 带快照的空闲停止。 手动挂起到磁盘已作为
clawk snapshot/clawk resume提供;接下来,自动空闲停止也会使用它,这样开发服务器能在停止后存活, 挂起的沙箱只占用磁盘。 - 运行中 VM 的上限。 当 RAM 已全部提交时,不再拒绝新 VM,而是将最近最少 使用的沙箱挂起到磁盘,然后启动新的。
- Firecracker 对等。 Linux 上的实时 worktree 传播和主机文件推送。
状态
Pre-1.0 且处于积极开发中,演进迅速:预期版本之间会有破坏性变更。CLI 表面变化 最少,内部变化最多,但在 1.0 之前没有任何东西是冻结的。
贡献
欢迎提交 Issue 和 PR。构建和测试见 CONTRIBUTING.md, 构建方式见 ARCHITECTURE.md,未来方向见 DESIGN.md。
许可证
Apache License 2.0。clawk 附带两个第三方组件,它们使用各自的许可证 (gvisor-tap-vsock,Apache-2.0;一个 hcsshim ext4 写入器,MIT); 见 NOTICE。