シークレットローテーション
API キーやデータベースパスワードなどの秘密情報を定期的に自動更新するセキュリティプラクティス
シークレットローテーションとは
シークレットローテーション (Secret Rotation) は、API キー、データベースパスワード、暗号鍵などの秘密情報を定期的に自動更新するセキュリティプラクティスである。秘密情報が漏洩した場合の影響を時間的に限定し、長期間同じ認証情報が使われるリスクを軽減する。
なぜローテーションが必要か
- 漏洩した認証情報の有効期間を限定する (30 日でローテーションすれば、漏洩の影響は最大 30 日)
- 適用される基準や社内規程が認証情報の定期更新を求めている場合、自動ローテーションの実行履歴がそのまま証跡になる (要求される頻度や代替策が認められるかは基準ごとに違うので、原文で確認する)
- 退職者がアクセスに使っていた認証情報を無効化する
Secrets Manager のローテーションには 2 つの形態がある。一般のシークレットは、Secrets Manager がローテーション関数 (Lambda) を呼び出して更新する。一方 Amazon RDS や Aurora、Redshift、DocumentDB のマスターユーザー認証情報は、各サービス側が設定と実行を受け持つマネージドローテーションが使えるため、Lambda 関数を自分で用意しなくてよい。ただしマネージドローテーションの対象はマスターユーザーであって、アプリケーションが日常的に使う権限を絞ったユーザーの認証情報は対象外なので、そちらはローテーション関数を設定する。
ローテーションの 4 ステップ
ローテーションは、Secrets Manager がローテーション関数を 4 回呼び出す形で進む。各段階でシークレットのバージョンに付くステージングラベルが移動していく。
1. createSecret: 新しいパスワードを生成し、AWSPENDING ラベルで保存
2. setSecret: DB のパスワードを新しいものに変更
3. testSecret: 新しいパスワードで DB に接続できることを確認
4. finishSecret: AWSPENDING → AWSCURRENT に昇格、古いパスワードを AWSPREVIOUS に
ここで誤解しやすいのは、ステージングラベルがシークレットのどのバージョンを指すかという目印であって、データベース側で古いパスワードを生かし続ける仕組みではない点である。AWSPREVIOUS は直前の正常なバージョンを取り出せるようにするためのラベルにすぎない。単一ユーザー方式では setSecret の時点でデータベースのパスワードが切り替わるので、古いパスワードを握ったままのクライアントが張り直す接続は認証に失敗し得る。確立済みの接続は接続時に認証を済ませているため途中で切れることはないが、ローテーション直後に新しい接続を張る経路には、認証エラー時にシークレットを取り直して再試行する処理を入れておく。
切り替えの隙を避けたい場合は、2 つのユーザーを交互に更新する方式 (alternating users) を選ぶ。初回のローテーションで元のユーザーを複製し、以降はどちらか一方のパスワードだけを更新するため、新しい認証情報を検証している間はもう一方のユーザーの認証情報が有効なまま残る。これが可用性の高い選択肢とされている理由である。
Lambda でのシークレット取得
呼び出しごとに Secrets Manager の API を叩くと遅延と API 料金が積み上がるため、実行環境が再利用される性質を活かしてモジュールスコープにキャッシュを置くのが定石である。
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!;
}
注意: このキャッシュが残るのはコールドスタートの間ではなく、逆に同じ実行環境が再利用される (ウォームスタートの) 間である。実行環境は一定時間使われ続けることがあるため、ローテーション後も古いパスワードを掴んだままになり得る。TTL 付きキャッシュにするか、認証エラーを検知したらキャッシュを捨てて取り直す経路を用意する。
ローテーション対象と頻度
頻度は対象の性質で決まる。人手を介さず更新できるものは短く、配布先が多くて切り替えに調整がいるものは長めに置く、というのが実際の落としどころである。
| 対象 | 推奨頻度 | 方法 |
|---|---|---|
| DB パスワード | 30〜90 日 | Secrets Manager 自動ローテーション |
| API キー | 90 日 | Secrets Manager + カスタム Lambda |
| JWT 署名鍵 | 90 日 | JWKS エンドポイントで公開鍵を配布 |
| TLS 証明書 | 自動 (ACM) | ACM が自動更新 |
実践的な知識は関連書籍でも得られる。
この記事は役に立ちましたか?
関連用語
Secrets Manager
AWS のシークレット管理サービスで、パスワードや API キーを安全に保存 / 自動ローテーションする
最小権限の原則
ユーザーやプログラムに、タスクの遂行に必要な最小限の権限のみを付与するセキュリティ原則
ゼロトラスト
ネットワークの内外を問わず全てのアクセスを検証し、暗黙の信頼を排除するセキュリティモデル
シークレット管理
パスワード、API キー、証明書などの機密情報を安全に保存 / 配布 / ローテーションする手法
Passkey
パスワード不要の認証技術で、FIDO2/WebAuthn 標準に基づく
多要素認証
パスワードに加えて追加の認証要素を要求し、アカウントの不正アクセスを防ぐセキュリティ手法
関連する記事
技術書の読む順番戦略 - 複数冊を組み合わせて理解を加速させる
技術書を 1 冊ずつ読むのではなく、複数冊を戦略的に組み合わせることで、1 冊では届かない理解の深さと広さに達する方法を解説します。
README を書くように本を読む - エンジニアのための構造化読書法
エンジニアが日常的に書く README のフォーマットを読書に応用する方法を紹介します。目的 / 使い方 / 注意点の 3 点で本の内容を整理すると、半年後に読み返しても実務で引き直せる記録として残ります。
OS / 低レイヤー本ガイド - コンピュータの仕組みを学ぶ技術書の選び方
OS、コンパイラ、ネットワークなど低レイヤーを学べる技術書の 4 ジャンルと、どこから始めるべきかの指針、賞味期限の見極め方を紹介します。