secrets-manager について
AWS Secrets Manager でアプリケーションのシークレットを管理する開発者向けのガイドです。保存と取得、バージョン管理、ローテーション、キャッシュ、CLI、アクセス制御、トラブルシューティングを説明します。
主な機能
- 01シークレットと認証情報の暗号化保存
- 02シークレットの取得、更新、バージョン管理
- 03Lambda による認証情報のローテーション
- 04API 呼び出しを抑えるキャッシュ
- 05CLI コマンドとアクセス制御の説明
活用シーン
- 01アプリの DB 認証情報や API キーを保存
- 02DB 認証情報を定期的にローテーション
- 03アプリでシークレットを取得してキャッシュ
- 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 対応