シークレットのローテーションと安全な保管
シークレット
ローテーション
セキュリティ
鍵管理
この記事の対象
本番運用中のアプリのシークレットを定期的に更新(ローテーション)したい運用担当者向けです。
本番運用中のアプリのシークレットを定期的に更新(ローテーション)したい運用担当者向けです。
シークレットは「長く同じものを使い続けるほど漏えいリスクが累積する」性質があります。退職したメンバーが過去に閲覧した、ログ出力に紛れた、バックアップに含まれて持ち出された——どれもありえる経路です。定期的なローテーションで、漏えいの影響範囲を時間で区切るのが基本戦略です。
ローテーション頻度の目安
| 対象 | 推奨頻度 | 即時更新の契機 |
|---|---|---|
| クライアントシークレット | 年1回 | 漏えい疑い、退職、漏えいインシデント |
| Webhookシークレット | 年1回 | 同上 |
| アクセストークン | 自動(1時間) | ― |
| リフレッシュトークン | 自動(90日) | ― |
クライアントシークレットのローテーション手順
レシートローラーは「新旧シークレットの並行期間」をサポートしているので、無停止でローテーションできます。
- 開発者ポータル → アプリ → クレデンシャル → 「シークレットを追加発行」
- 新シークレットを安全に保管
- シークレット管理サービス(AWS Secrets Manager 等)の値を新シークレットに更新
- 本番環境を順次デプロイ(またはローリング再起動で環境変数を反映)
- 全環境が新シークレットで動作していることをログで確認
- 開発者ポータルで旧シークレットを「失効」させる
並行期間中は両方のシークレットが有効です。デプロイの最中に旧シークレットでリクエストが来ても認証が通るため、無停止での切り替えが可能です。
Webhookシークレットのローテーション
Webhookシークレットも同様に並行期間運用が可能です。受信側で「新旧両方のシークレットで署名検証を試す」実装にしておくと、切り替え期間が安全です。
function verify(body, signature, ts) {
return verifyWith(body, signature, ts, NEW_SECRET)
|| verifyWith(body, signature, ts, OLD_SECRET);
}
切り替え完了後、コードからOLD_SECRETの参照を削除します。
保管のベストプラクティス
- シークレット管理サービスを使う:AWS Secrets Manager / Azure Key Vault / GCP Secret Manager / HashiCorp Vault
- 環境変数の暗号化:CIに登録するときは暗号化機能を使う(GitHub Secrets、GitLab CI Variables 等)
- アクセス監査:誰がいつシークレットを取得したか追跡できる状態に
- 最小権限:本番シークレットは本番のサービスアカウントのみが取得可能
- バックアップ非含有:DBバックアップやログアーカイブにシークレットを含めない
- 退職時オフボーディング:退職者がアクセスしていたシークレットは即時ローテーション
やってはいけないこと
| アンチパターン | 対処 |
|---|---|
| .envファイルをgitにコミット | .gitignore に追加、過去の混入は履歴ごと削除+シークレット再生成 |
| Slackやメールでシークレットを共有 | シークレット管理サービス経由で共有 |
| クライアント側コードに埋め込み | サーバー側へ移動、即時再生成 |
| エラーログにシークレットを出力 | マスキング処理、ログ削除、再生成 |
| 何年も同じシークレットを使い続ける | 年次ローテーションをカレンダーに登録 |
関連ガイド
公開日: 2026-04-27
更新日: 2026-04-27
カテゴリ
タグ
API (8)
Webhook (8)
api (6)
oauth (5)
トラブル (5)
OAuth (4)
getting-started (4)
アプリ登録 (4)
app-registration (3)
webhook (3)