SuperAPI AI 工具集

zamokctl

安全与审计

查看项目

更新于 10-15 17:25

技能介绍

用途:zamokctl 是 Zamok 的离线签名 CLI(Swift,位于 apps/macapp),与 ZamokApp GUI 同为 ZamokSigning 核心的两个薄接口,共用 macOS 钥匙串中的根密钥和 /draft → confirm → verbatim-sign → /publish 流程。已移除 bun/TS 签名 CLI。

信任模型:根密钥是离线信任锚,私钥仅存本地 macOS 钥匙串(service app.bshk.zamok.root-key,每个 kid 一项),服务器不持有也无法签名。产品 keyset 仅用该产品在 packages/signing-keys/trusted-roots.json 中列出的公钥验证;增删/轮换根需改该文件→PR→部署。钥匙串为 ThisDeviceOnly,不随换机保留,须将导出的 .age 与 .identity 托管到保险库。CLI 为 ad-hoc 签名/无 entitlement,使用文件/登录钥匙串,无每次生物识别提示。JWS 使用 alg=EdDSA、header kid,payload 为逐字 /draft 的 payloadJson 字节;kid = "root_" + base64url(sha256(spkiDer))[:16]。

获取二进制:Homebrew(zamokctl 在 PATH),见 apps/macapp/Distribution/Homebrew/;开发构建:cd apps/macapp && xcodebuild -scheme zamokctl -configuration Debug -derivedDataPath build/cli build。

root-key 命令:generate 生成新 Ed25519 根并打印 kid 与公钥 PEM;list 列出本地根;export --kid <kid> --out ~/zamok-escrow 写出 .age 与 .identity(两者都需托管,.identity 用于解密 .age);import 从 age 托管或原始私钥 PEM 恢复。建议每个产品一个根以隔离风险。

keyset 命令:zamokctl keyset publish --product <slug> [--kid <root>],先 GET 草稿(需 zamokctl auth login 管理员认证),渲染草稿并显示与已发布 keyset 的差异,确认(CI 可用 --yes)后用根签名逐字 payloadJson,再 POST 发布。它只签名展示过的字节,若服务器展示 payload 与签名 payloadJson 不一致则中止。

完整发布/轮换:每产品生成根→导出托管→在 trusted-roots.json 添加公钥→PR 合并部署→auth login 后逐产品 publish→重建并发布内嵌 trustedRootPublicKeysPEM 与 initialProductKeysetJWS 的客户端。轮换根需重新发布客户端;轮换产品签名密钥只需重发 keyset。trusted-roots.json 变更须走 PR,不可改为环境变量或数据库可变。钥匙串报 OSStatus -50/-34018 说明构建过旧,应使用文件钥匙串存储。