AWS Secrets Manager 入门:基本概念、创建 Secret、自动轮转、IAM 权限配置

好,我们直接进入正题。AWS Secrets Manager 是做什么的呢?说白了,它就是帮你管密码、、数据库连接串这些敏感信息的托管服务。你不需要再把密钥写在代码里、配在环境变量中,或者找个加密文件到处拷。Secrets Manager 帮你集中存、自动转、精细控权限。

我刚开始用的时候,心里也犯嘀咕:这东西不就是个高级的 Key-Value 存储吗?后来在项目中踩过几次坑才真正明白,它的价值在于自动轮转和细粒度权限。你想想看,如果只是存个密码,那用 Parameter Store 也够。但 Secrets Manager 能帮你定期改密码,而且改的时候业务不受影响,这才是杀手锏。

基本概念:Secret、版本、轮转配置

先理清几个核心术语,后面才不会绕晕。

  • Secret:你要保护的敏感信息本体。它是一段 JSON,可以包含用户名、密码、主机名、端口、密钥字符串等等。
  • 版本:每个 Secret 可以有多个版本(Version ID)。AWS 自动用 AWSCURRENT、AWSPREVIOUS、AWSPENDING 这些标签来标记当前版本、上一个版本、待定版本。轮转时就是靠这些标签切换的。
  • 轮转配置:定义如何自动更换 Secret 值。可以是用 Lambda 函数自定义逻辑,也可以用 AWS 预置的轮转模板(比如 RDS、Redshift 的轮转)。
概念说明典型场景
Secret 本体JSON 格式的加密配置数据库连接串、第三方
版本标签AWSCURRENT / AWSPREVIOUS / AWSPENDING轮转切换时自动更新标签
轮转 Lambda自定义轮转逻辑的函数轮转 LDAP 密码、轮转自定义
加密密钥默认使用 AWS 托管 KMS 密钥也可自建 KMS CMK 来加密

小提示:我个人习惯把 Secret 的 Key 命名得清晰一点,比如 prod/mysql/master-user,这样在 IAM 策略里写资源 ARN 的时候会很方便,一眼就知道控制的是哪个环境的哪个密钥。

创建 Secret:控制台 vs CLI vs SDK

创建 Secret 有三种主流方式,我分别说说。先讲控制台,因为它最直观。登录 AWS 控制台,进入 Secrets Manager 服务,点“存储新的密钥”。这一步会让你选择密钥类型:

  • 其他类型的密钥:自由输入键值对,比如 username 和 password。
  • 数据库凭证:可以直接连接 RDS、Redshift 等数据库,自动给你生成凭证并存入 Secret。
  • 纯文本:直接粘贴一段 JSON 或明文密钥。

选好后,给 Secret 一个名字。名字有讲究,我建议用 环境/服务/用途 这种层级结构。比如 production/rds/main-db。然后配置自动轮转——这一步可以暂时跳过,后门专门讲。

用 CLI 创建其实更常用,尤其是在 CICD 流程里。举个例子:

aws secretsmanager create-secret \
    --name production/rds/main-db \
    --description "Main production database credentials" \
    --secret-string '{"username":"admin","password":"P@ssw0rd123"}' \
    --tags Key=Environment,Value=production Key=Service,Value=rds

嗯,这里要注意:--secret-string 只能传一个字符串或 JSON。如果你的密钥是二进制,可以用 --secret-binary。我个人很少用二进制,大多数场景 JSON 就够了。

SDK 方式适合在应用代码里动态创建,比如新用户注册时自动生成数据库凭证。但说实话,生产环境更推荐提前创建好 Secret,应用只读取不写入,这样更安全。

自动轮转:怎么配,有什么坑

自动轮转是 Secrets Manager 的核心卖点。但不是所有 Secret 都能自动轮转,你必须配置一个 Lambda 函数来执行实际的轮转逻辑。

AWS 针对常见的服务(RDS、Aurora、Redshift、DocumentDB)提供了预置轮转模板。你在创建 Secret 时选择“启用自动轮转”,然后指定一个轮转周期(比如 30 天),再创建一个关联的 Lambda 函数。这个 Lambda 会自动处理以下步骤:

  1. 创建新版本并标记为 AWSPENDING
  2. 调用目标服务修改密码(比如 ALTER USER … PASSWORD)
  3. 测试新密码可用
  4. 将新版本标记为 AWSCURRENT,旧版本降为 AWSPREVIOUS
  5. 删除 AWSPENDING 标签

避坑指南:我曾经在生产环境配置轮转时,忘记给 Lambda 函数授予对 RDS 实例的访问权限。结果轮转失败,新密码没写进去,旧密码又被删了,业务直接打不开。教训就是:轮转前一定要用 IAM 角色模拟测试一次,确保 Lambda 能连接目标服务。

如果你的服务在预置模板之外,就得自己写 Lambda。这不算复杂,但需要你处理好错误回滚。比如,第四步设置新密码失败时,必须能恢复到旧密码。AWS 的轮转函数模板里其实有范例,你可以直接改。

IAM 权限配置:最小权限原则

Secrets Manager 的权限控制,核心是两个部分:读取权限和管理权限。大部分业务场景只需要读取权限,只有运维人员才需要创建、删除、轮转权限。

我给出一个典型的最小权限策略模板:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ReadSecret",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue",
                "secretsmanager:DescribeSecret"
            ],
            "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:production/*"
        },
        {
            "Sid": "DecryptSecret",
            "Effect": "Allow",
            "Action": "kms:Decrypt",
            "Resource": "arn:aws:kms:us-east-1:123456789012:key/your-kms-key-id"
        }
    ]
}

这里要注意:GetSecretValue 本身就是读取明文密钥,所以这个权限一定要严格控制。另外,如果你用了自定义 KMS 密钥加密 Secret,还要加 kms:Decrypt 权限。

对于管理权限,你还需要:

  • secretsmanager:CreateSecret、secretsmanager:DeleteSecret
  • secretsmanager:RotateSecret、secretsmanager:CancelRotateSecret
  • secretsmanager:PutSecretValue(更新 Secret 值)
  • secretsmanager:TagResource(管理标签)

为什么会这样设计?因为如果你给应用服务器也赋予 DeleteSecret 权限,万一某个环节被攻破,攻击者可以删除所有密钥,那就完蛋了。所以我建议:读取权限给应用,管理权限给人。

核心要点:Secrets Manager 的 IAM 权限配置,本质上是把“谁可以读”和“谁可以写”彻底分开。读权限用 GetSecretValue + kms:Decrypt,写权限用 CreateSecret + PutSecretValue + RotateSecret。不要混在一起给。

本章知识结构

我们来看这张图,它把 Secrets Manager 的核心逻辑串起来了。从 Secret 定义开始,到创建、存储、读取,再到自动轮转和 IAM 权限控制,每一步都有对应的 IAM 权限和 Lambda 函数支持。

AWS Secrets Manager 知识逻辑图 AWS Secrets Manager 核心逻辑 Secret(密钥本体) 控制台创建 CLI 创建 SDK 创建 版本管理(标签切换) 自动轮转 (Lambda + 轮转模板) IAM 权限控制 (读/写分离 + KMS) 读取:GetSecretValue + kms:Decrypt | 管理:CreateSecret + PutSecretValue + RotateSecret