Skip to content

feat(runtime): 支持 Private Sandbox Runner 私有执行后端与半私有部署 #438

Description

@AsperforMias

Area

Runtime

Problem

Mosoo 当前将 Runtime 生命周期、文件操作、环境 artifact、终端和 sandbox 执行直接实现于 Cloudflare Sandbox / R2 路径。

这使得客户即使拥有私有 VPS/VPC,也无法将其作为 Mosoo 的 sandbox 执行资源;执行面必须继续运行在 Cloudflare。对于有客户自管执行环境、私网访问或数据处理边界要求的 ToB 场景,这成为产品限制。

本请求不将 Private Sandbox Runner 视为 AI Agent:

  • Private Sandbox Runner:客户 VPS/VPC 内的非 AI 执行连接器。
  • Agent Driver:sandbox 内的既有 Agent protocol adapter / harness。
  • Codex、Claude Code、OpenCode:实际执行任务的 AI Agent harness。

Proposal

将本请求作为父 Feature:在不改变默认 Cloudflare Runtime 行为的前提下,为 Runtime 增加可选的 private-runner sandbox 执行后端,首期面向单 VPS / 单 VPC / 单 Runner 场景,并逐步扩展至半私有数据面。

目标架构

flowchart LR
  Browser["浏览器 / Public API"]

  subgraph Cloud["Mosoo 云端控制面"]
    CP["Runtime<br/>Run、租约、审计、计费"]
    RC["RunnerConnection<br/>命令、心跳、容量"]
    DC["DriverConnection<br/>既有 Driver 控制通道"]
    Meta["D1 / 控制面元数据"]
  end

  subgraph VPC["客户 VPC / VPS"]
    R["Private Sandbox Runner<br/>非 AI;仅出站连接"]
    OS["OpenSandbox Server<br/>仅 loopback"]
    SB["Docker + gVisor Sandbox"]
    AD["Agent Driver"]
    Store["客户 MinIO/S3(P2)"]
    Vault["客户 Vault(P2)"]
    Egress["Egress Proxy / 防火墙"]
  end

  Browser --> CP
  CP --> Meta
  CP <-->|"出站 WSS"| RC
  RC <-->|"出站 WSS"| R
  R --> OS --> SB --> AD
  AD <-->|"既有出站 Driver WebSocket"| DC
  SB --> Store
  SB --> Vault
  SB --> Egress
Loading

Runner、OpenSandbox、Docker 和 sandbox 管理接口不得暴露公网入站端口。Runner 与 Mosoo 控制面保持一条主动建立的 WSS 连接;Agent Driver 保持现有的独立出站 Driver WebSocket 控制模式。

OpenSandbox 可以作为 Runner 的本地实现选项,提供 Docker sandbox 生命周期、文件与命令 API、网络策略和隔离运行时支持;Mosoo 不直接依赖或暴露其 API,以便未来替换为其他本地执行实现。

需要建立的 Runtime 抽象

1. SandboxBackend

将 Cloudflare-specific sandbox 实现收敛为 SandboxBackend 的一个实现,而不是让 Runtime 直接调用 Cloudflare SDK。

首期通用能力应包括:

  • ensureSubject / destroySubject
  • 文件读写与目录创建
  • 命令执行
  • 进程启动、终止、状态与日志查询
  • sandbox 状态读取
  • 可选能力:backup / restore、interactive terminal、preview、file watch

RuntimeExecutionPlaneAdapter 继续负责 Run 编排、租约、状态机和业务语义;SandboxBackend 仅负责执行资源操作。

Cloudflare backend 必须保留为默认实现。

2. RunnerControlProtocol

新增 Mosoo 控制面与 Runner 之间的版本化协议,至少包括:

  • Runner enrollment、密钥轮换和撤销
  • 心跳、版本、能力与容量上报
  • sandbox.ensuresandbox.destroy
  • 文件写入、命令执行、进程启动/停止、状态读取
  • 幂等 operationId
  • sandbox ULID、lease expiry、generation
  • 操作结果、错误码、重连后的结果回放
  • Runner drain / offline 状态

