7.1 KiB
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 与恢复设计。
被否决的替代方案
- 请求继续携带 issuer:让 transport 字段冒充平台 authority,拒绝。
- 只检查
stdin.isTTY或 loopback:两者都不证明部署文件权限或调用者身份,拒绝。 - pepper 通过 argv/env/stdin:会进入进程列表、诊断或继承边界,拒绝。
- 事务成功后直接写 secret 文件:崩溃或 ENOSPC 会永久丢失一次性 secret,拒绝。
- 为 console 另开常驻服务或 watcher:扩大攻击面并破坏路由设备零常驻成本,拒绝。
- 把本机 POSIX proof 复用于 cluster-control:集群仍使用独立 PostgreSQL/cluster-admin/Worker 身份与传输边界,拒绝。
验收证据
@qinglong/local-owner-bootstrap8 项真实 SQLite 测试在 issuer 构造期绑定和跨进程时间漂移后继续通过;请求注入 issuer/identity 被拒绝,稳定 authentication identity 不变时 exact replay 成功,不同 identity 冲突。@qinglong/local-owner-console19 项测试通过:私有 POSIX proof、完整 provision/issue/transport-free claim、预提交 pending 保留、数据库提交后 credential/challenge 自动恢复、文件删除后数据库事实重放、权限/摘要篡改与 64 条目录预算 fail closed、数据库 inode 替换、幂等关闭与无bin/默认 runtime 导出。- dependency audit 登记 32 个 QL3 package importer;只有 local-owner-console 可以直接导入 local-owner-bootstrap,产品 CLI 只能导入 console facade,默认根继续禁止全部 QL3 authority 包。
- 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 完成。