diff --git a/docs/architecture/cross-machine-permit-wiring.md b/docs/architecture/cross-machine-permit-wiring.md index e8e8519a..31eb090b 100644 --- a/docs/architecture/cross-machine-permit-wiring.md +++ b/docs/architecture/cross-machine-permit-wiring.md @@ -1,9 +1,12 @@ # 跨机许可交付 —— 接线指南(登记与取钥) > **Status**: 跨机许可交付「登记与取钥」环节的接线方操作指南 -> **Date**: 2026-10-28 +> **Date**: 2026-11-07 > **Audience**: 部署与接线方(把跨机许可交付接到真实受保护部署的人) > **Binding**: 跨机许可交付设计文档(框架治理仓内,见对应 mission 的 evidence 目录) +> **变更(2026-11-07)**: §3.1 由「Windows 服务身份必须显式声明」改写为**平台中立的三条能力条款** +> (Windows 服务身份降为「满足方式之一」,其原有条款一字未改地保留在 §3.1.1);新增 §3.10 +> 「目标侧票据部署与控制端主机无关」。依据:M-053 统调裁定 G-Q3 / G-Q4。 本文件是**接线方的操作契约**。下面每一条「必须」都是复核方在签发 / 验签环节独立复核中 明确要求的接线约束,缺一条即视为接线不合规。 @@ -215,7 +218,46 @@ permitStore.consume(consumeFields); ## 3. 接线验收判据(逐条必须满足) -### 3.1 服务身份必须显式声明 +### 3.1 受保护部署的三条能力条款(平台中立) + +「受保护部署」指**受保护部署能力条款**。一台主机满足下列**三条能力**,即构成受保护部署。 +判定对象是**能力**,不是操作系统、不是产品形态、不是 IP 或主机位置。 + +- **G1 能保管**:能在**本机自己的**受保护存储内保管私钥 / 授权凭据, + 且该存储的**写入者集合**可被声明、可被独占登记。 +- **G2 能在受保护临界区校验**:能在**本机自己的**受保护登记型锚点域内, + 读出 pin、撤销集合与期望指纹并完成校验;**调用方不得自报**这三者。 +- **G3 能自判本机状态**:能在受保护临界区内**自行判定**本机进程与 run 状态 + (对应 `targetHasProcess` / `targetHasPriorRun`),**不接受远端报告后原样传入**; + 查不出时传 `null`,由判定落到 fail-closed。 + +**满足方式是示例,不构成定义**(示例可随平台变化,能力条款不变): + +- 在 Windows 上,满足方式可以是「受保护服务身份 + 受保护域」(本形态的附加条款见 §3.1.1); +- 在 macOS 上可以是「受保护钥匙串 / Keychain 访问控制 + 独立受保护目录」; +- 在 Linux 上可以是「受保护的凭据存储 + 目录权限」。 + +若某平台**尚无**满足方式,则该平台**暂不能**担任对应角色 —— 这是**能力缺口**, +不是「换一个平台口径就能通过」。 + +**约束(不因中立化而放宽)**: + +- 目标侧锚点域的**写入者集合**仍须**恰为**目标侧自己的受保护身份; +- 签发侧私钥**只在**签发侧的受保护存储内,不进目标侧; +- 不得引入第二把密钥;撤销集合仍由批次公钥对应的私钥签发; +- 不得以「本机可跑」替代「受保护部署成立」的判定。 + +**为什么必须平台中立**:本节早期版本只写 Windows(「服务身份必须显式声明」)。只写一种形态, +「受保护部署」就成为 Windows 专有概念 —— 「Windows 控 Windows」与其它主机组合就无法进入 +同一套判定口径,「角色与主机无关」只能是口号。平台中立的能力条款允许**不同平台以不同形态 +满足同一条款**,而**判定口径一致**。中立化改的是**表述**,不是约束 —— 中立化前后必须一致的 +不变项逐条列在下方 MR 描述中。 + +**边界**:本节**不**要求签发侧必须具备 Windows 原生的受保护凭据形态。该形态是否需要 +留待 Stage C 实测定型;届时若确需原生形态,**单独申请裁定**。在此之前,任何实现**不得** +为满足本节而扩写 `protected-anchor.js` / `protected-permit-store.js` 的既有语义(§6 已禁止)。 + +#### 3.1.1 Windows 服务身份形态的附加条款(仅适用于该形态) 在 Windows 上,**服务身份的声明是强制的**。原因是那台机器上的调用账号 不一定就是服务本身:不声明就退化成「拿调用方和它自己比」,判定变成恒真的废话。 @@ -362,6 +404,20 @@ permitStore.consume(consumeFields); 任一条不满足,路线在**写入任何 pin 之前**停止,域中不会留下 「`created` + pin 在」的残留状态。 +### 3.10 目标侧票据部署与控制端主机无关(必须) + +跨机取件的通道由**一次性票据 + 本机命名管道代理**组成:目标侧本机的票据代理签发一次性票据, +Host 只从**本机**命名管道取票(`SAMHMI_AUTOMATION_PERMIT_TICKET_PIPE`),**取不到即不发请求**。 + +- 目标侧的票据部署形态**必须与控制端主机无关**,且**必须无关**: + **不得**因控制端是 Windows 还是 Mac 而给目标侧增加任何**前置条件** + (不额外要求目标侧具备某种凭据形态、不额外要求某台机器上的特定组件); +- 目标侧票据代理的职责是「向**本机** Host 出票」。票据在跨机通道上被出示时, + **出示对象的形态不改变目标侧的义务**; +- 这与 §3.1 是同一条原则的两面:角色由**能力**定义,不由主机定义。 + 控制端换成 Windows **不**改变目标侧的任何义务; +- 目标侧完成了票据部署 **≠** 跨机信任成立(§7 的状态声明不变)。 + ## 4. 时钟偏差裕量(`skewToleranceMs`)—— 接线方必须知道的三件事 ### 4.1 裕量必须来自显式配置,并被记录