工作区隔离能力
Open ACE 为本地交互工作区(聊天 WebUI、文件接口、会话历史)提供版本化的多用户 隔离能力契约。管理员与可信接入方应通过 API 查询实际生效的能力,而不是依赖 README 声明或客户端传入的 capability 布尔值。本文档说明契约语义、部署要求、 reason code 对照与已知缺口。关联 issue:#3374(os_user)、#3378(sandboxed)、#3431(约束与本机 gVisor 容器)、#3438(本机 Kata 容器)。
本文是参考文档。要选择并配置一种隔离方式,请先看管理员指南 WORKSPACE_ISOLATION。
1. 能力契约字段
查询端点:GET /api/workspace/isolation-capabilities(需要登录会话)
{
"local_workspace_multi_user": "supported | unsupported",
"backend": "shared | plain | bwrap | local-gvisor | local-kata | opensandbox:<tier>",
"isolation_level": "none | os_user | sandboxed",
"enforced": ["identity", "filesystem", "environment", "process"],
"unsupported": ["resources", "network_egress", "kernel"],
"reasons": [{"code": "...", "message": "..."}],
"entry_points": {
"webui": "enforced",
"filesystem_api": "enforced",
"session_history": "enforced",
"terminal": "remote_machine_scope",
"vscode": "remote_machine_scope",
"autonomous": "separate_contract"
},
"entry_point_details": {
"filesystem_api": {
"status": "enforced",
"scope": "local_workspace",
"covered_by_isolation_level": true,
"operations": [
{"name": "upload", "roots": ["home"],
"symlink_policy": "never_followed_with_elevated_privilege"},
{"name": "browse", "roots": ["home", "shared_projects"],
"symlink_policy": "resolved_then_rejected_if_outside"}
],
"access_control": ["home_subtree_lock", "shared_project_acl", "os_account_dac",
"nofollow_fd_descent"],
"boundary": "...",
"limitations": [],
"residuals": [{"code": "shared_project_roots_are_cross_user_by_design", "message": "..."}]
}
},
"policy_revision": "2026-09-26.3",
"install_method": "package | docker | dev | unknown",
"available_backends": {"local-kata": {"available": false, "reason": "install_method_docker"}, "...": {"available": true}}
}
local_workspace_multi_user:本地交互工作区多用户隔离是否受支持。backend:即workspace.isolation.backend的名字(#3446),快照报告管理员配置的 backend——plain(每用户独立 WebUI 进程,以该用户的 OS 账户运行)、bwrap(#3431:同上,且每个进程运行在 systemd scope + bubblewrap 约束内,见 §5.1)、shared(共享单实例)、local-gvisor(#3431:sandboxed 等级, WebUI 运行于本机 gVisor 容器,见 §5.2)、local-kata(#3438:sandboxed 等级,WebUI 运行于本机 Kata 容器,见 §5.3)或opensandbox:<tier>(#3378:sandboxed 等级,WebUI 运行于该 tier 的 OpenSandbox pod, 见 §6)。配置了但未就绪的 backend 报告为supported: false并给出原因,绝不会被替换成别的 backend; 报告的等级是本机验证到的等级。install_method/available_backends:本部署的安装方式(OPENACE_INSTALL_METHOD),以及每个 backend 在这里到底能否使用(不能时为install_method_docker/platform_unsupported)。所配置 backend 的就绪 状态见reasons。isolation_level/enforced/unsupported:见下节。reasons:unsupported 时的机器可读原因(可能为空)。entry_point_details(#3410 新增,与entry_points同生共死):每个入口的机器 可读细节,让接入方能区分「满足所声明等级」「由其它机制治理」「真实缺口」, 而不必解析散文。字段:status:与entry_points中同名键完全一致(单测钉住);scope:local_workspace/remote_machine/separate_contract;covered_by_isolation_level:该入口是否被本快照声明的isolation_level覆盖;operations[]:{name, roots, symlink_policy}——逐操作声明可达根集合与 符号链接策略(同一入口内并不统一,见 §4);access_control[]:实际强制该入口的机制代号;limitations[]:真实缺口/未覆盖范围,参与准入判定(enforced入口恒为空);residuals[]:已知且被接受的性质(如共享项目根按设计跨用户),不参与准入判定。
- 未知
status或未评审过的policy_revision必须按拒绝处理(fail closed): 本契约会新增状态词,接入方不得把未知值当作通过。 entry_points:各入口的隔离覆盖状态(§4)。仅在 supported 快照中输出—— 入口矩阵描述的是多用户隔离的覆盖面,unsupported(单用户/未验证/降级)部署 不携带该矩阵,避免"无隔离"与"webui: enforced"同帧自相矛盾。该矩阵为静态 审计结论,随policy_revision版本化;各入口与代码的 conformance 绑定为 后续工作(§8)。policy_revision:契约语义版本;推导逻辑或入口矩阵变化时递增。
2. 隔离等级语义
等级序:none < os_user < sandboxed(required_isolation 请求参数与
下限 workspace.isolation.level 均按此序比较,只能抬高不能降低)。
| 等级 | 语义 |
|---|---|
none | 所有本地交互会话共享同一服务账户运行,无用户间文件/环境/进程隔离(单用户轻量模式,by design) |
os_user | 每用户独立系统账户与 HOME/TMP/XDG;WebUI 进程以该用户 UID 经 sudo -u 启动;子进程环境为显式白名单(真实模型 API key 永不进入,以代理 token 替代);文件接口应用层 home 子树锁 + OS 权限 |
sandboxed | 每用户 WebUI 运行在拥有独立内核边界的沙箱里:OpenSandbox pod(#3378,§6)或本机容器(#3431/#3438,§5.2、§5.3)。以下为 pod 形态:每用户 WebUI 进程运行于 OpenSandbox pod(#3378):每实例独立 pod、digest-pinned 且在 image_allowlist 的专属 webui 镜像、deny-default 出口、恒有资源边界;身份为 per-instance token secret(非 OS 账户,实例销毁即失效);浏览器经控制面本地端口代理访问。部署要求与诚实边界见 §6 |
边界声明:os_user 共享宿主内核,没有命名空间隔离、没有网络出口策略——
"分目录/更换 HOME"不构成强运行时隔离。resources、network_egress 与
kernel 三个维度对普通 os_user 始终列在 unsupported(交互 WebUI 无 per-task
cgroup,仅实例数上限与空闲清理;无出口策略;共享宿主内核)。约束模式(§5.1)会补上
resources 与 network_egress。sandboxed 等级的维度语义与验证边界见 §5.2、§5.3 与 §6.1。autonomous 任务的资源与沙箱策略沿用独立的
#2022 sandbox 契约(sandbox_effective_policy),见 SANDBOX_BACKENDS。
平台边界:仅 Linux 部署可申报 os_user。macOS 跳过系统用户创建,Open ACE
无法建立/验证身份映射;Windows 强制单实例。两者契约均为
unsupported/platform_unsupported。
3. Reason Code 对照
四套代码,职责不同:
3.1 契约 reasons[](部署级:为什么整体 unsupported)
| code | 含义 |
|---|---|
webui_disabled | WebUI 管理器未启用,无交互工作区运行时 |
platform_unsupported | 非 Linux 平台(Windows/macOS/其他) |
isolation_backend_shared | workspace.isolation.backend 为 shared(单用户轻量模式,预期状态而非缺陷) |
launch_path_degraded | WebUI 启动路径无法承载按用户实例(message 括注 §3.3 的具体原因,如 dev 目录模式/包装器缺失);契约与 /user-url 门闸看同一条路径,不会互相矛盾 |
launch_path_unverified | 冷 worker 上 manager 尚未初始化、探针未运行:等级为 provisional(部署形态达标),manager 初始化后自动消除;按 revision 缓存/灰度的接入方应同时检查该码 |