AWS Secrets Manager + Parameter Store 凭证管理实战:从硬编码到零泄露完整教程(2026最新版)
Meta Description: AWS Secrets Manager 和 Parameter Store 凭证管理完整教程:创建密钥、IAM 权限策略、Lambda/RDS/ECS 集成、自动轮换、价格对比与成本优化,告别硬编码零泄露实战指南。
- 前言
- 为什么必须用密钥管理服务:硬编码的 5 大风险
- Secrets Manager vs Parameter Store:选哪个?
- 实战一:用 Secrets Manager 管理数据库密码
- 实战二:用 Parameter Store 管理配置参数
- IAM 权限策略:谁能读哪些密钥
- 实战三:Lambda + Secrets Manager 集成
- 实战四:RDS 自动轮换密码
Meta Description: AWS Secrets Manager 和 Parameter Store 凭证管理完整教程:创建密钥、IAM 权限策略、Lambda/RDS/ECS 集成、自动轮换、价格对比与成本优化,告别硬编码零泄露实战指南。
关键词:AWS Secrets Manager、AWS Parameter Store、密钥管理、凭证轮换、IAM策略、Lambda密钥、RDS密码、SSM Parameter Store、AWS安全合规
前言
先给结论:把数据库密码、API Key、第三方服务凭证硬编码在代码或环境变量里,是 AWS 账号被入侵的第一大入口。 AWS 提供了两个原生工具来解决这个问题:Secrets Manager(管理动态密钥,支持自动轮换)和 Systems Manager Parameter Store(管理配置参数和静态密钥)。选哪个?动态密钥选 Secrets Manager(数据库密码、API Key),静态配置选 Parameter Store(Region、环境标志),两者搭配用最省钱。 本文基于 2026 年最新 AWS 控制台和 CLI 实操,手把手带你从"密钥散落在代码里"升级到"集中管理、自动轮换、零泄露"的安全架构。
一、为什么必须用密钥管理服务:硬编码的 5 大风险
在动手之前,先看看不用密钥管理服务会怎样:
| 风险 | 场景 | 后果 |
|---|---|---|
| 代码泄露 | 开发者把含密码的代码推到 GitHub | 数据库被拖库,勒索赎金 |
| 环境变量暴露 | Docker inspect、/proc/xxx/environ 可读 | 容器逃逸后凭证一览无余 |
| 无法轮换 | 密码写死在 10 个服务里 | 一次泄露 = 手动改 10 处,漏改就等着被攻击 |
| 审计缺失 | 谁在什么时候读了密码?不知道 | 出了安全事件无法溯源 |
| 合规失败 | SOC2、PCI-DSS、等保 2.0 审计 | 被判定不合规,丢客户 |
AWS 官方推荐的架构:所有敏感信息存入 Secrets Manager 或 Parameter Store,应用通过 IAM 策略按需获取,访问日志全部进 CloudTrail。
二、Secrets Manager vs Parameter Store:选哪个?
很多人搞不清这两个服务的区别。简单记:Secrets Manager 管"秘密"(密码、密钥),Parameter Store 管"参数"(配置、环境变量)。 详细对比:
| 对比维度 | Secrets Manager | Parameter Store |
|---|---|---|
| 适合存储 | 数据库密码、API Key、OAuth Token、证书 | 环境标志、Region、配置字符串、非敏感参数 |
| 自动轮换 | ✅ 原生支持(RDS/Redshift/DocumentDB/Aurora) | ❌ 不支持 |
| 加密 | 自动 KMS 加密 | 支持 Standard(免费)和 SecureString(KMS 加密) |
| 版本管理 | ✅ 自动多版本,可回滚 | ✅ 支持参数版本 |
| 跨区域复制 | ✅ 原生跨区域复制 | ❌ 不支持 |
| 付费模式 | $0.40/密钥/月 + $0.05/10,000 次 API 调用 | Standard 参数免费,SecureString 免费(API 调用免费) |
| 免费额度 | 无 | Standard 参数无限免费,SecureString 免费 |
| 最大参数大小 | 64 KB | Standard: 4 KB,高级参数: 8 KB |
| CloudTrail 审计 | ✅ 自动记录所有 API 调用 | ✅ 自动记录所有 API 调用 |
决策口诀:
- 数据库密码、API Key、需要自动轮换的 → Secrets Manager
- 环境标志、配置字符串、非敏感信息 → Parameter Store Standard
- 大于 4KB 但小于 8KB 的加密配置 → Parameter Store SecureString
三、实战一:用 Secrets Manager 管理数据库密码
3.1 控制台操作:创建一个数据库密钥
登录 AWS 控制台,搜索"Secrets Manager",点击"存储新密钥"。
选择"数据库凭证",然后选择数据库类型(以 MySQL 为例):
- 密钥名称:
prod/myapp/mysql - 描述:生产环境 MySQL 数据库密码
- 数据库:选择已有的 RDS 实例(或手动输入连接信息)
- 用户名:
admin - 密码:选择"自动生成"(推荐,16 位随机密码)
- 加密密钥:使用默认的
aws/secretsmanager - 轮换:暂不配置(下面单独讲)
点击"存储",密钥创建完成。记下密钥 ARN(后续 IAM 策略和代码集成要用)。
3.2 CLI 操作:批量创建密钥
如果需要一次性创建多个密钥,用 CLI 更高效:
// 创建 MySQL 数据库密钥
aws secretsmanager create-secret \
--name "prod/myapp/mysql" \
--description "Production MySQL credentials" \
--secret-string '{"username":"admin","password":"MyStr0ng!Pass2026"}' \
--region us-east-1
// 创建 Redis 密钥
aws secretsmanager create-secret \
--name "prod/myapp/redis" \
--description "Production Redis auth token" \
--secret-string '{"host":"my-redis.xxx.cache.amazonaws.com","port":"6379","auth_token":"r3d1s_T0k3n_2026"}' \
--region us-east-1
// 创建第三方 API Key
aws secretsmanager create-secret \
--name "prod/myapp/stripe-api-key" \
--description "Stripe payment gateway API key" \
--secret-string 'sk_live_xxxxxxxxxxxxxxxxxxxxxxxx' \
--region us-east-1
关键点:密钥名称用 / 分隔表示层级结构(prod/myapp/mysql),方便后续按前缀批量授权。
3.3 读取密钥:Python + Boto3
import boto3
import json
def get_secret(secret_name):
"""从 Secrets Manager 获取密钥,带本地缓存"""
client = boto3.client('secretsmanager', region_name='us-east-1')
try:
response = client.get_secret_value(SecretId=secret_name)
secret = json.loads(response['SecretString'])
return secret
except client.exceptions.ResourceNotFoundException:
print(f"密钥 {secret_name} 不存在")
return None
except client.exceptions.AccessDeniedException:
print(f"没有权限读取 {secret_name},检查 IAM 策略")
return None
// 使用示例
db_cred = get_secret('prod/myapp/mysql')
if db_cred:
conn = pymysql.connect(
host='mydb.xxx.rds.amazonaws.com',
user=db_cred['username'],
password=db_cred['password'],
database='myapp'
)
性能优化提示:Boto3 客户端默认每次调用 AWS API 都会发起网络请求。在 Lambda 中建议用 aws-lambda-powertools 库的缓存功能,或自己实现 LRU 缓存,避免每次请求都读 Secrets Manager($0.05/万次 API 调用会累积)。
四、实战二:用 Parameter Store 管理配置参数
4.1 控制台操作:创建参数
搜索"Systems Manager" → "参数存储" → "创建参数":
- 名称:
/myapp/prod/region - 类型:String
- 值:
us-east-1 - 描述:应用部署区域
对于敏感配置,选择"SecureString"类型(使用 KMS 加密):
- 名称:
/myapp/prod/redis-host - 类型:SecureString
- 值:
my-redis.xxx.cache.amazonaws.com
4.2 CLI 操作:批量创建参数
// 创建普通字符串参数
aws ssm put-parameter \
--name "/myapp/prod/region" \
--type "String" \
--value "us-east-1" \
--description "App deployment region"
// 创建 SecureString 参数
aws ssm put-parameter \
--name "/myapp/prod/redis-host" \
--type "SecureString" \
--value "my-redis.xxx.cache.amazonaws.com" \
--description "Redis cluster endpoint"
// 创建带标签的参数(方便批量管理)
aws ssm put-parameter \
--name "/myapp/prod/max-connections" \
--type "String" \
--value "100" \
--tags "Key=Environment,Value=prod" "Key=App,Value=myapp"
4.3 高级参数(Advanced Parameters)
如果参数值超过 4KB(比如存储完整的 JSON 配置文件),需要使用高级参数:
aws ssm put-parameter \
--name "/myapp/prod/app-config" \
--type "String" \
--value '{"database":{"pool_size":20,"timeout":30},"cache":{"ttl":3600}}' \
--tier "Advanced" \
--description "Full app configuration JSON"
高级参数的限制:8KB 大小上限,每月前 10,000 次 API 调用免费,之后 $0.05/万次。对于绝大多数应用,高级参数完全够用。
五、IAM 权限策略:谁能读哪些密钥
IAM 策略是安全的核心——最小权限原则:只给应用它需要的密钥访问权限,不多给一个。
5.1 Lambda 读取特定密钥的策略
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadMyAppSecrets",
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"ssm:GetParameter",
"ssm:GetParameters"
],
"Resource": [
"arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/myapp/*",
"arn:aws:ssm:us-east-1:123456789012:parameter/myapp/prod/*"
]
},
{
"Sid": "DecryptSecureStrings",
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "arn:aws:kms:us-east-1:123456789012:key/xxx",
"Condition": {
"StringEquals": {
"kms:ViaService": "ssm.us-east-1.amazonaws.com"
}
}
}
]
}
5.2 限制只能读最新版本
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadOnlyLatestVersion",
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:us-east-1:*:secret:prod/myapp/*",
"Condition": {
"StringEquals": {
"secretsmanager:VersionStage": "AWSCURRENT"
}
}
}
]
}
安全提醒:永远不要给 secretsmanager:DeleteSecret 或 ssm:DeleteParameter 权限给应用角色——只有管理员才能删除密钥。
六、实战三:Lambda + Secrets Manager 集成
6.1 在 Lambda 中读取密钥
import boto3
import json
from functools import lru_cache
@lru_cache(maxsize=1)
def get_db_config():
"""带 LRU 缓存的密钥获取(Lambda 容器复用时不会重复请求)"""
client = boto3.client('secretsmanager', region_name='us-east-1')
response = client.get_secret_value(SecretId='prod/myapp/mysql')
return json.loads(response['SecretString'])
def lambda_handler(event, context):
config = get_db_config()
// 使用密钥建立数据库连接
import pymysql
conn = pymysql.connect(
host=config['host'],
user=config['username'],
password=config['password'],
database=config['dbname'],
cursorclass=pymysql.cursors.DictCursor
)
// 你的业务逻辑...
return {'statusCode': 200, 'body': 'OK'}
关键优化:Lambda 容器可能被复用(warm start),用 @lru_cache 缓存密钥可以避免重复调用 Secrets Manager API,既省钱又降低延迟。
6.2 Lambda 环境变量中引用密钥(推荐)
AWS 支持在 Lambda 环境变量中直接引用 Secrets Manager 和 Parameter Store 的值:
在 Lambda 配置 → 环境变量 → 编辑中:
- 键:
DB_SECRET - 值:
{"SecretsManager": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/myapp/mysql"}
这样在代码中直接用 os.environ['DB_SECRET'] 即可获取,无需在代码中 import boto3,既简化代码又更安全。
七、实战四:RDS 自动轮换密码
Secrets Manager 最强大的功能是自动轮换数据库密码——设置一次,AWS 每 30 天自动改密码,应用通过密钥名读取最新密码,完全无感。
7.1 启用轮换(控制台)
- 打开 Secrets Manager → 选择密钥
- 点击"轮换"标签页 → "编辑轮换配置"
- 轮换 Lambda:选择或创建一个轮换函数(AWS 提供了 RDS MySQL/PostgreSQL 的预置模板)
- 轮换间隔:30 天(最短可设 1 天)
- KMS 密钥:使用默认即可
7.2 CLI 启用轮换
// 为 RDS MySQL 密钥配置自动轮换
aws secretsmanager rotate-secret \
--secret-id "prod/myapp/mysql" \
--rotation-lambda-arn "arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRDSMySQLRotationSingleUser" \
--rotation-rules '{"AutomaticallyAfterDays":30}' \
--region us-east-1
7.3 轮换流程原理
- Secrets Manager 调用轮换 Lambda
- Lambda 生成新密码
- Lambda 在数据库中更新密码
- Lambda 在 Secrets Manager 中更新密钥值
- Lambda 验证新密码能正常连接
- 完成,旧密码被标记为
AWSPREVIOUS
整个过程不到 30 秒,应用完全无感知——下次读取密钥时自动获得新密码。
八、价格对比与成本优化
8.1 价格对比表
| 方案 | 月固定成本 | API 调用费 | 自动轮换 | 适合场景 |
|---|---|---|---|---|
| Secrets Manager | $0.40/密钥 | $0.05/万次 | ✅ 原生支持 | 数据库密码、API Key、需要轮换的密钥 |
| Parameter Store Standard | 免费 | 免费 | ❌ | 环境标志、配置字符串、非敏感参数 |
| Parameter Store Advanced | 免费(前10K次) | $0.05/万次 | ❌ | 大于 4KB 的配置(JSON 配置文件) |
| 环境变量(硬编码) | 免费 | — | ❌ | ⚠️ 不推荐用于敏感信息 |
8.2 成本优化策略
策略 1:混合使用,省钱 80%
不要所有东西都塞进 Secrets Manager。实际拆分:
- Secrets Manager($0.40/个/月):数据库密码、Stripe API Key、SendGrid API Key 等真正需要轮换的密钥
- Parameter Store Standard(免费):Region、环境标志、最大连接数、日志级别等非敏感配置
假设你有 5 个数据库密钥 + 20 个配置参数:
- 全用 Secrets Manager:5 × $0.40 = $2.00/月 + API 调用费
- 混合使用:5 × $0.40 = $2.00/月 + 0(Parameter Store 免费)
策略 2:在 Lambda 中缓存密钥
每次 Lambda 调用都读 Secrets Manager = $0.05/万次。如果 Lambda 每天被调用 10 万次,一年 API 调用费 = $18.25。用 @lru_cache 缓存后,每次容器启动只读一次,成本降到约 $0.06/年(1000 个容器 × $0.05/万次 × 12 月)。
策略 3:合并同类型密钥
一个 Secrets Manager 密钥可以存储 JSON 格式的多个字段。把同一服务的多个凭证合并到一个密钥里(如 {"host":"...","port":"...","username":"...","password":"..."}),减少密钥数量。
九、ECS/EKS 集成:容器化应用的密钥管理
9.1 ECS Fargate 读取 Secrets
在 ECS 任务定义中,可以直接将 Secrets Manager 和 Parameter Store 的值映射为容器环境变量:
{
"containerDefinitions": [
{
"name": "myapp",
"image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest",
"secrets": [
{
"name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/myapp/mysql:password::"
}
],
"environment": [
{
"name": "DB_HOST",
"valueFrom": "arn:aws:ssm:us-east-1:123456789012:parameter/myapp/prod/db-host"
}
]
}
]
}
关键区别:secrets 字段从 Secrets Manager 获取,environment 字段从 Parameter Store 获取。容器启动时自动注入,不需要在代码中调用任何 SDK。
9.2 EKS(Kubernetes)集成
在 Kubernetes 中使用 External Secrets Operator 或 AWS Secrets Store CSI Driver:
// 使用 CSI Driver 将密钥挂载为 Volume
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: aws-secrets
spec:
provider: aws
parameters:
objects: |
- objectName: "prod/myapp/mysql"
objectType: "secretsmanager"
jmesPath:
- path: username
objectAlias: db-username
- path: password
objectAlias: db-password
这样密钥会以文件形式挂载到 Pod 的 /mnt/secrets/ 目录,应用从文件读取即可。
十、审计与监控:谁在什么时候读了密钥
10.1 CloudTrail 审计
所有 Secrets Manager 和 Parameter Store 的 API 调用都会自动记录到 CloudTrail。在 CloudTrail 控制台搜索:
- 事件源:
secretsmanager.amazonaws.com或ssm.amazonaws.com - 事件名称:
GetSecretValue、PutSecretValue、RotateSecret
10.2 设置异常检测告警
// 用 CloudWatch 监控异常的密钥读取行为
aws cloudwatch put-metric-alarm \
--alarm-name "ExcessiveSecretReads" \
--metric-name "GetSecretValue" \
--namespace "AWS/SecretsManager" \
--statistic Sum \
--period 300 \
--threshold 100 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 1 \
--alarm-actions "arn:aws:sns:us-east-1:123456789012:security-alerts" \
--region us-east-1
如果某个 Lambda 函数在 5 分钟内读了 100 次密钥,说明可能有死循环或配置错误,立即收到告警。
十一、常见问题 FAQ
Q: Secrets Manager 和 Parameter Store 能一起用吗?
可以,而且推荐这样做。实际架构中,一个应用通常同时使用两者:Secrets Manager 存放数据库密码、API Key 等需要轮换的密钥,Parameter Store 存放环境标志、配置参数等非敏感信息。Lambda 和 ECS 都支持同时引用两个服务。
Q: Secrets Manager 的 $0.40/密钥/月 贵吗?
不贵。10 个密钥 = $4/月,换取的是自动轮换、集中审计、零泄露风险。相比之下,一次数据库泄露的损失(数据恢复、客户赔偿、品牌声誉)远超 $4/月。而且 Parameter Store Standard 是完全免费的,非敏感配置不用花钱。
Q: Lambda 冷启动时读 Secrets Manager 会更慢吗?
会有 50-100ms 的额外延迟(首次调用时)。解决方案:① 用 Lambda 环境变量引用密钥(容器启动时自动注入,不需要在代码中调用 API);② 用 @lru_cache 缓存密钥(warm start 时零延迟);③ 用 Provisioned Concurrency 保持容器热。
Q: 密钥轮换后,旧的密码还能用吗?
轮换完成后,旧密码被标记为 AWSPREVIOUS,默认 24 小时后自动删除。在 24 小时窗口内,使用旧版本标签仍可读取旧密码。这是为了在轮换出问题时可以快速回滚。生产环境建议设置为 0 天(立即删除旧版本)。
Q: Parameter Store 的高级参数和 Secrets Manager 价格一样吗?
不一样。高级参数 API 调用 $0.05/万次(和 Secrets Manager 相同),但没有 $0.40/月的固定费用。对于需要加密但不需要轮换的配置,高级参数比 Secrets Manager 便宜。
Q: 如何跨账号共享密钥?
Secrets Manager 支持跨账号共享:在密钥的资源策略中添加目标账号的 ARN 即可。Parameter Store 不支持跨账号,但可以用 CloudFormation StackSets 在多个账号中同步创建相同参数。
总结
凭证管理是 AWS 安全的基石。从"密码写在代码里"到"Secrets Manager + Parameter Store"的迁移,核心就三步:
- 分类:敏感密钥(密码、API Key)放 Secrets Manager,配置参数放 Parameter Store
- 授权:用 IAM 策略按前缀精细控制谁能读哪些密钥
- 轮换:对数据库密码启用自动轮换,对 API Key 设置定期提醒手动轮换
⚠️ 文中价格为 2026 年参考价,实际费用随区域和官方调价变动,请以 AWS 官网为准。
🚀 需要 AWS 国际版账号?通过 3.chengzicloud.cloud 获取最新注册教程与专属优惠,助你轻松上云。
本文由 3.chengzicloud.cloud 提供,点击访问首页了解更多