AgentConnect
运维与治理

沙箱隔离

为每个 Agent 的会话选择运行边界,并控制 Agent 可以访问哪些资源。

Kubernetes:官方 Helm 部署默认使用 Agent Sandbox 来管理 Agent Pod 和持久化工作区。安装与配置见 Kubernetes 部署。

你自己运行的 Daemon:每个 Agent 的执行策略决定其会话运行在什么边界之内,从没有任何边界到独立的虚拟机都可以选择。srt 和 microsandbox 只能在 Linux 上运行;macOS 或 Windows 上的 Daemon 只提供 host,选择器会把另外两项显示为不可用。每个沙箱都有一个私有的 Runtime 主目录以及分配给它的工作区。要共享更多主机目录,请使用挂载。

选择执行环境

选项适用场景环境
主机(host)需要完整主机访问权限的可信任务直接以 Daemon 用户的权限在主机上运行
沙箱(srt)可信的内部开发与自动化使用主机工具,但受文件系统与网络限制
虚拟机(microsandbox)通用任务与可信度较低的代码每个会话一台独立的虚拟机
Kubernetes(Agent Sandbox)跨多台机器运行大量 Agent 的团队集中管理的 Agent Pod 与持久化工作区

srt 不是安全边界:它与主机共用内核和用户,而且 Daemon 会在沙箱之外执行部分工作区操作,例如在多个会话共享的工作区里运行 Git。如果某个 Agent 会处理来自组织外部的内容,比如外部贡献者的 Pull Request 和 Issue,或公开的 Webhook,请让它运行在 microsandbox 或 Kubernetes 中,即使其会话是由维护者发起的。

比较 Linux Daemon 沙箱

你使用的内容SRTmicrosandbox
工具与软件包主机工具;安装到可写路径镜像中的工具;安装在会话虚拟机内
主机文件受保护路径被隐藏;其他路径可能可读仅限分配的主机挂载
共享缓存共享的只读或可写挂载共享挂载或私有 overlay
互联网通过代理(工具必须支持代理)公共互联网(私有网络受限)
本地服务器不发布到主机不发布到主机
CPU 与内存未配置按会话的限制可按虚拟机配置
OAuth 凭证工具规则(Claude/Codex);其他情况无防护与 SRT 相同
已保存的 API 密钥工具规则(Claude/Codex);其他情况无防护主机代理(支持的已保存密钥)

两种沙箱都会写入分配的工作区。共享工作区和可写的主机挂载仍然是共享的;microsandbox 会为每个会话单独保存其他虚拟机文件。

工具规则限制 Runtime 的工具访问凭证。主机代理把真实的 API 密钥留在虚拟机之外。支持的 Runtime、登录方式和限制见凭证保护。

技术背景:SRT 隔离与 microsandbox。

选择执行策略

添加或编辑 Agent 时,在执行策略中选择策略。选择器会列出 Agent 所在位置可用的策略:

  • 单个 Daemon:该 Daemon 提供的策略。
  • Daemon 组:至少有一个在役成员提供的策略。会话无法在缺少所选策略的成员上运行,因此请确认你依赖的每个成员都能运行该策略。
  • AgentConnect Cloud 或 Kubernetes Daemon 池:没有选择器。每个会话本来就运行在自己的 Pod 中。
选项边界
主机(host)无
沙箱(srt)一个 SRT 进程沙箱
虚拟机(microsandbox)一台独立的虚拟机

无法在该位置运行的策略仍会留在列表中,但处于禁用状态并标记为不可用。把鼠标悬停在上面可以查看原因:来自 Daemon 启动检查的原因,或者当 Daemon 配置关闭了该策略时显示的 sandbox.<strategy> is off on this daemon。

没有 SRT 工具的 Daemon 上的执行策略选择器:沙箱和虚拟机被标记为不可用,提示框中列出了缺失的软件包

新建的 Agent 在 host 可以运行时默认使用它,否则使用第一个可用的沙箱。版本过旧、无法上报策略的 Daemon 则只提供 host 和沙箱两项,其中沙箱指该 Daemon 配置使用的那个沙箱。要选择具体的策略,请升级 Daemon。

在编辑中,如果有一次迁移到其他 Daemon 的操作尚未保存,选择器会被锁定;请先保存迁移。如果 Agent 所在的位置不再提供已保存的策略,该策略仍保持选中,并标记为“当前位置不提供此策略”。Agent 的配置标签页会在 Runtime 卡片的执行策略行中显示这一选择。

