mcpField
S
secrets-manager

secrets-manager

github.com/itsmostafa安全1.2k155 次安装2 天前更新
代码仓库

关于 secrets-manager

面向需要管理 AWS 应用密钥的开发者,介绍 AWS Secrets Manager 的存储、读取和轮换方式。指南覆盖密钥版本、CLI、缓存、访问控制和问题排查。

主要功能

  1. 01加密存储密钥与凭证
  2. 02读取、更新和管理密钥版本
  3. 03使用 Lambda 自动轮换凭证
  4. 04缓存密钥以减少 API 调用
  5. 05CLI 命令与访问控制参考

适用场景

  1. 01存储应用数据库凭证和 API 密钥
  2. 02定期轮换数据库凭证
  3. 03在应用中读取并缓存密钥
  4. 04排查访问权限或轮换失败

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/itsmostafa/aws-agent-skills --skill secrets-manager

安装后在 Claude Code 中输入/secrets-manager确认已加载。

附带文件rotation-strategies.md

详细介绍

AWS Secrets Manager

AWS Secrets Manager 可帮助保护对应用程序、服务和 IT 资源的访问。存储、检索凭证、API 密钥和其他密钥,并自动轮换它们。

目录

核心概念

密钥

存储在 Secrets Manager 中的加密数据。可以包含:

  • 数据库凭证
  • API 密钥
  • OAuth 令牌
  • 任意键值对(最大 64 KB)
版本

每个密钥可以有多个版本:

  • AWSCURRENT:当前活动版本
  • AWSPENDING:正在轮换到的版本
  • AWSPREVIOUS:上一版本
轮换

使用 Lambda 函数自动轮换凭证。内置支持:

  • Amazon RDS
  • Amazon Redshift
  • Amazon DocumentDB
  • 自定义密钥

常见模式

创建密钥

AWS CLI:

# Create secret with JSON
aws secretsmanager create-secret \
  --name prod/myapp/database \
  --description "Production database credentials" \
  --secret-string '{"username":"admin","password":"MySecurePassword123!","host":"mydb.cluster-xyz.us-east-1.rds.amazonaws.com","port":5432,"database":"myapp"}'

# Create secret with binary data
aws secretsmanager create-secret \
  --name prod/myapp/certificate \
  --secret-binary fileb://certificate.pem

boto3:

import boto3
import json

secrets = boto3.client('secretsmanager')

response = secrets.create_secret(
    Name='prod/myapp/database',
    Description='Production database credentials',
    SecretString=json.dumps({
        'username': 'admin',
        'password': 'MySecurePassword123!',
        'host': 'mydb.cluster-xyz.us-east-1.rds.amazonaws.com',
        'port': 5432,
        'database': 'myapp'
    }),
    Tags=[
        {'Key': 'Environment', 'Value': 'production'},
        {'Key': 'Application', 'Value': 'myapp'}
    ]
)
检索密钥
import boto3
import json

secrets = boto3.client('secretsmanager')

def get_secret(secret_name):
    response = secrets.get_secret_value(SecretId=secret_name)

    if 'SecretString' in response:
        return json.loads(response['SecretString'])
    else:
        import base64
        return base64.b64decode(response['SecretBinary'])

# Usage
credentials = get_secret('prod/myapp/database')
db_password = credentials['password']
缓存密钥
from aws_secretsmanager_caching import SecretCache, SecretCacheConfig

# Configure cache
cache_config = SecretCacheConfig(
    max_cache_size=100,
    secret_refresh_interval=3600,
    secret_version_stage_refresh_interval=3600
)

cache = SecretCache(config=cache_config)

def get_cached_secret(secret_name):
    secret = cache.get_secret_string(secret_name)
    return json.loads(secret)
更新密钥
# Update secret value
aws secretsmanager update-secret \
  --secret-id prod/myapp/database \
  --secret-string '{"username":"admin","password":"NewPassword456!"}'

# Put new version with staging labels
aws secretsmanager put-secret-value \
  --secret-id prod/myapp/database \
  --secret-string '{"username":"admin","password":"NewPassword456!"}' \
  --version-stages AWSCURRENT
为 RDS 启用轮换
aws secretsmanager rotate-secret \
  --secret-id prod/myapp/database \
  --rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRDSPostgreSQLRotation \
  --rotation-rules AutomaticallyAfterDays=30
创建并启用轮换的密钥
# Use CloudFormation for RDS secret with rotation
aws cloudformation deploy \
  --template-file rds-secret.yaml \
  --stack-name rds-secret
# rds-secret.yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  DBSecret:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: prod/myapp/database
      GenerateSecretString:
        SecretStringTemplate: '{"username": "admin"}'
        GenerateStringKey: password
        PasswordLength: 32
        ExcludeCharacters: '"@/\'

  DBSecretRotation:
    Type: AWS::SecretsManager::RotationSchedule
    Properties:
      SecretId: !Ref DBSecret
      RotationLambdaARN: !GetAtt RotationLambda.Arn
      RotationRules:
        AutomaticallyAfterDays: 30
在 Lambda 中使用扩展
import json
import urllib.request

def handler(event, context):
    # Use AWS Parameters and Secrets Lambda Extension
    secrets_port = 2773
    secret_name = 'prod/myapp/database'

    url = f'http://localhost:{secrets_port}/secretsmanager/get?secretId={secret_name}'
    headers = {'X-Aws-Parameters-Secrets-Token': os.environ['AWS_SESSION_TOKEN']}

    request = urllib.request.Request(url, headers=headers)
    response = urllib.request.urlopen(request)
    secret = json.loads(response.read())['SecretString']

    credentials = json.loads(secret)
    return credentials

CLI 参考

密钥管理
命令说明
aws secretsmanager create-secret创建密钥
aws secretsmanager describe-secret获取密钥元数据
aws secretsmanager get-secret-value检索密钥值
aws secretsmanager update-secret更新密钥
aws secretsmanager delete-secret删除密钥
aws secretsmanager restore-secret恢复已删除的密钥
aws secretsmanager list-secrets列出密钥
版本
命令说明
aws secretsmanager put-secret-value添加新版本
aws secretsmanager list-secret-version-ids列出版本
aws secretsmanager update-secret-version-stage移动暂存标签
轮换
命令说明
aws secretsmanager rotate-secret配置/触发轮换
aws secretsmanager cancel-rotate-secret取消轮换

最佳实践

密钥组织
  • 使用分层名称:environment/application/secret-type
  • 为密钥添加标签,以便组织管理和成本分配
  • 按环境区分(dev、staging、prod)
安全
  • 使用资源策略控制访问
  • 使用客户管理的 KMS 密钥启用加密
  • 定期轮换密钥(30-90 天)
  • 使用 CloudTrail 审计访问
  • 使用 VPC 端点进行私有访问
访问控制
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue",
        "secretsmanager:DescribeSecret"
      ],
      "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/*",
      "Condition": {
        "StringEquals": {
          "secretsmanager:ResourceTag/Environment": "production"
        }
      }
    }
  ]
}
应用程序集成
  • 缓存密钥以减少 API 调用
  • 妥善处理轮换(使用新凭证重试)
  • 使用 Lambda 扩展以加快访问速度
  • 切勿记录密钥

故障排除

AccessDeniedException

原因:

  • IAM 策略缺少 secretsmanager:GetSecretValue
  • 资源策略拒绝访问
  • KMS 密钥策略缺少权限

调试:

# Check secret resource policy
aws secretsmanager get-resource-policy --secret-id my-secret

# Check IAM permissions
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789012:role/my-role \
  --action-names secretsmanager:GetSecretValue \
  --resource-arns arn:aws:secretsmanager:us-east-1:123456789012:secret:my-secret
轮换失败

调试:

# Check rotation status
aws secretsmanager describe-secret --secret-id my-secret

# Check Lambda logs
aws logs filter-log-events \
  --log-group-name /aws/lambda/SecretsManagerRotation \
  --filter-pattern "ERROR"

常见原因:

  • Lambda 超时(增加到 30 秒以上)
  • 网络连接问题(VPC 配置)
  • 数据库连接问题
  • 密钥格式错误
找不到密钥
# List secrets to find correct name
aws secretsmanager list-secrets \
  --filters Key=name,Values=myapp

# Check if deleted (within recovery window)
aws secretsmanager list-secrets \
  --include-planned-deletion

参考资料

评论

支持 Markdown