feat(runtime): enforce miniapp capability policy

This commit is contained in:
2026-08-06 00:23:11 +08:00
parent 58e77462ad
commit c77a0cf69b
5 changed files with 84 additions and 17 deletions
@@ -16,7 +16,7 @@
| 状态 | 优先级 | 编号 | 问题 | 证据 | 当前结论 / 下一步 |
|---|---:|---|---|---|---|
| 🔴 | P1 | A1 | MiniApp 的 Capability 请求绕过 Runtime 的 Manifest、Policy 和审计边界 | `tauri/src/runtime/coordination/lineup-runtime.ts:379-381` | 必须由 Runtime 校验 Manifest 声明、Capability Registry/Policy、输入 schema、前台要求和用户确认;不能直接拼接 `app.call` 发出。 |
| | P1 | A1 | MiniApp 的 Capability 请求绕过 Runtime 的 Manifest、Policy 和审计边界 | `tauri/src/runtime/coordination/lineup-runtime.ts``capability-audit.ts` | 已统一经过 Manifest 声明、Capability Registry/Policy、输入 schema、前台要求和审计记录,再进入普通 Agent 确认请求;拒绝原因也由 Runtime 返回。 |
| ✅ | P1 | A2 | `bundled` MiniApp 的业务逻辑仍在可信 Host JS 中运行,没有真正的受限执行边界 | `tauri/src/main.ts``isolated-surface-host.ts` | 已移除 Host 直接实例化;Task Dashboard/Whiteboard 业务逻辑改在 opaque sandbox iframe 内运行,只能通过 Runtime Bridge 请求能力。待浏览器复验。 |
| ✅ | P1 | A3 | SDK 暴露完整 workspaceMiniApp 可看到其他 App 实例和全局焦点栈 | `lineup-runtime.ts``miniapp-sdk.ts` | 已从 `LineUpMiniAppSDK` 删除 `workspace()`,不再把全局实例和焦点栈交给 bundled MiniApp。 |
| ✅ | P1 | A4 | 同一个 App 的多个 instance 之间 Inbox 订阅没有隔离 | `lineup-runtime.ts` | 已按 `app_scope + conversation_id + instance_id` 过滤实时订阅,并补充双实例回归测试。 |
@@ -31,7 +31,7 @@
## 1. 已验证通过的部分
- `npm run build` 通过。
- `npm test -- --run` 通过:29 个测试文件、126 个测试。
- `npm test -- --run` 通过:29 个测试文件、127 个测试。
- `git diff --check` 通过。
- 使用独立 `agent-browser` 会话登录本地测试账号成功。
- 主 IM 页面、同步状态、应用子会话区域和“启用任务面板”入口可见。
@@ -42,14 +42,14 @@
## 2. P1 问题说明
### A1Capability 请求没有经过 Runtime 的完整裁决
### A1Capability 请求没有经过 Runtime 的完整裁决(已修复)
现在 bundled MiniApp 可以调用 `sdk.capabilities.request(name, reason, input)`,实现直接把参数包装成
`lineup.v1.app.call`。这意味着 MiniApp 可以请求一个没有写入自己 Manifest、没有经过当前 Capability Policy
检查、也没有经过 Host 支持检查的能力。即使后续 Agent 还要确认,这条入口也已经让 MiniApp 伪造了系统能力请求
现在 `sdk.capabilities.request(name, reason, input)` 只会进入 Runtime 的统一入口。Runtime 依次检查当前实例
对应的 bundled Manifest 是否声明该能力、Capability Registry/Policy 是否可用、输入是否符合 schema,以及
能力要求的前台状态;拒绝会返回明确原因,并写入不含敏感参数的审计记录
正确的边界应该是:MiniApp 提出请求 → Runtime 检查 Manifest 和 Policy → 校验参数 → 检查前台/生命周期 →
进入统一的 Capability 状态机和用户确认流程 → 再由 Host 执行
通过检查后,Runtime 生成唯一 `call_id`,记录 pending 审计项,再进入普通 `lineup.v1.app.call` Agent 确认流程。
MiniApp 不会拿到 Host handler、Transport 或权限对象
### A2bundled MiniApp 实际仍是可信代码(已修复,待浏览器复验)
@@ -92,10 +92,10 @@ Interact 使用 `ChatRuntimeSDK` 和 Host 注入的 `toolInteractions`,而 Tas
功能回归:通过
基础构建与自动化测试:通过
真实登录和消息发送:通过
App 架构边界:部分通过(A2 已实现,待浏览器复验;A1/A5/A6 仍不通过)
MiniApp 隔离与 SDK 规范:A2/A3/A4 已通过,Capability/Interact/状态机仍不通过
App 架构边界:部分通过(A1/A2 已实现,A2 待浏览器复验;A5/A6 仍不通过)
MiniApp 隔离与 SDK 规范:A1A4 已通过,Interact/状态机仍不通过
标准交互终态契约:不通过
迭代整体验收:不通过,继续处理 A1,再处理 A5/A6A2A4 需在最终浏览器复验中确认
迭代整体验收:不通过,继续处理 A5/A6;A2 需在最终浏览器复验中确认
```
本次验收没有修改实现代码。下一步应先处理 P1,再重新运行自动化测试和真实浏览器验收;P2/P3 不能被静默