3. AWS KMS 概述
讲到 Secrets Manager 的审计,你绕不开一个核心组件——AWS KMS(Key Management Service)。
说白了,Secrets Manager 的加密能力基本就靠 KMS 撑着。我自己的习惯是:每次做审计排查,第一件事就是翻 KMS 的 CloudTrail 日志。为什么呢?因为很多安全问题,根源其实都在 KMS 的密钥策略或者权限配置上。
3.1 为什么需要 KMS?
在云上管理密钥,最怕什么?
- 密钥明文落盘,容易被 dump 出来
- 密钥分散在各处,轮换全靠人工
- 审计日志不统一,出了问题查不清谁用了密钥
KMS 就是来解决这些问题的。它提供一个集中式的密钥管理平台,所有加密操作都在 KMS 内部完成,密钥材料不离开服务边界。嗯,这一点非常关键。
我记得之前接手一个合规项目,客户需要证明所有敏感数据都是加密存储的。我们就是用 KMS 的 CloudTrail 日志,逐条展示了每个 Secret 的加密时间、操作人、来源 IP。审计方很满意,因为日志里连密钥版本号都有。
3.2 KMS 的密钥层次
KMS 的加密模型是典型的两层结构:
- 主密钥(CMK)——你直接管理的顶级密钥,用于加密/解密数据密钥,不能直接加密大数据(4KB 以内除外)
- 数据密钥(Data Key)——由 CMK 生成的实际加密数据的对称密钥,你拿它去加密业务数据,用完就丢或者持久化存储加密后的版本
这就是 信封加密(Envelope Encryption)。为什么这么做?你想想看,如果每次加密 1GB 的文件都让 KMS 来算,延迟和成本都受不了。数据密钥在客户端本地完成加密,性能好很多。
| CMK 类型 | 来源 | 管理能力 | 轮换控制 | 审计覆盖 |
|---|---|---|---|---|
| AWS 托管 CMK | AWS 服务自动创建 | 只读(不能配置策略) | AWS 自动轮换,不可关闭 | 完整 |
| 客户管理 CMK | 你手动创建 | 完全控制(策略、启用/禁用) | 可选自动轮换,可强制手动轮换 | 完整 |
| 自定义密钥存储(CloudHSM) | 你自己的 HSM 集群 | 完全控制 | 手动轮换 | 需要额外配置 HSM 审计 |
3.3 密钥类型:对称 vs 非对称
KMS 支持这两大类,但日常 Secrets Manager 场景几乎只用对称密钥。
- 对称密钥:加密和解密用同一个密钥。Secrets Manager 的 Encrypt/Decrypt 操作都是对称密钥完成的
- 非对称密钥:包含公私钥对,用于数字签名、加密通信等。Secrets Manager 本身不直接调用非对称密钥,但你可以用它加密外部数据
我个人建议,除非你有非对称签名需求,否则一律用对称 CMK。配置简单,审计日志也更容易解读。
3.4 权限模型与策略
KMS 的权限控制有三层,审计时每一层都得看:
- 密钥策略(Key Policy)——每个 CMK 的第一道防线。定义谁可以对这个密钥做什么操作
- IAM 策略——附加到用户/角色的权限,允许或拒绝特定 KMS 操作
- 授权(Grants)——临时授给其他 AWS 服务(比如 Secrets Manager)的权限,不用改 Key Policy
3.5 密钥轮换与生命周期
密钥轮换是安全最佳实践。KMS 对客户管理 CMK 支持自动轮换(每年一次),你也可以手动创建新的密钥版本。
但有一点要注意:轮换创建的是新密钥版本,而不是替换旧密钥。 旧版本依然存在,可以用于解密历史数据。这就是为什么 KMS 要求你保存所有旧密钥材料——否则之前加密的数据就废了。
删除 CMK 更危险。KMS 有一个等待期(Pending Deletion),默认 30 天。在这个窗口期你还能恢复密钥。一旦等待期结束,密钥被永久删除,所有用它加密的数据将永远无法解密。
3.6 KMS 与 Secrets Manager 的集成
Secrets Manager 对每个 Secret 都可以指定一个 KMS CMK(默认是 aws/secretsmanager)。当你创建或读取 Secret 时,Secrets Manager 会自动调用 KMS 的 Encrypt 和 Decrypt。这些调用会记录在 CloudTrail 中,事件名称是:
GenerateDataKey(创建 Secret 时生成数据密钥)Decrypt(读取 Secret 时解密)ReEncrypt(轮换 Secret 时重新加密)
| 操作 | CloudTrail 事件 | 常见问题 |
|---|---|---|
| 创建 Secret | GenerateDataKey, Encrypt | 如果报 AccessDenied,查 Key Policy 是否允许 Secrets Manager 服务调用 |
| 读取 Secret | Decrypt | 确认 IAM 主体有 kms:Decrypt 权限 |
| 轮换 Secret | GenerateDataKey, Decrypt, ReEncrypt | 需确保 Lambda 轮换函数有相应 KMS 权限 |
你可能会问:为什么 Secrets Manager 不直接用 CMK 直接加密 Secret,而是要用数据密钥?因为 CMK 每次只能加密 4KB 的数据,而 Secrets Manager 的 Secret 最大支持 64KB(加上 JSON 结构有时会超限)。所以它先用 CMK 生成一个数据密钥,再用数据密钥去加密 Secret,最后把加密后的数据密钥和密文一起存下来。这就是信封加密在实战中的应用。
有了这张图,再看 KMS 的审计日志就清晰多了。你只需要关注 generateDataKey 和 decrypt 这两个事件,配合 encryptionContext 里的 secretsmanager: