第2章 KMS密钥创建与权限管理:如何创建CMK,IAM策略与密钥策略的配置

先聊聊创建CMK这事儿。很多人以为就是点个按钮完事——嗯,其实是,但背后有很多细节你得心里有数。

2.1 创建CMK:不止是点点点

在KMS里,CMK(Customer Master Key)是所有加密操作的中心。我个人习惯在创建之前先想清楚几个问题:

  • 密钥类型:对称还是非对称?大部分场景对称就够了。但如果你要做数字签名或跨环境公钥分发,就得选非对称。
  • 密钥区域:CMK是区域级别的。我在项目中遇到过一件糗事:在美东创建的密钥,跑到美西去解密,结果报权限错误——你想想看,这得多尴尬。
  • 自动轮换:对称CMK可以开启年度自动轮换。如果合规要求严格,我建议你打开;如果只是内部测试,手动轮换也够用。

创建方式有三种:控制台、CLI、API。我一般用CLI写脚本,方便重复执行。

# 创建一个对称CMK,开启自动轮换
aws kms create-key --origin AWS_KMS --key-usage ENCRYPT_DECRYPT --customer-master-key-spec SYMMETRIC_DEFAULT

# 创建一个非对称CMK,用于数字签名
aws kms create-key --origin AWS_KMS --key-usage SIGN_VERIFY --customer-master-key-spec RSA_2048

创建完记得马上加--tags和--description。我曾经接手过一个项目,200多个CMK全是默认描述,排查起来简直想摔键盘。

个人技巧:创建时用--policy参数直接附加密钥策略,避免事后忘记配置导致密钥变成“谁也碰不了”的死锁状态。

2.2 IAM策略 vs 密钥策略:你到底该配哪个?

很多初学者搞不清这两者的关系。说白了:

  • IAM策略:控制“谁可以调用KMS的API”。比如,是否允许某个用户调用kms:Encrypt。
  • 密钥策略:控制“谁可以用这个具体的密钥”。它是挂在CMK上的资源策略,粒度更细。

两者需要同时满足才能执行操作。想象一下:IAM策略是门禁卡,让你进了大厦;密钥策略是办公室钥匙,让你进了具体房间。缺一不可。

关键规则:当你用IAM管理KMS时,密钥策略必须显式授予IAM账户访问权限。否则就算IAM策略允许,密钥策略也会拦下来。

下面我放个表格,把区别列清楚——

对比项 IAM策略 密钥策略
作用范围 用户/角色/组 单个CMK
管理位置 IAM控制台 KMS控制台(每个CMK单独)
适用场景 统一权限管控 密钥级精细控制
跨账户支持 不支持(跨账户需密钥策略) 支持(通过指定AWS账户)
条件键支持 支持(如kms:ViaService) 同样支持
我曾经踩过的坑:某次我配了一个IAM策略,允许管理员删除任何CMK,但忘了在密钥策略里加一条“允许该管理员删除本密钥”——结果管理员看到密钥列表却删不掉,报403。记住:密钥策略是最后的防线。

2.3 实战配置示例

我们用一个典型需求来演示:让应用服务器(使用IAM角色)可以加密数据,但只限在EC2环境里调用。

第一步:创建IAM策略(附加给EC2角色)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "kms:Encrypt",
        "kms:Decrypt"
      ],
      "Resource": "arn:aws:kms:us-east-1:123456789012:key/xxxx-xxxx-xxxx"
    }
  ]
}

第二步:配置密钥策略

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/AppServerRole"
      },
      "Action": [
        "kms:Encrypt",
        "kms:Decrypt"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "kms:ViaService": "ec2.us-east-1.amazonaws.com"
        }
      }
    }
  ]
}

注意:密钥策略里的Principal如果漏掉根账户,连管理员都会被锁在外面。我就是这么被锁过一次——嗯,还好当时有管理员的备用访问权限。

2.4 权限管理的几个“不要”

  • 不要给IAM用户直接挂kms:*的Admin权限,除非是专人。尽量用角色+临时凭证。
  • 不要忽略kms:ThroughputLimit条件键。有些场景需要限制单个密钥的QPS,防止滥用。
  • 不要把所有密钥放在同一个策略里。用资源ARN区分不同环境(开发/生产)的密钥。
CMK创建与权限管理流程 管理员/应用 IAM角色/用户 KMS API 创建CMK请求 调用API CMK密钥库 密钥策略 附属策略 IAM策略 附加 联合授权 核心原则 IAM策略决定“谁可以调用KMS API”,密钥策略决定“谁可以用某个CMK” 两者必须同时允许,操作才能成功

2.5 常见避坑清单

  1. 权限膨胀:别为了省事给IAM用户配kms:*,你会后悔的。我记得有个项目因为这事被审计警告,花了三天重配策略。
  2. 密钥策略漏了根账户:如果你在其他账户里创建了密钥,别忘了在密钥策略里加上自己账户的根用户作为管理员。否则你自己都改不了策略。
  3. 条件键误用:kms:ViaService很好用,但如果你写错了服务名(比如写了小写),策略会默默失效。大写字母、精确匹配——检查三遍。
  4. 跨账户访问:跨账户用密钥时,密钥策略必须显式赋予对方账户ID,并且对方自己的IAM策略也要Allow。我见过有人只配了一半,两边互相甩锅。
我的生产建议:把密钥策略和IAM策略分开管理。IAM策略交给平台团队统一维护,密钥策略由每个业务团队自行负责。职责清晰,出了问题也好溯源。