# ADR-0078:POSIX 本机 Owner Console 证明与 Secret 交付门禁 - 状态:Proposed(POSIX proof、staged Secret 恢复、摘要绑定确认与 Owner ceremony CLI 已实现;fresh setup 和实机故障门禁待完成) - 日期:2026-07-21 - 关联 RFC:QL-RFC-0001 D-27、D-74、D-76、D-77、D-78 - 关联 ADR:ADR-0063、ADR-0075、ADR-0076、ADR-0077、ADR-0079 > ADR-0087 现行增量:原 `@qinglong/local-owner-bootstrap` 与 `@qinglong/local-owner-credential-recovery` 已物理合并为无聚合根入口的 `@qinglong/local-owner-ceremony/bootstrap` 与 `/credential-recovery`;本文中的旧包名保留为当时实现证据,现行依赖与权限门禁以新 subpath 为准。 ## 上下文 ADR-0077 已提供默认不可达的 Identity provisioning、challenge 与原子首 Owner claim,但 `provision/issue` 请求仍携带结构化 `issuer`。包边界能够阻止默认 application 导入 authority,却不能把一段调用方构造的 JSON 变成可信 `local_console` 事实。 直接增加 CLI 还有另一个崩溃窗口:数据库事务可能已经提交,而 credential/challenge plaintext 尚未写入用户指定文件。此时 exact replay 按设计只能返回 `null`,如果没有先暂存、提交后发布和重启恢复协议,fresh install 会得到无法取回的凭据。3.0 不以“多数时候能写成功”替代可恢复交付。 ## 决策 ### 1. Authority 在组合根绑定,不进入请求 DTO `ProvisionLocalIdentityRequest` 与 `IssueLocalOwnerBootstrapRequest` 不再包含 `issuer`。`createLocalOwnerBootstrapService` 在构造时绑定短时 `local_console` authority,并在每次操作时重新验证其时间和 subject/assurance;公开请求若添加 issuer、User、principal 或 credential identity 会被 exact-shape 校验拒绝。 这不是把 TypeScript 对象当成不可伪造 capability。真正的生产入口只能是受依赖审计保护的 `@qinglong/local-owner-console` 组合根;默认 runtime/application 和其他 package 不能导入 bootstrap authority。 ### 2. POSIX 证明绑定部署根、数据库、pepper 与进程用户 短生命周期 console 要求 real/effective UID 存在且相同;显式 `deploymentRoot` 必须是当前 UID 拥有的真实 `0700` 目录,数据库和 pepper 必须是该根下经逐段验证、无 symlink 的真实 `0600` 普通文件。路径必须是规范化、有界绝对路径,两个 authority 文件不能同路径或共享 inode。 该证明表达“当前进程已取得这个私有部署目录的 OS 文件权限”,不把 `localhost`、TTY、环境变量或 HTTP body 当成身份。容器中能否执行该短命令、volume ownership 与宿主管理权限是否等价,仍由部署模板和实机证据负责;库本身不伪造宿主 attestation。 ### 3. 打开前后和每次操作都复核路径身份 组合根先捕获 root/intermediate/database/pepper 的 `(device,inode,uid,mode,type)`,再打开唯一 SQLite bootstrap connection,打开后立即复核一次;每次 provisioning/issue/claim 前再次复核。路径替换、权限放宽、UID 变化或 symlink 都在触发数据库 authority 前 fail closed。 console 不增加 listener、timer、watcher、scanner、cache、sidecar 或第二 SQLite connection,关闭继续复用同一 operation authority 的幂等 close fence。 ### 4. Pepper 只从私有普通文件读取 pepper 不接受 argv、环境变量、stdin 或 JSON。组合根以 `O_RDONLY|O_NOFOLLOW` 打开已证明的 `0600` 文件,比较 fd 与路径的 device/inode,施加 32–256 bytes 上限,只接受无空白的 base64url 内容,并在转成短生命周期字符串后清零读取 Buffer。 本 ADR 不负责 pepper 创建、轮换、备份或恢复;这些动作需要 no-replace 文件发布、版本化引用与恢复策略,不能由 migration/application 启动时自动生成。 ### 5. Secret 可恢复交付已实现,但 CLI 继续受剩余门禁 `@qinglong/local-owner-console` 已按 ADR-0079 实现有界、私有、no-replace 的 staged secret record:数据库提交前耐久暂存,提交并核对数据库事实后原子发布;重启以 mutation/database 事实恢复。启用 delivery 后 provision/issue 响应始终返回 `token: null`,明文只存在于私有 ready record,不进入 stdout、日志或错误。 该包仍不声明 `bin`;ADR-0086 由独立 `@qinglong/local-owner-cli` 组合它,并以 command-file-only 的 `ql3-owner` 开放 provisioning/claim/delivery acknowledgement/credential recovery。ADR-0080/0081/0082/0083/0084 已补齐 pepper no-replace provision/backup/restore、ready record 摘要绑定确认、SQLite acknowledgement ledger、pepper/credential rotation 与可恢复 tombstone retention/GC;fresh setup、rotation 管理命令、断电/真实 ENOSPC/只读文件系统和 Linux/容器权限证据仍未完成。HTTP/UI 继续禁止,因为它们还需要独立的 origin/CSRF/rate-limit/transport 与恢复设计。 ## 被否决的替代方案 1. **请求继续携带 issuer**:让 transport 字段冒充平台 authority,拒绝。 2. **只检查 `stdin.isTTY` 或 loopback**:两者都不证明部署文件权限或调用者身份,拒绝。 3. **pepper 通过 argv/env/stdin**:会进入进程列表、诊断或继承边界,拒绝。 4. **事务成功后直接写 secret 文件**:崩溃或 ENOSPC 会永久丢失一次性 secret,拒绝。 5. **为 console 另开常驻服务或 watcher**:扩大攻击面并破坏路由设备零常驻成本,拒绝。 6. **把本机 POSIX proof 复用于 cluster-control**:集群仍使用独立 PostgreSQL/cluster-admin/Worker 身份与传输边界,拒绝。 ## 验收证据 1. `@qinglong/local-owner-bootstrap` 8 项真实 SQLite 测试在 issuer 构造期绑定和跨进程时间漂移后继续通过;请求注入 issuer/identity 被拒绝,稳定 authentication identity 不变时 exact replay 成功,不同 identity 冲突。 2. `@qinglong/local-owner-console` 19 项测试通过:私有 POSIX proof、完整 provision/issue/transport-free claim、预提交 pending 保留、数据库提交后 credential/challenge 自动恢复、文件删除后数据库事实重放、权限/摘要篡改与 64 条目录预算 fail closed、数据库 inode 替换、幂等关闭与无 `bin`/默认 runtime 导出。 3. dependency audit 登记 32 个 QL3 package importer;只有 local-owner-console 可以直接导入 local-owner-bootstrap,产品 CLI 只能导入 console facade,默认根继续禁止全部 QL3 authority 包。 4. 32 个 QL3 production importer 的 low/moderate/high/critical advisory 均为零;legacy 根 3 low/9 moderate/2 high 独立可见。 ## 未完成项 credential `pepper_key_id` provenance、受审 keyring/active CAS、credential rotate/revoke/recovery、versioned acknowledgement tombstone retention/GC 与 Owner ceremony CLI 已由 ADR-0083/0084/0086 完成;仍需 Linux rootless/root 容器与 volume ownership 证据、真实断电/ENOSPC/只读文件系统故障注入、固定低配路由设备 RSS/闪存写放大门禁,以及 fresh setup/rotation 运维入口。ready record 显式确认、安全删除与 SQLite 账本已由 ADR-0081/0082 完成。