设计说明
这一页说明 Anpio Key 为什么这样设计、各部分保证什么。完整的实现级规格在仓库的 DESIGN.md。
目标
Anpio Key 要同时做到两件事:
- 长期私钥不通过普通接口交出去;
- 调用者只能在批准的身份、目标、期限和次数内使用密钥。
密钥解锁本身不等于授权。解锁只让钥匙可用;能不能签、签什么,由 grant 和策略决定。
两种运行方式
| 方式 | 前提 | 能依赖什么 |
|---|---|---|
| Linux 受保护部署 | 服务、管理员、Agent 是三个系统账号;程序和配置由 root 持有 | 在系统、管理员和 daemon 可信时,限制 Agent 读私钥、改策略、跨主体签名 |
| 开发模式 | 同一个账号下的 serve 和客户端 | 常规接口不返回私钥;不提供同账号代码隔离 |
同一个账号下的不受限程序属于同一个主体。文件权限、二进制白名单和终端限制都不能把它们隔开。
受保护部署的前提是:Agent 没有 sudo、宿主 Docker socket、管理员凭据,也不能修改服务程序或配置。这些前提不成立时,不能套用受保护部署的结论。
一次签名经过什么
text
Agent 提交请求
→ 内核确认调用者 UID
→ 映射到持久主体
→ 规范化 HTTP 请求并计算摘要
→ 检查 grant、策略、期限、次数、撤销状态
→ 事务 A:预留额度、写审计
→ 调用签名
→ 事务 B:保存结果、写审计
→ 返回签名头预留额度后就可能已经扣次,所以签名失败时不能简单地“免费重试”。系统会区分:
completed:签名结果已经保存;failed_reserved:预留后明确失败;outcome_unknown:不知道签没签,需要查询和人工核对。
相同 request_id 和相同输入的重试只复用已有结果,不重新签名,也不再次扣次。
授权模型
- 主体:由内核 UID 映射成持久的 principal UUID。PID、工作目录、调用方自报名字都不参与授权。
- 钥匙角色:root、hot、device_signing、key_agreement、recovery、challenge。grant 只能绑定与操作匹配的角色:hot 用于 HTTP 与 origin proof,device_signing 用于用途断言与对象 proof,key_agreement 用于 ECDH,root 只通过管理面签发的 grant 用于文档 proof。
- grant:绑定主体、指定钥匙、不可变策略版本、启动轮次、绝对到期时间和最大次数。
- 策略:当前只支持精确 HTTPS 域名、方法白名单、精确路径、禁止或精确 query、空或有界 body。没有通配域名、路径正则或可执行策略。
管理员和 Agent 分开
管理员通过独立的管理 socket:
- 登记身份、确认钥匙角色;
- 发布策略;
- 创建和撤销 grant;
- 解锁、轮换、恢复。
Agent 通过数据 socket 只能:
- 列出自己获准的钥匙;
- 读取公开文档;
- 请求 HTTP 签名、origin proof、用途断言、对象/文档 proof 或 X25519 协商;
- 查询自己的请求状态。
数据面没有密码、解锁、通用根签名、任意字节签名或生命周期入口。除了基线六个操作,其余签名路各自一个开关、默认关;唯一能用根键的是 SIGN_DOCUMENT_PROOF,它的 grant 只能由管理面签发。
持久化和恢复
SQLite 是主体、角色、策略、grant、请求和审计的真源。
- 启动只打开已有实例,拒绝缺失、损坏、链接、外来实例和更新的 schema。
- 重启时递增 boot epoch、撤销旧 grant、把未决请求标成
outcome_unknown、作废未完成批准,并保持所有钥匙锁定。 - 数据库和文档文件不能原子提交,因此文档替换依赖已批准的操作意图和旧/新摘要恢复;遇到未知内容就拒绝服务。
当前不支持无人值守恢复。重启后需要管理员重新解锁和建权。
审计
授权、配额、撤销和签名事件和状态在同一个事务里写入 SQLite。
events.jsonl 是按顺序导出的投影:
- 重复导出不重复事件;
- 导出失败保留上一份完整文件;
- 它不是第二套授权真源;
- 不记录口令、seed、原始敏感 body。
本地链和文件权限能检查一致性、阻止 Agent 修改。独立采集器能发现源侧整体回滚或重写,但不防御源端和采集器主机一起失陷。
信封和硬件根
信封默认由三路材料保护:
text
KEK = HKDF-SHA256( argon2id(口令) ‖ device.secret ‖ HS, salt )- 不绑硬件时,没有 HS。
- 绑定硬件后,HS 由芯片保管,磁盘上没有。
- 硬件只保护解封材料;解封后 Ed25519 签名仍在普通内存里执行。
- 指定的硬件不可用时必须报错,不能静默降级。
当前不支持的能力
- macOS 受保护执行域和正式发行;
- Secure Enclave 的正式分发(Developer ID 签名、公证、长期安装身份);
- 实体 TPM 硬件保护声明;
- 无人值守恢复;
- 通配域名、路径正则、字段级 body/query、多 origin 等扩展策略;
- 跨主体委托;
- 远程多租户 KMS、通用密码管理器、完整企业 IAM,以及不可信宿主管理员下的密钥保密。
每项能力单独定义威胁模型和验收,不会因为 Linux 首版完成就自动获得安全声明。