编码代理只有在你真正让它动手做事时才有用:安装包、运行它写的代码、启动服务器、使用网络。在你自己机器上,这只会留下两个糟糕的选择。要么你批准每一条命令(然后每隔几秒就盯着一个提示符),要么你运行 --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`