mcpField
S
secrets-manager

secrets-manager

github.com/itsmostafaセキュリティ1.2k155 回インストール2 日前に更新
リポジトリ

secrets-manager について

AWS Secrets Manager でアプリケーションのシークレットを管理する開発者向けのガイドです。保存と取得、バージョン管理、ローテーション、キャッシュ、CLI、アクセス制御、トラブルシューティングを説明します。

主な機能

  1. 01シークレットと認証情報の暗号化保存
  2. 02シークレットの取得、更新、バージョン管理
  3. 03Lambda による認証情報のローテーション
  4. 04API 呼び出しを抑えるキャッシュ
  5. 05CLI コマンドとアクセス制御の説明

活用シーン

  1. 01アプリの DB 認証情報や API キーを保存
  2. 02DB 認証情報を定期的にローテーション
  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

参考資料

コメント