Runner 必须持久化最小命令 journal,避免重连、超时重试或控制面重复投递导致重复创建、重复启动或重复销毁。

3. Runner 资源与绑定模型

新增明确的私有 Runner 记录,而不是泛化为 Service

  • private_sandbox_runner:Organization、设备公钥、版本、能力、状态、心跳时间、drain 状态。
  • 在既有 sandbox 资源上增加 backend kind、runner id、外部 sandbox reference,或建立等价的显式关联记录。
  • Mosoo sandbox ULID 仍为唯一业务身份;Runner 侧只保存其外部执行引用。
  • 既有 Cloudflare-specific session / backup 标识应逐步迁移为 provider-neutral external reference;数据库变更必须新增 migration,不改写既有 baseline。

4. Artifact、文件与密钥边界

P1 可以暂时通过当前控制面文件路径向 Runner 提供已授权附件,但不得将其表述为数据驻留能力。

P2 需要将以下能力抽象为 customer-managed storage / vault:

  • Environment artifact:从 Cloudflare backup id 演进为 provider-neutral artifact reference;推荐 immutable OCI image 或客户对象存储 artifact。
  • Session attachment、运行产物、Pet checkpoint:支持客户 MinIO/S3。
  • Secret delivery:Runner 使用客户 Vault,或仅接收为其设备公钥加密的短期密文;不将明文 secret 写入 Runner journal、控制面日志或长期存储。
  • network policy:现有 Environment 配置中的网络策略仅是保存的 intent,不能作为安全边界;Runner 必须通过 egress proxy / 防火墙实际执行默认拒绝和 allowlist。

Runner 的职责与边界

Runner 负责:

  • 主动连接 Mosoo 并完成设备身份认证。
  • 上报健康、版本、CPU、内存、磁盘、并发槽位和能力。
  • 在本地调用 OpenSandbox / Docker 创建、回收和查询 sandbox。
  • 执行 RunnerControlProtocol 命令并返回幂等结果。
  • 强制 sandbox CPU、内存、PID、磁盘和网络限制。
  • 以本地安全边界执行镜像、artifact、secret 与 egress 策略。
  • 维护最小本地 journal、健康诊断和审计事件。

Runner 不负责:

  • AI 推理、任务理解或 Agent 决策。
  • 用户身份、Organization 授权、Run lease 或业务状态机。
  • 生成 Mosoo 的业务记录、账单或审计结论。
  • 向公网暴露 Docker、OpenSandbox、宿主机 shell 或 sandbox 管理端口。
  • 将 Docker socket、宿主目录、特权权限或云 metadata endpoint 暴露给 sandbox。
  • 在 Runner 离线时决定将执行静默迁移到 Cloudflare。

Agent Driver 不属于 Runner;它仍在 sandbox 内运行并通过既有机制主动连接 Mosoo DriverConnection

Mosoo 接入前的兼容改造

  • runtime-subject-platform.ts 中的 @cloudflare/sandbox 获取逻辑移入 Cloudflare backend 实现。
  • SandboxHandle 中 Cloudflare-specific 类型,例如 terminal PtyOptions,移入可选 terminal capability,避免跨 backend 类型泄漏。
  • 保留现有 Pet / Cattle 生命周期、Run lease、Driver boot payload 和 Driver WebSocket 语义。
  • 新增独立的 RunnerConnection Durable Object;不得复用 DriverConnection,因为两者的身份、令牌、生命周期和安全语义不同。
  • 为 backend capability 做 feature negotiation,避免 private-runner 尚未支持 terminal、backup 或 preview 时被 Runtime 隐式调用。
  • 首期按部署配置或内部 feature flag 将一个 Organization 固定到一个已注册 Runner;不新增公开 GraphQL 配置页和复杂调度 UI。
  • Runner 离线时明确失败、等待重试或进入诊断状态;不得静默回退到 Cloudflare,以免违反客户预期的数据与执行位置边界。

分层交付计划

