Skip to content

feat(agent): 增加可选的受限执行模式与 Agent 工具策略 - #18

Merged
Sunwuyuan merged 3 commits into
Moonrend:mainfrom
momo-mnsjtxy:feat/restricted-agent-execution-upstream
Oct 7, 2026
Merged

Sunwuyuan merged 3 commits into
Moonrend:mainfrom
momo-mnsjtxy:feat/restricted-agent-execution-upstream

Conversation

@momo-mnsjtxy

@momo-mnsjtxy momo-mnsjtxy commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

背景与已有隔离的关系

Zakura 已有 Docker 工作区隔离和工具权限控制。本改动补充一种可选、限制更严格的逐命令执行策略,不把既有工作区称作无隔离,也不替代完整编码环境。

  • 现有工作区按 Space 复用长期容器,挂载可写 /workspace,支持终端、浏览器和 ACP:工作区创建、执行分流。
  • 既有 MCP allow/deny 与 disabledTools 保留;新增持久 Agent 策略在实际工具分发处执行默认拒绝白名单。

改动

  • 使用独立 Docker 容器执行命令,固定非 root、移除 capabilities、禁止提权、禁网、只读镜像与源码工作区。
  • 提供 64 MiB 临时 /tmp;限制内存 512 MiB、1 CPU、64 PIDs、最长 300 秒、每路输出 256 KiB、最多 4 个并发执行。
  • 增加按工作区隔离的任务状态和取消,服务端取消会发送 kill 并等待终态;无法确认清理时返回明确错误,绝不回退宿主执行。
  • 设置 Agent config.executionMode="sandbox" 后,只允许强制受限 shell_exec 和 ask_user;其他工具及 ACP 拒绝,模型参数不能降低限制。
  • 区分实际返回类型 host、workspace-container、sandbox;restrictedPolicyApplied 仅表示新受限策略,已有 Docker 工作区仍准确标识为容器隔离。
  • 增加测试、专用 Docker CI 与配置文档。未包含 fork 中无关的 release artifact 路径修复。

兼容性与边界

默认行为保留。新受限模式目前只接入 host 类型工作区,通过新容器只读挂载其专用目录;已有 container 类型工作区暂不能直接启用该模式。源码不可持久修改,/tmp 临时且 noexec;因此本模式不能作为现有可写编码、ACP 或浏览器工作区的无损替代。

需要本地 Linux Docker、预置可信且无 VOLUME 的镜像及支持 bind-recursive=disabled 的引擎。须在开始运行前启用策略,既有宿主任务不会被追溯终止。手动用户管理 API、模型请求与控制面权限属于独立边界。信任 Docker daemon、镜像和宿主工作区管理,且运行期间应避免宿主侧并发修改挂载目录。

创建/启动响应丢失及 daemon 故障可能导致结果或清理状态无法确认;会报告不确定性,不盲目重试。这里不声称 VM 隔离、沙箱逃逸认证或全应用数据隔离。

评审后补修

提交 20f03ed5ab15e89328e6175110c0644ce6293e53 修正了此前测试未覆盖的边界,未把全部自动评论都当作已确认问题:

  • 实际 sandbox 结果(包括 runner 强制模式)的长 stdout/stderr 仅返回有界内存预览,不通过服务端文件 RPC 写回工作区;truncated 合并 runner 限制和服务端 24KB 预览限制。
  • 将执行、传输观察、启动和清理预算区分;只有终态/清理经过确认才保留超时或取消前的最终输出。操作者强制模式也使用后台任务生命周期,普通工作区原 RPC 期限保持。
  • RPC 写入排队、socket 写入及取消均有期限;部分写入失败关闭连接,避免清理等待卡在无期限传输上。
  • ACP、cloud、providers 和 admin-default 内部配置保存改为字段级 CAS 更新,避免旧快照覆盖 executionMode;公共完整配置替换仍保留有意修改/清空策略的语义。
  • 明确 server shell_exec 要求镜像含 bash。加入真实 server→WebSocket runner→Docker 测试,以及一次性 PostgreSQL 并发配置测试;仅使用正常输出、sleep 和临时表等良性测试。

验证

当前 head 10fa4ce79011d122a8d622ed0853bdb10dd39b54 文件树已通过本地完整 Agent 竞态/vet、完整 Server 测试/vet、相关 Server 全包竞态、scanlint、格式及 YAML 检查。独立补丁复核发现的相关问题已修正并增加回归。

新增全链路 CI 在 20f03ed 上发现真实 runner 的长 JSON 响应会分片,而旧 server 只处理单帧,导致输出丢失和超时。10fa4ce 补充有界消息重组及正常分片输出/交错 ping 回归;本地相关竞态、完整 Server 测试/vet 已通过。

当前 head 10fa4ce79011d122a8d622ed0853bdb10dd39b54 的 fork CI 已成功,已逐项核对日志:

  • 真实 Docker 后端检查通过
  • 真实 server→WebSocket runner→Docker:长 stdout/stderr 不写回工作区、超时保留最终输出、调用方取消并确认清理、操作者强制模式不落盘及取消,全部通过
  • 一次性 PostgreSQL CAS 测试通过;SQLite 并发/字段保留测试也通过
  • 完整 Agent 竞态/vet、完整 Server 测试/vet 通过

本地没有 Docker/PostgreSQL,以上真实后端结果来自该次 CI,不是模拟测试。已确认远端文件树与本地测试树完全一致。此前 20f03ed 全链路失败已由分片修复及此次真实运行覆盖。

上游当前 head 的两项工作流仍为 action_required,待维护者批准:sandbox-validation、zakura-agent。没有绕过批准,也不把 fork 通过说成上游已通过。PR 当前为待评审状态,未合并或部署。

@momo-mnsjtxy
momo-mnsjtxy marked this pull request as ready for review October 7, 2026 07:13
@Sunwuyuan
Sunwuyuan merged commit 408da4e into Moonrend:main Oct 7, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants