mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-20 17:30:59 +00:00
fix(tenancy): close isolation and permission gaps
This commit is contained in:
@@ -28,7 +28,7 @@
|
||||
|
||||
| 编号 | 结论 | 首期状态 |
|
||||
| ----- | --------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
|
||||
| D-001 | 一个共享 Plugin Runtime 控制面;每个运行中的 plugin installation 独占一个 nsjail 子进程;只有 digest 相同且已验证的代码 artifact 可以只读共享 | `IMPLEMENTED — real Linux/egress deployment gate pending` |
|
||||
| D-001 | 一个共享 Plugin Runtime 控制面;每个运行中的 plugin installation 独占一个 nsjail 子进程;只有 digest 相同且已验证的代码 artifact 可以只读共享 | `FOUNDATION IMPLEMENTED — Linux/egress, crash recovery and disk-quota gates pending` |
|
||||
| D-002 | 一个共享 Box Runtime;Cloud 固定使用 nsjail;符合套餐的 Workspace 最多一个持久 `global` 逻辑 sandbox,普通执行按需启动 nsjail 进程 | `IMPLEMENTED FAIL-CLOSED — hard filesystem quota provider pending` |
|
||||
| D-003 | SaaS 业务数据使用 PostgreSQL shared schema、应用层作用域和 RLS 双重隔离;pgvector 使用同一 PostgreSQL,作为 SaaS 默认向量后端 | `PARTIALLY IMPLEMENTED — transaction/outbox/deployment gates remain` |
|
||||
| D-004 | stdio MCP 与 Box availability 解耦;Cloud v2 首期强制关闭 stdio MCP,避免为每个 Workspace 创建额外的 `mcp-shared` persistent sandbox | `IMPLEMENTED` |
|
||||
@@ -82,12 +82,12 @@ Core 不能继承 Plugin Runtime 所需的 nsjail/cgroup 权限。Box Runtime
|
||||
|
||||
## 3. D-001:Plugin Runtime 多租户控制面
|
||||
|
||||
状态:`IMPLEMENTED — Cloud deployment verification pending`
|
||||
状态:`FOUNDATION IMPLEMENTED — Cloud deployment and worker-recovery gates pending`
|
||||
|
||||
### 3.1 已实现的基础
|
||||
|
||||
- Plugin Runtime 控制连接只绑定稳定实例身份;一个 Supervisor 通过完整 installation binding 管理多个 Workspace。
|
||||
- 每个 enabled installation 使用独立 nsjail worker;代码只读,home/tmp/data 私有,shared profile 不读取 artifact `.env`。
|
||||
- Plugin Runtime 控制连接只绑定稳定实例身份;一个逻辑共享控制面通过完整 installation binding 管理多个 Workspace,M0 由一个 Supervisor replica 承担。
|
||||
- 每个运行中的 installation 使用独立 nsjail worker;enabled-resident 是 desired semantics。代码只读,home/tmp/data 私有,shared profile 不读取 artifact `.env`。
|
||||
- 实例级 `PluginWorkerPolicy` 由 Core 的 `data/config.yaml` 下发,支持原生环境变量覆写;manifest 不能覆盖。
|
||||
- `installation_uuid`、`artifact_digest` 和 `runtime_revision` 已持久化并进入 desired-state、注册、Host API 和 generation/revision fence。
|
||||
- 已验证 `.lbpkg` 先进入 Workspace-scoped durable binary storage;Runtime 本地缓存丢失后可由 Core replay。
|
||||
@@ -110,13 +110,14 @@ Core 不能继承 Plugin Runtime 所需的 nsjail/cgroup 权限。Box Runtime
|
||||
|
||||
### 3.3 首期执行模型
|
||||
|
||||
- 整个 SaaS 实例共享一个可信 Plugin Runtime Supervisor;新 Workspace 不创建专属 Runtime、连接、卷或进程。
|
||||
- 整个 SaaS 实例共享一个可信 Plugin Runtime 逻辑控制面,M0 运行一个 Supervisor replica;新 Workspace 不创建专属 Runtime、连接、卷或进程。
|
||||
- Supervisor 的控制连接只绑定稳定 `instance_uuid` 和短期 Runtime identity,不绑定某个 Workspace。
|
||||
每条 installation desired-state 命令都携带并验证完整的 installation binding;每个 worker action context 在注册后永久绑定该 tuple。
|
||||
- 安装并启用插件后,Supervisor 在自己的 Runtime 容器内直接启动一个 nsjail 子进程;
|
||||
不再为每个插件创建 nested container、Pod、sidecar 或租户级 Runtime service。
|
||||
- 为兼容现有事件监听和定时任务语义,首期继续采用“enabled installation 保持 resident”,不做 idle eviction;
|
||||
停用、删除、revision/generation 变化或 entitlement 撤销时停止并按需重建。
|
||||
- desired semantics 要求 enabled installation 保持 resident,不做 idle eviction;停用、删除、revision/generation 变化或 entitlement 撤销时停止并按需重建。
|
||||
当前实现只会在 Runtime 重连或 Core apply/reconcile 时恢复意外退出的 worker,尚缺 completion callback、有界 backoff 和跨租户重启风暴抑制;
|
||||
这属于 Cloud 激活门禁,不能把 desired semantics 描述成已经具备即时自愈。
|
||||
- 子进程使用一次性 registration capability 向 Supervisor 注册;capability 由可信 desired state 派生并绑定完整 installation tuple,
|
||||
不是插件直接建立 Core Host connection,也不能只绑定 author/name/path。Supervisor/Core 据此注入 tenant context,
|
||||
丢弃插件 payload 中自带的 scope 字段。
|
||||
@@ -193,8 +194,9 @@ installation data 的总空间硬配额需要 filesystem project quota 或独立
|
||||
| MVP 不引入 | Runtime 专用数据库、Redis、Kafka 或独立 scheduler | 当前无容量证据,会增加组件和运维面 |
|
||||
| 后续演进 | 多 Supervisor replica、owner lease、dedicated pool | 保留接口,达到容量或可用性阈值后再决定具体存储与调度方式 |
|
||||
|
||||
后续仍需决定的只有:Core/Supervisor 是否共置、artifact/venv cache 的签名/来源/撤销/GC 规范、v1 connection 的兼容期限,
|
||||
以及进入多 replica 后的 lease TTL、fencing token 和 owner 转移顺序。这些不改变“每 installation 一个隔离进程”的首期边界。
|
||||
架构扩展项包括:Core/Supervisor 是否共置、artifact/venv cache 的签名/来源/撤销/GC 规范、installation data hard-quota provider、
|
||||
v1 connection 的兼容期限,以及进入多 replica 后的 lease TTL、fencing token 和 owner 转移顺序。
|
||||
这些不改变“每个运行中的 installation 一个隔离进程”的首期边界。
|
||||
|
||||
### 3.7 验收条件
|
||||
|
||||
@@ -203,8 +205,10 @@ installation data 的总空间硬配额需要 filesystem project quota 或独立
|
||||
- 插件不能读取其他 installation 文件、枚举或 signal 其他进程,也不能修改共享代码/依赖目录。
|
||||
- CPU、内存、PID、open files 和单文件上限在真实 nsjail/cgroup 环境中生效;超额只终止或拒绝对应 installation。
|
||||
- 修改 manifest 不能改变任何资源上限。
|
||||
- installation data 的总空间硬配额在写入边界原子拒绝超额,并证明目录扫描不是生产 enforcement。
|
||||
- 旧 generation/revision 的回调、消息、副作用和存储访问全部失败关闭。
|
||||
- Runtime 重启能从业务 desired state 恢复,不依赖本地进程表作为权威真相。
|
||||
- 意外退出的 enabled worker 由 completion callback 触发带有界 backoff 的自动恢复;连续失败只影响对应 installation,不能形成跨租户重启风暴。
|
||||
- requirements 中存在 Runtime 基础镜像未预装的包时,Supervisor 仍能先完成共享依赖环境准备再启动 worker;
|
||||
安装失败不会留下持续重启的半启动进程,也不会影响同 digest 已就绪环境的其他 installation。
|
||||
|
||||
@@ -253,7 +257,7 @@ installation data 的总空间硬配额需要 filesystem project quota 或独立
|
||||
|
||||
### 4.3 Cloud nsjail 执行模型
|
||||
|
||||
- 整个逻辑 SaaS 实例共享一个 Box Runtime 控制面;不创建每 Workspace Box service、worker pool、PVC、bucket、scheduler、Redis 或 Box 数据库。
|
||||
- 整个逻辑 SaaS 实例共享一个 Box Runtime 逻辑控制面,M0 运行一个 Runtime replica;不创建每 Workspace Box service、worker pool、PVC、bucket、scheduler、Redis 或 Box 数据库。
|
||||
- Cloud 显式固定 `box.backend: nsjail`。sandbox 直接作为 Box Runtime 容器内的 nsjail 子进程运行,
|
||||
不创建 nested Docker container、独立 Pod、microVM 或 warm pool,也不挂宿主机 `docker.sock`。
|
||||
- 符合 entitlement 的 Workspace 首次使用时懒创建一个逻辑 session,内部固定 ID 为 `global`,并强制 `persistent=True`;
|
||||
|
||||
Reference in New Issue
Block a user