4 密钥策略与权限控制:IAM与密钥策略的区别,最小权限原则在审计中的应用

权限控制是KMS审计的核心环节。很多同学一开始会混淆IAM策略和密钥策略。我刚开始接触KMS时也踩过坑——有一次因为策略写错,导致一个微服务无法解密,排查了半天才发现是密钥策略漏了放行那个角色的Principal。嗯,今天我们就彻底讲清楚这两个东西的区别,以及最小权限原则怎么在审计中落地。

4.1 IAM策略 vs 密钥策略:核心区别

说白了,IAM策略控制的是谁可以对KMS这个服务本身做什么操作——创建密钥、列出密钥、启用/禁用密钥。而密钥策略是直接挂载在特定密钥上的,控制谁可以用这把密钥进行具体的加密、解密、签名等操作。你想想看,一个团队里可能所有人都能申请创建密钥(IAM),但只有少数生产线角色才允许用某把密钥解密数据(密钥策略)。

维度IAM策略密钥策略
作用范围整个AWS账户、用户或角色仅作用于该特定KMS密钥
最大长度6144字符32KB(但不建议写太长)
条件支持支持AWS全局条件 + 服务条件支持(部分条件不适用)
默认权限默认所有用户无权限默认只有根用户有完全控制权
常见用例管理密钥生命周期(创建/删除/轮换)控制谁可以用该密钥进行加解密操作

这里有个关键点:两者是叠加的。AWS KMS授权时,会同时评估IAM策略和密钥策略。只要任何一个策略显式拒绝(Deny),操作就会被拒绝。如果两个策略都没有明确允许,默认拒绝。所以,你如果只给IAM开了Decrypt权限,但密钥策略没加相应主体,调用还是会失败。

4.2 最小权限原则在审计中的应用

审计日志里最常见的问题就是权限过大。比如,给整个AWS账号的IAM用户都授予了kms:Decrypt权限,但实际上只有几个微服务需要解密。这种情况一旦密钥泄露,攻击者就能解密所有受保护的数据。

我建议在审计时重点关注以下几点:

  • 检查密钥策略中是否使用了 "Principal": "*" 或 "Principal": {"AWS": "arn:aws:iam::123456789012:root"} —— 这相当于允许该账号下的所有主体操作。除非必要,否则应该限定到具体的IAM角色或用户。
  • 检查是否缺少条件限制。比如,应该加上 kms:ViaService 条件,限制只能通过特定的AWS服务(如S3、Lambda)调用密钥。
  • 检查是否使用了Deny语句来兜底。比如,对敏感密钥添加Deny语句,拒绝非生产环境的角色调用。
我曾经在审计一个客户的KMS密钥策略时,发现他们给一个外部AWS账号开了完全访问权限,理由是“方便数据共享”。其实完全可以用跨账号角色 + 临时凭证,而不是直接开放永久权限。

4.3 密钥策略实战示例

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Allow production role to decrypt",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/prod-app-role"
      },
      "Action": [
        "kms:Decrypt",
        "kms:GenerateDataKey"
      ],
      "Resource": "*"
    },
    {
      "Sid": "Deny non-production roles",
      "Effect": "Deny",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/dev-*"
      },
      "Action": "kms:*",
      "Resource": "*"
    }
  ]
}

这个策略做了两件事:只允许 prod-app-role 角色进行解密和生成数据密钥;同时显式拒绝所有以 dev- 开头的角色执行任何KMS操作。这样即使dev角色在其他地方有IAM权限,也会被这个Deny挡住。

注意:Deny语句会覆盖任何Allow。所以一旦写成Deny,该主体就彻底无法访问这个密钥,哪怕密钥策略的另一个Statement允许也不行。一定要小心使用Deny,避免把自己锁在外面。

4.4 审计中如何检查策略

我一般用两种方式:

  1. CloudTrail事件历史:搜索 kms:Decrypt 和 kms:GenerateDataKey 的调用记录,看哪些IAM角色/用户在调用。如果发现不预期的调用者,就去查它的权限来源。
  2. AWS Config规则:可以使用托管规则 kms-key-policy-not-public 或自定义Lambda规则,定期扫描密钥策略是否公开。

另外,我个人习惯在CloudWatch Logs中设置告警,当出现“AccessDenied”错误时立即通知。因为很多时候,权限配置错误会导致应用大面积故障,早发现早修复。

KMS权限评估是IAM策略与密钥策略的“与”关系——两个策略都必须允许,并且不能有任何拒绝。审计时抓住“谁被允许,谁被拒绝”这条线,就能快速定位风险。
KMS权限评估流程图 发起请求 IAM策略评估 密钥策略评估 存在Deny? 存在Allow? 拒绝访问 允许访问 说明: Deny优先 至少一个Allow 无Deny才生效