AgentConnect 绝不会回退到更弱的边界。如果某个会话的策略无法在其所在机器上运行,该会话会被拒绝并给出原因。

在选择器推出之前创建的 Agent 会保留原有边界。之前关闭了在沙箱中运行的 Agent 使用 host。之前开启了该选项的 Agent,在其 Daemon 上报策略后,使用该 Daemon 所配置的沙箱,即 srt 或 microsandbox。没有 Daemon 的沙箱化 Agent 使用 srt。

配置 Daemon

把这些设置添加到 Daemon 现有的 config.json(通常是 ~/.agentconnect/config.json)中。保留其中已有的连接和身份设置。

sandbox 对象列出 Daemon 提供的策略。三项默认都是开启的,因此省略它们等同于:

{
  "sandbox": {
    "host": true,
    "srt": true,
    "microsandbox": true
  }
}

每个值可以是 true(按默认设置提供该策略)、false(关闭该策略),或者对于 microsandbox,一个包含虚拟机设置的对象。Daemon 启动时会检查它提供的每个策略。未通过检查的策略为不可用;Daemon 会记录原因,选择器也会显示出来。这些检查不会安装或下载任何东西。没有任何可用策略的 Daemon 会拒绝启动。

SRT

在 Ubuntu 或 Debian 上,安装它的依赖:

sudo apt-get update
sudo apt-get install --yes bubblewrap ripgrep socat

主机必须允许非特权用户命名空间。Daemon 会检查沙箱能否启动。Ubuntu 24.04 及更高版本默认限制非特权用户命名空间,Ubuntu 23.10 在开启该限制后也是如此:请先为 bubblewrap 放行用户命名空间。

microsandbox

要更改虚拟机资源,把 microsandbox 设为一个对象:

{
  "sandbox": {
    "microsandbox": {
      "cpus": 2,
      "memoryMiB": 2048,
      "diskGiB": 10
    }
  }
}

这些资源值是默认值。CPU 和内存限制按虚拟机生效。diskGiB 设置每个可写磁盘(根磁盘、Docker 数据盘,以及使用 overlay 时的一块额外磁盘)的容量。磁盘文件会随着数据写入而增长。

microsandbox 需要 Linux amd64 主机。Daemon 用户需要能访问 /dev/kvm 和 /dev/vhost-vsock。虚拟主机需要支持嵌套虚拟化。第一个 microsandbox 会话启动时,Daemon 会安装 microsandbox SDK 并准备镜像。镜像未缓存时,首次启动会更慢。

强制使用沙箱

要让某个 Daemon 拒绝未沙箱化的会话,请关闭 host:

{
  "sandbox": {
    "host": false
  }
}

此后,对于该 Daemon 上的 Agent,选择器会把 host 显示为不可用,新建的 Agent 会使用第一个可用的沙箱。已经设置为 host 的 Agent 在你为它们选择沙箱之前无法在该 Daemon 上启动会话。如果也没有任何可用的沙箱,Daemon 会拒绝启动。

旧版配置

sandbox.backend 和 security.requireSandbox 已停用。仍然发现这两项的 Daemon 会在启动时读取一次并记录一条警告:它忽略 backend 并按上文提供全部策略,并把 requireSandbox: true 解读为 "host": false。请把它们从 config.json 中删除。会话使用哪个沙箱现在由 Agent 的执行策略决定。

编辑配置后重启:

npx -y @agentconnect.md/cli restart

对于具名实例,加上 --instance <name>。对于前台运行的 Daemon,重新执行它原来的命令(加上 --require-sandbox 可关闭 host)。实例相关命令见升级 Daemon。

Runtime 镜像

microsandbox 使用由已安装的 Daemon 版本选定的 ghcr.io/agentconnect-md/runtime-sandbox-full 镜像。要使用兼容的自定义镜像:

{
  "sandbox": {
    "microsandbox": {
      "image": "registry.example.com/agentconnect/runtime-sandbox-full:build-tag"
    }
  }
}

删除 image 属性即可恢复默认镜像。开发构建版本必须显式指定镜像。

更改镜像内容、虚拟机资源、挂载或凭证布局后,受影响的虚拟机会在刷新或下次使用时重建。挂载自主机的工作区、主目录和记忆文件会保留。虚拟机本地文件、Docker 数据和 overlay 写入会被重置。需要持久保存的数据请放在主机挂载中。内容完全相同的新镜像标签会复用现有虚拟机。