阶段 交付内容 对外承诺 主要验收
P0 ADR、术语锁定、SandboxBackend contract、Runner protocol、fake Runner 不改变生产行为 Cloudflare backend 回归通过;协议含版本、lease、幂等和错误模型
P1 单 VPS/VPC、单 Runner、Cattle sandbox、出站 WSS、Docker + gVisor 可选运行时 customer-managed execution 创建/销毁、Driver 启动、重复命令、Runner 重连、离线失败、资源配额测试通过
P2 客户 MinIO/S3、客户 Vault、artifact 抽象、egress proxy、审计/保留/删除 半私有数据面 附件、产物、checkpoint 与 secrets 不再落入 Mosoo 默认对象存储;egress allowlist 实际生效
P3 Pet checkpoint/restore、私有 terminal tunnel、多 Runner、drain 与容量调度 私有执行能力增强 Pet 状态边界、故障恢复、terminal 授权、Runner drain 和容量准入通过
P4 控制内容端到端加密,或客户自托管控制面 严格数据驻留 prompt、Driver events、会话内容和模型出口满足客户的数据处理边界

安全与 ToB 合规基线

P1 仅意味着 sandbox 计算发生在客户 VPS/VPC;Mosoo 控制面、prompt、Driver events、附件和模型请求仍可能经过 Mosoo/Cloudflare 或模型供应商。

P2 才能声明半私有数据面,最低要求:

  • Runner 使用设备密钥、短期 challenge、轮换与撤销机制认证。
  • Runner 仅允许出站到 Mosoo 控制端点、客户批准的模型端点和业务私网目标。
  • sandbox 默认拒绝 egress,阻断云 metadata endpoint。
  • 客户自有对象存储承载附件、artifact、checkpoint 与运行产物。
  • 客户 Vault 或加密 envelope 交付敏感凭据。
  • 镜像签名、SBOM、漏洞修复策略和版本兼容矩阵。
  • 审计日志、数据保留、删除、Runner drain、密钥撤销和故障响应流程。
  • 每个高隔离客户至少使用独立 Runner host / VPS;gVisor 是增强隔离,而非替代租户级基础设施隔离。

严格数据驻留不在 P1/P2 承诺范围内。由于当前浏览器输入和 Agent Driver event 会经过 Mosoo 控制面,若客户要求控制内容完全不离开 VPC,则需要 P4 的端到端加密设计或客户自托管控制面;模型调用也必须使用客户批准的私有或区域端点。

Alternatives considered

  • 保持 Cloudflare Sandbox:保持最低实现成本,但无法使用客户 VPS/VPC。
  • Mosoo API 直连客户 OpenSandbox/Docker:需要暴露入站管理 API,且将本地实现细节耦合进控制面。
  • E2B BYOC:具备参考价值,但目前面向 AWS/GCP 商业托管,不是通用 VPS 开源底座。
  • Kubernetes / Agent Sandbox:适用于未来多节点场景,对单 VPS 首期过度设计。
  • 直接把 OpenSandbox 作为 Mosoo 公开 API:会锁定第三方模型与生命周期语义,不利于后续替换。

Compatibility and migration

  • 默认关闭;未配置 private-runner 时,现有 Cloudflare Runtime 行为必须完全不变。
  • 先通过内部配置绑定单 Runner;用户可见配置、Runner 池与调度策略后置。
  • Cloudflare backend 与 private-runner backend 并存;按新建 Runtime 选择 backend,不迁移运行中的 sandbox。
  • Runner 离线时不得自动切换 Cloudflare;Cattle 可由明确策略重试,Pet 仅报告不可用,直至后续 checkpoint/restore 能力实现。
  • 所有数据库变更使用新增 migration;不改写生产已应用 baseline。
  • P1 的产品文案为 “customer-managed execution”;只有完成 P2 后才可称为“半私有数据面”。

Contribution

I can provide product feedback

Checklist

  • I searched existing issues before opening this request.
  • I described the problem before the proposed solution.
  • I kept this request focused on one improvement.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions