代表的な面接トピック

バックエンド面接:ダウンタイムなしでWebhookシークレットをローテーションするには?

バックエンド難しい
Offer.cc 編集チーム公開日 更新日

質問

プロバイダーは配信が継続している間にWebhook署名シークレットをローテーションする必要があります。有効なイベントの拒否や古い署名の受け入れを防ぐにはどうすればよいですか?

プロンプトと前提条件

プロバイダーがシークレットを変更する間、レシーバーは署名付きWebhookリクエストを検証します。ローテーションは、シークレットの漏洩や検証のギャップを生じさせることなく、処理中のリトライや複数の送信者レプリカに対応できる必要があります。

面接官がテストするポイント

  • 未加工の本文(raw-body)署名検証と定数時間比較の維持。
  • アクティブなシークレットと廃止予定のシークレットの間における、期限が区切られた重複期間の設計。
  • ローテーション状態、リプレイ保護、オブザーバビリティ、およびロールバックの分離。

回答前の確認事項

  • 誰がローテーションを制御し、送信者はキー識別子やバージョンを提示できますか?
  • 配信リトライとクロックスキューはどのくらい持続する可能性がありますか?
  • 送信者はデュアル署名期間を調整できますか、それともレシーバーが2つのシークレットを受け入れる必要がありますか?
  • リプレイチェックにはどのようなイベントID、タイムスタンプ、未加工のペイロードが利用できますか?

30秒の回答フレームワーク

新しいシークレットをプロビジョニングし、すべてのレシーバーに配布して短い重複期間に入ります。重複期間中は、キーIDで選択された署名を検証するか、現在のシークレットと廃止予定のシークレットを定数時間チェックで試しつつ、タイムスタンプの許容範囲とイベントIDの重複排除を適用します。メトリクスでどのバージョンが検証されたかを示し、リトライ期間にわたって旧バージョンのトラフィックがゼロのまま維持された後にのみローテーションを完了します。ロールバックはウィンドウが閉じるまで廃止予定のシークレットを維持します。

ステップごとの詳細解説

1. 署名対象のバイト列を保持する

JSONパースの前に、リクエストボディを未加工のバイト列として一度だけ読み取ります。タイムスタンプや区切り文字のルールを含め、プロバイダーの指定どおりに正確に署名入力を構築します。定数時間でMACを比較し、不正な形式やサイズ超過のペイロードは早期に拒否します。

2. シークレットのバージョンをモデル化する

作成日時、有効期限、プロバイダースコープ、および PENDINGOVERLAP、または RETIRED などのステータスとともに、アクティブなバージョンと廃止予定のバージョンを保存します。試行検証を回避できるためキー識別子が望ましいですが、利用できない場合は2つのシークレットによるフォールバックの範囲を限定し、どのシークレットが成功したかを記録します。

3. 安全にロールアウトする

シークレットマネージャーを介して新しいシークレットを配布し、レシーバーをアトミックにリロードして、署名付きカナリアを実行します。準備完了が確認された後にのみ、送信者にデュアル署名または切り替えを依頼します。最大リトライ期間にクロックスキューのマージンを加えた期間、古いシークレットを利用可能な状態にしておきます。

4. リプレイをブロックする

許容範囲内の署名付きタイムスタンプを要求し、リトライをカバーする保持期間でイベントIDまたはダイジェストを保存します。検証はキューイングの前に行う必要があります。有効な重複配信については、ビジネス処理を繰り返すことなく成功(ACK)を返すことができます。

5. 観測と廃止

シークレットや完全な機密ペイロードをログに記録することなく、キーバージョンごとの検証成功数、古いタイムスタンプ、重複ID、不正な署名、およびキュー処理の結果をカウントします。重複期間とリトライ期間が経過した後にのみ古いバージョンを廃止します。新しいバージョンが失敗した場合は、古いバージョンを復元してアラートを発報します。

質の高い模範解答

「シークレットマネージャーで新しいバージョンをステージングし、すべてのレシーバーをリロードして、送信側を切り替える前にカナリアを検証します。制限された重複期間の間は、署名付きタイムスタンプのチェックとイベントIDの重複排除を行いながら、できればキーIDで選択された、現在および廃止予定バージョンの署名を受け入れます。バージョンごとの検証状況を追跡し、送信者のリトライ期間にクロックスキューを加えた時間が経過するのを待ってから廃止します。新しいバージョンが失敗した場合、ロールバックにより古いシークレットが有効なまま維持されます。ログにはカウンターとIDのみを含め、シークレットや未加工ペイロードは決して記録しません。」

よくある間違い

  • シークレットを一度にすべて置き換える → 古い署名によるリトライが失敗する → 重複ウィンドウを使用する。
  • 検証前にJSONをパースする → 正準バイト列が変わる可能性がある → 最初に未加工のボディを検証する。
  • 両方のシークレットを永続的に受け入れる → 古い認証情報が有効なままになる → リトライとスキューの境界に紐づく有効期限を設定する。
  • 署名やシークレットをログに記録する → オブザーバビリティが認証情報の漏洩につながる → バージョン管理されたカウンターと安全な識別子をログに記録する。

フォローアップ質問と回答

送信者がデュアル署名できない場合はどうしますか?

新しいシークレットを事前ロードし、制限されたウィンドウの間、レシーバー側で両方のバージョンを受け入れます。送信側の切り替えを調整し、バージョン固有の検証を監視し、最大リトライ期間が過ぎるまで古いバージョンを保持します。

重複期間はどのように決定しますか?

送信者のドキュメントに記載されたリトライ上限、キュー遅延、クロックスキューの許容範囲、およびインシデントマージンを使用します。平均レイテンシから推測するのではなく、期限を明示的に設定し、有効期限が近づいている古いバージョンのトラフィックに対してアラートを発報します。

攻撃者が過去の有効なイベントをリプレイした場合はどうしますか?

許容範囲外のタイムスタンプを拒否し、イベントIDまたは署名付きペイロードダイジェストの重複を排除します。リプレイレコードは、受け入れられるタイムスタンプウィンドウおよびビジネスリトライ期間と少なくとも同じ期間保持します。

公開情報ソース

関連する質問