完整镜像包含 Claude Code、Codex、DeepSeek Harness、OpenCode、pi、Oh My Pi、Grok Build、Qwen Code、Cline、Devin、Antigravity ACP、GitHub Copilot、Qoder CLI 和 Qoder CN CLI。Antigravity 需要 AVX 支持。Amp 需要自定义镜像。

镜像还包含 Docker Engine、Buildx 和 Compose。当 Runtime 权限允许时,Agent 可以在自己的虚拟机内启动 Docker。Docker 数据在虚拟机停止/启动后仍然保留,但在虚拟机重建时会被重置。Codex 的工具限制目前会阻止镜像中基于 sudo 的 Docker 启动方式。

网络访问

microsandbox 会话可以访问公共 API 和软件包源。每个虚拟机都有自己的网络环境,因此不同会话可以使用相同的本地端口。虚拟机端口不会发布到主机。

该策略限制对私有网络的访问,但不保证所有指回主机的公网 IP 或 DNS 名称都会被拦截。SRT 通过其代理允许出站 Web 访问;忽略代理设置的工具可能无法连接。

故障排查

消息检查内容
策略不可用选择器提示框中的原因、该策略的要求以及 Daemon 日志
会话被策略拒绝Agent 的策略无法在该机器上运行;修复原因或改选其他策略
镜像中未安装二进制文件所选镜像是否包含该 Runtime
需要登录Runtime 是否已以 Daemon 用户身份登录
挂载被拒绝源路径是否存在、目标路径是否有效、模式是否受支持(见挂载)
虚拟机替换失败检查镜像可用性和挂载访问权限,然后重试

独立的 chat 命令支持 SRT。microsandbox 请使用由 Daemon 托管的会话。

Ubuntu 23.10 及更高版本:为 bubblewrap 放行用户命名空间

症状:在执行策略选择器中,沙箱策略(srt)被标记为不可用,且原因中包含以下之一:

bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted
bwrap: setting up uid map: Permission denied

较新的 Daemon 会在原因中直接指出 AppArmor 限制。

原因:Ubuntu 24.04 及更高版本在 /usr/lib/sysctl.d/10-apparmor.conf 中默认设置 kernel.apparmor_restrict_unprivileged_userns=1。Ubuntu 23.10 引入了该设置,但默认保持为 0。开启后,非特权用户命名空间得不到任何 capability,因此 bubblewrap 无法为沙箱建立隔离网络。在运行时(例如用 sysctl -w)设置的 0 会在重启后丢失。

修复:给 bubblewrap 一个允许用户命名空间的 AppArmor 配置文件。该配置文件只覆盖 /usr/bin/bwrap,即 bubblewrap 软件包的安装位置;其他所有程序仍然受限。创建 /etc/apparmor.d/bwrap 并加载它:

sudo tee /etc/apparmor.d/bwrap > /dev/null <<'EOF'
abi <abi/4.0>,
include <tunables/global>

profile bwrap /usr/bin/bwrap flags=(unconfined) {
  userns,
  include if exists <local/bwrap>
}
EOF
sudo apparmor_parser -r /etc/apparmor.d/bwrap

AppArmor 会在每次启动时重新加载该配置文件。

不要改用 apparmor-profiles 软件包中 Ubuntu 提供的 bwrap-userns-restrict 配置文件。它会剥夺沙箱内的 capability,Daemon 的检查虽然能通过,但像 Codex 这样会在其中再启动自己的 bubblewrap 沙箱的 Runtime 会失败,并报错 bwrap: No permissions to create new namespace。

或者,为整台机器解除该限制。这会对所有程序关闭这项保护,而不仅仅是 bubblewrap:

echo 'kernel.apparmor_restrict_unprivileged_userns = 0' | sudo tee /etc/sysctl.d/60-userns.conf && sudo sysctl --system

验证:以 Daemon 的用户身份运行:

bwrap --unshare-net --ro-bind / / true && echo ok

当 bubblewrap 能够带着自己的网络启动时,它会输出 ok。

然后重启 Daemon,让它重新检查策略:在控制台中从 Daemon 的操作里选择重启,或者在主机上用 npx -y @agentconnect.md/cli restart 或你的服务管理器重启它。

How is this guide?

本页目录

How is this guide?