← 返回博客列表
安全2026-05-27·5 分钟阅读

Vault 设计 — 我们怎么做到「零知识」持有用户密钥

本平台数据库只持有 secrets_manager_ref(引用名)+ 元数据,实际明文存阿里云 Secrets Manager。所有 fetch / rotate / delete 进 vault_access_log。

"零知识"在加密语境下是个术语,意思是:服务方知道你"有"某个东西,但不知道"是什么"。我们对 Vault 的设计就是这种状态 — 我们知道你有一个微信支付商户 API 密钥,但我们的数据库里没有那串明文。

存储分层

明文层 — 阿里云 Secrets Manager

用户每次写入 Vault 的 secret_value 直接走阿里云 Secrets Manager API,产物是一个 ref(如 acs:kms:cn-hangzhou:xxx:secret/aiops-user-{uid}-{alias}/{version})。明文从此只在阿里云存储,我们的服务端进程读完即弃。

元数据层 — 我们的数据库

vault_entries 表只存:id / user_id / project_id / key_alias / secrets_manager_ref / created_at / last_used_at / expires_at。没有 secret_value。

SELECT key_alias, secrets_manager_ref, last_used_at
FROM vault_entries
WHERE user_id = 'xxx';

-- 即便数据库被攻破,攻击者拿到的也只是引用名,
-- 想拿明文还得攻破阿里云 KMS,这是两个独立信任域。

审计层 — vault_access_log

每次读 / 改 / 轮换 / 删 都进 vault_access_log,带 IP + UA + business_context + success/failure。3 年留存。即便没人盗你的密钥,你也能看到「这个密钥过去 30 天被哪些进程读过」。

客户端模式 — 更彻底的「零接触」

如果你装了桌面客户端,SSH 私钥这种最敏感的东西可以直接存进本机 Keychain(macOS Keychain / Win DPAPI / Linux Secret Service),Vault ref 字段写 `local:ssh-key-alias` 而不是 `acs:kms:...`。服务端从此完全看不到这个密钥的存在 — 这是「零接触」。

从「零知识」到「零接触」是一个递进:第一步是我们不持有明文,第二步是我们连引用都不持有。

同类阅读

评论功能未启用(需要环境变量 NEXT_PUBLIC_UTTERANCES_REPO=owner/repo)