第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 加密流程是怎样的?
大致分三步。我一步步拆给你看。
- 创建 Secret 时:Secrets Manager 调用 KMS 的
GenerateDataKeyAPI。KMS 返回一个明文数据密钥和一个密文数据密钥。明文密钥只存在内存里,用来加密你的密码。加密完后,内存里的明文密钥立即丢弃。密文数据密钥随密文一起存入 Secrets Manager。 - 读取 Secret 时:应用程序发起读取请求。Secrets Manager 取出密文数据密钥,发送给 KMS。KMS 用 CMK 解密它,返回明文数据密钥。Secrets Manager 用这个明文密钥解密你的密码,最后把明文返回给应用。
- 整个过程:你的 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 的配置,都会查这四件事:
- 密钥策略是否过于宽松?KMS 的密钥策略如果允许“*”主体,等于裸奔。
- 是否开启了 CloudTrail 数据事件?有些团队只记录管理事件,不记录 KMS 的数据事件。数据事件才是加解密操作的细粒度记录。
- Secrets Manager 是否用了自定义 KMS key?用默认的 AWS-managed key 也可以,但无法做密钥轮换或跨账户授权。我一般建议用客户管理的 CMK。
- 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 管理事件。