第4章:Secrets Manager 与 KMS 的关系

很多朋友刚接触 Secrets Manager 时,会把它和 KMS 搞混。

其实它俩是两码事。但配合起来,堪称绝配。

KMS 负责加密,Secrets Manager 负责存密文。

一个管钥匙,一个管保险柜。缺一不可。

4.1 各自扮演什么角色?

先看 KMS。它是 AWS 的密钥管理服务。

核心能力:生成、存储、轮换、销毁加密密钥。

它不保存你的数据库密码、API 。

它只保存用来加密这些密码的“根密钥”——我们叫 CMK。

再看 Secrets Manager。

它的职责是安全地存储、轮换、审计敏感信息。

但它自己不做加密。它问 KMS 要钥匙。

我习惯打个比方:

  • KMS = 银行的保险库总管。他只管钥匙,不管箱子里装什么。
  • Secrets Manager = 租用保险箱的客户。他把箱子锁好,钥匙交给总管保管。

你想想看,如果 Secrets Manager 自己加密自己,那密钥存哪儿?

存自己硬盘里?那就变成了“自己锁自己”,审计和合规根本过不了。

核心结论:KMS 是加密引擎,Secrets Manager 是存储与生命周期引擎。两者通过“信封加密”机制协作。

4.2 加密流程是怎样的?

大致分三步。我一步步拆给你看。

  1. 创建 Secret 时:Secrets Manager 调用 KMS 的 GenerateDataKey API。KMS 返回一个明文数据密钥和一个密文数据密钥。明文密钥只存在内存里,用来加密你的密码。加密完后,内存里的明文密钥立即丢弃。密文数据密钥随密文一起存入 Secrets Manager。
  2. 读取 Secret 时:应用程序发起读取请求。Secrets Manager 取出密文数据密钥,发送给 KMS。KMS 用 CMK 解密它,返回明文数据密钥。Secrets Manager 用这个明文密钥解密你的密码,最后把明文返回给应用。
  3. 整个过程:你的 CMK 从未离开过 KMS 硬件安全模块(HSM)。数据密钥也只短暂出现在内存里。磁盘上全是密文。

我在处理一个金融客户的项目时,客户安全团队非要看加解密的完整链路。

我就用下面这张图跟他们解释的。一目了然。

Secrets Manager 与 KMS 加密流程图 Secrets Manager 与 KMS 加密/解密流程 应用 / SDK Secrets Manager KMS (CMK) 加密存储 (密文) 1. 读取请求 2. 发送密文数据密钥 3. 返回明文数据密钥 4. 返回明文密码 创建时:GenerateDataKey CMK 全程不离开 KMS HSM;数据密钥仅短暂出现在内存中

实践建议:生产环境中,强烈推荐使用 KMS 自动密钥轮换。每年轮换一次 CMK,可以大幅降低密钥泄露的风险敞口。

4.3 权限边界在哪里?

两者权限模型不同,不能混为一谈。

维度 KMS Secrets Manager
核心资源 CMK (Customer Master Key) Secret
关键 API Encrypt, Decrypt, GenerateDataKey GetSecretValue, PutSecretValue
权限控制 密钥策略 + IAM 策略 资源策略 + IAM 策略
审计日志 CloudTrail 记录 KMS 操作 CloudTrail 记录 Secrets Manager 操作
频率限制 默认 5,500 请求/秒(可提额) 默认 200 请求/秒(可提额)

从审计角度看,这两类日志要分开审。

KMS 日志告诉你“谁在什么时候用了哪把钥匙”。

Secrets Manager 日志告诉你“谁在什么时候拿了哪个密码”。

配合起来,才能完整还原一次敏感操作的链路。

我曾经遇到一个事故:开发团队直接给了 Secrets Manager 全量 KMS 权限。结果某个微服务被攻破,攻击者不仅拿到了数据库密码,还能用同样的密钥去解密其他服务的秘密。教训是什么?权限必须最小化。Secrets Manager 只需要特定 CMK 的 Decrypt 和 GenerateDataKey 权限,别的都用不上。

4.4 审计时应该盯哪些点?

作为审计专家,我每次看 Secrets Manager + KMS 的配置,都会查这四件事:

  1. 密钥策略是否过于宽松?KMS 的密钥策略如果允许“*”主体,等于裸奔。
  2. 是否开启了 CloudTrail 数据事件?有些团队只记录管理事件,不记录 KMS 的数据事件。数据事件才是加解密操作的细粒度记录。
  3. Secrets Manager 是否用了自定义 KMS key?用默认的 AWS-managed key 也可以,但无法做密钥轮换或跨账户授权。我一般建议用客户管理的 CMK。
  4. Secrets Manager 的轮换配置是否依赖 KMS?轮换涉及重新加密,离不开 KMS 的参与。如果 KMS 权限配置不当,轮换会自动失败,而且没有明显告警。

最佳实践:在 CloudTrail 中创建一个 KMS 数据事件的专用跟踪。再创建一个 Secrets Manager 管理事件的跟踪。两套日志关联查询,能快速定位“谁在什么时间、通过哪个应用、访问了哪个密钥、解密了哪个密码”。

4.5 代码示例:创建时指定 KMS Key

用 CLI 创建一个 Secrets Manager 并指定自定义 KMS key,很简单:

aws secretsmanager create-secret \
    --name prod/db-password \
    --secret-string "MyP@ssw0rd!" \
    --kms-key-id "arn:aws:kms:us-east-1:123456789012:key/abcd1234-..."

用别的方式实现也一样。SDK、Terraform、CloudFormation 都支持 KmsKeyId 参数。

小技巧:如果你不指定 kms-key-id,Secrets Manager 会用区域默认的 AWS-managed key。但这个 key 你无法控制轮换策略,也不方便跨账户共享。生产环境还是自己创建一个 CMK 吧。

好了,到这里你应该搞清楚了:

  • KMS 是加密基础设施。
  • Secrets Manager 是秘密生命周期管理。
  • 两者通过信封加密和 API 调用协作。
  • 审计时,必须同时盯住 KMS 数据事件和 Secrets Manager 管理事件。