シークレットローテーション
API キーやデータベースパスワードなどの秘密情報を定期的に自動更新するセキュリティプラクティス
セキュリティ運用
シークレットローテーションとは
シークレットローテーション (Secret Rotation) は、API キー、データベースパスワード、暗号鍵などの秘密情報を定期的に自動更新するセキュリティプラクティスである。秘密情報が漏洩した場合の影響を時間的に限定し、長期間同じ認証情報が使われるリスクを軽減する。
なぜローテーションが必要か
- 漏洩した認証情報の有効期間を限定する (30 日でローテーションすれば、漏洩の影響は最大 30 日)
- コンプライアンス要件 (PCI DSS、SOC 2) でパスワードの定期変更が求められる
- 退職者がアクセスに使っていた認証情報を無効化する
Secrets Manager は Lambda 関数を呼び出してローテーションを実行する。RDS の場合、Secrets Manager が自動的にパスワードを変更し、新しいパスワードをシークレットに保存する。
ローテーションの 4 ステップ
1. createSecret: 新しいパスワードを生成し、AWSPENDING ラベルで保存
2. setSecret: DB のパスワードを新しいものに変更
3. testSecret: 新しいパスワードで DB に接続できることを確認
4. finishSecret: AWSPENDING → AWSCURRENT に昇格、古いパスワードを AWSPREVIOUS に
この 4 ステップにより、ローテーション中もアプリケーションが中断しない。AWSCURRENT と AWSPREVIOUS の両方が一時的に有効になるため、古いパスワードを使っているアプリケーションも即座には壊れない。
Lambda でのシークレット取得
import { GetSecretValueCommand, SecretsManagerClient } from '@aws-sdk/client-secrets-manager';
const sm = new SecretsManagerClient({});
let cachedSecret: string | null = null;
async function getDbPassword(): Promise<string> {
if (cachedSecret) return cachedSecret;
const result = await sm.send(new GetSecretValueCommand({ SecretId: 'myapp/db-password' }));
cachedSecret = JSON.parse(result.SecretString!).password;
return cachedSecret!;
}
注意: Lambda のコールドスタート間でキャッシュが残るため、ローテーション後に古いパスワードが使われる可能性がある。TTL 付きキャッシュを使うか、接続エラー時にキャッシュをクリアする。
ローテーション対象と頻度
| 対象 | 推奨頻度 | 方法 |
|---|---|---|
| DB パスワード | 30〜90 日 | Secrets Manager 自動ローテーション |
| API キー | 90 日 | Secrets Manager + カスタム Lambda |
| JWT 署名鍵 | 90 日 | JWKS エンドポイントで公開鍵を配布 |
| TLS 証明書 | 自動 (ACM) | ACM が自動更新 |
実践的な知識は関連書籍でも得られる。