4. 密钥的访问控制:IAM策略与权限管理归纳总结
密钥的访问控制,说白了就是「谁能在什么条件下、对哪把密钥做什么操作」。我过去在帮一家金融客户做KMS迁移时,就因为权限策略没写清楚,导致一个测试账号能删生产密钥……那一次真是惊出一身冷汗。所以这一章我打算把IAM策略和KMS权限管理的核心要点掰开揉碎了讲清楚。
4.1 IAM策略的基本模型
IAM策略分两类:身份策略(贴给用户/角色/组)和资源策略(直接贴到密钥上)。KMS同时支持这两类,但实际项目中我更推荐优先用资源策略——因为密钥的权限边界更清晰。
一个完整的策略文档包含四个要素:
- 主体(Principal):谁可以访问?用ARN指定用户/角色。
- 操作(Action):能做什么?kms:Encrypt、kms:Decrypt、kms:CreateKey 等。
- 资源(Resource):作用于哪些密钥?通常写 "arn:aws:kms:region:account:key/*" 或精确到某个Key ID。
- 条件(Condition):额外的限制,比如来源VPC、加密上下文、请求时间等。
下面这个表格能帮你快速区分两类策略的适用场景:
| 策略类型 | 挂载位置 | 典型使用场景 | 权限范围 |
|---|---|---|---|
| 身份策略 | IAM用户/角色/组 | 给开发人员分配通用加密权限 | 跨多个密钥 |
| 资源策略 | CMK(客户主密钥) | 限制特定密钥只能由特定服务或账号使用 | 只作用于该密钥 |
我个人习惯:平时用资源策略管密钥,只有需要跨密钥批量授权时才用身份策略。这样每个密钥的权限一目了然,审计日志对起来也快。
4.2 细粒度权限设计原则
这里有三条铁律,是我踩过坑后总结出来的:
- 最小权限:给操作员只开放他用得到的那几个API。比如只做加密的人,别给他kms:Decrypt。
- 职责分离:密钥管理员(能创建/删除/轮换密钥)和密钥使用者(只能加解密)必须分开。我曾经把这两个角色混到一个组里,结果有人误删了密钥,所有加密数据全部作废……心疼那几天的恢复工作。
- 条件约束:尽量加上 Condition 限定。比如只允许来自特定VPC的请求,或者只允许带有特定加密上下文的调用。
我曾经遇到一个场景:给Lambda角色赋予了 kms:* 权限。结果Lambda函数被注入恶意代码后,攻击者直接用这个角色删除了所有密钥。教训就是——永远别用通配符 * 在KMS上。就算你图省事,也要用 kms:Encrypt,kms:Decrypt 这样的显式列表。
嗯,这里再补充一个细节:条件里的 kms:ViaService 非常实用。比如你希望某个密钥只给ECS服务用,写在资源策略里:"Condition": { "StringEquals": { "kms:ViaService": "ecs.amazonaws.com" } }。这样就算有人拿着管理员权限发请求,只要不是来自ECS,照样被拒绝。
4.3 常见权限配置模式
讲几个我在生产环境反复用过的模式:
模式一:加密解密权限分离
开发团队用加密权限(Encrypt/GenerateDataKey),运维团队用解密权限(Decrypt)。这样就算开发人员的账号被盗,攻击者也解不了生产数据。
模式二:密钥管理员 vs 密钥使用者
创建一个管理员角色,可以管理密钥生命周期(CreateKey/EnableKeyRotation/ScheduleKeyDeletion);再创建一个使用者角色,只能进行密码运算。两者用不同IAM路径隔离。
模式三:限制加密上下文
在资源策略里强制要求加密上下文匹配某个固定值。例如:"Condition": { "StringEquals": { "kms:EncryptionContext:department": "finance" } }。这样就算有人拿到了密钥,也得知道上下文才能解密——多了一层防护。
下面这张表汇总了三种模式的策略片段:
| 模式 | 关键操作 | 典型条件 | 适用角色 |
|---|---|---|---|
| 读/写分离 | 开发者:Encrypt, GenerateDataKey 运维:Decrypt | 无或按IP限制 | 开发/运维组 |
| 管理/使用分离 | 管理员:CreateKey, EnableKeyRotation 使用者:Encrypt, Decrypt | 管理员可附加kms:ViaService条件 | 安全团队/业务团队 |
| 上下文绑定额 | 同上 | kms:EncryptionContext:appId = "order-service" | 微服务场景 |
写策略时可以先在AWS IAM Policy Simulator里测试,或者用aws kms encrypt --dry-run参数模拟执行。我每次改策略都先跑一遍模拟,确认不会意外拒绝正常业务。
4.4 权限审计与监控
策略写好了,不代表万事大吉。你想想看,业务在变,人员流动也在变。权限会慢慢变宽。我建议你做三件事:
- 激活CloudTrail审计日志:记录每次KMS API调用,至少保留90天。
- 定期用IAM Access Analyzer:它会自动检测哪些策略有「越权」风险。比如某个资源策略允许了匿名主体访问,它会直接报告警。
- 每季度做一次权限Review:把策略文档拉出来,逐个密钥过一遍。问问自己:「这把密钥真的还需要对那个旧角色开放吗?」
我记得有一次Review,发现一个三年前试用的临时角色仍然拥有某个核心密钥的 kms:Decrypt 权限。幸好发现得早,没出事故。从那以后我就把权限Review写进了SOP。
4.5 最佳实践总结
好了,把这一章的核心要点串起来——
- 优先使用资源策略绑定到密钥,权限边界清晰。
- 坚持最小权限:明确列出需要的操作,别用 *。
- 利用Condition强化约束:kms:ViaService、加密上下文、来源IP。
- 分离管理员与使用者角色。
- 定期审计并清理僵尸权限。
密钥的访问控制不是「写一次就完事」,而是需要持续治理的活。但只要你把策略模型吃透、条件用对、审计跟上,就能把风险降到最低。
下面这张图帮你直观理解整个IAM策略与KMS密钥的访问控制关系:
从图里能清楚看到:主体通过策略绑定到操作,而操作最终作用于具体的CMK,而且中间还可以插一层条件来做精细控制。这就是整个KMS访问控制的骨架。记住它,你写策略时就不会乱。