代表的な面接トピック

バックエンド面接:APIキー漏洩検知と緊急ローテーションの設計

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

質問

マルチテナントプラットフォームの読み取り専用APIキーがパブリックリポジトリにコミットされました。キーは複製された可能性があり、呼び出し元は即座に一括停止できない200のサービスに分散しています。正常な全テナントをオフラインにすることなく攻撃ウィンドウを最小限に抑えるための、検知、アラート、失効、影響分析、ローテーション、および検証を設計してください。

プロンプトとコンテキスト

マルチテナントプラットフォームの読み取り専用APIキーがパブリックリポジトリにコミットされました。キーは複製された可能性があり、呼び出し元は即座に一括停止できない200のサービスに分散しています。正常な全テナントをオフラインにすることなく攻撃ウィンドウを最小限に抑えるための、検知、アラート、失効、影響分析、ローテーション、および検証を設計してください。

これは、バックエンド、セキュリティエンジニアリング、およびプラットフォームエンジニアリング職向けのライフサイクルとインシデント対応に関する質問です。読み取り専用スコープ、200の呼び出し元、およびすべてを即座に停止できないという制約は面接上の前提条件であり、業界のベンチマークではありません。漏洩を観測可能なセキュリティイベントとして扱い、検知の前倒し、失効の伝播、影響範囲の限定、および復旧のオーケストレーションを行うことに焦点を当ててください。完全な暗号鍵管理プラットフォームを設計する必要はありません。

面接官がテストしていること

第一に、「テキストがキーのように見えること」と「認証情報が有効であること」を区別できるかどうかです。正規表現やプロバイダーのフィンガープリントは候補を生成しますが、シークレットを出力することなく、制限付き検証パス、ステータス検索、または内部メタデータによって有効性を確認する必要があります。

第二に、予防、検知、対応を結び付けられるかどうかです。pre-commitまたはpush protectionによってリポジトリへの混入を減らし、履歴スキャンやパブリックリポジトリスキャンで見逃しをキャッチし、キーサービスが失効させ、リクエストログが影響分析をサポートし、デプロイシステムが呼び出し元をローテーションします。

第三に、失効セマンティクスを定義できるかどうかです。データベースのステータスを変更しても、エッジキャッシュが即座に拒否するわけではなく、攻撃者によってすでに複製された静的認証情報が無効化されるわけでもありません。優れた回答では、伝播目標、キャッシュポリシー、およびダウンストリームのローテーション順序を具体的に指定します。

最後に、セキュリティと継続性の間で適切に境界付けられた選択ができるかどうかです。テナント全体ではなくキーを失効させ、通常のローテーションでは短いデュアルキーウィンドウを許可するものの漏洩後はデフォルトで許可しないこと、そしてすべてのステップを監査可能、再試行可能、かつ元に戻せるように設計します。

最初に明確にすべき質問

  • どのような認証情報か:読み取り専用APIキー、書き込みキー、クラウド認証情報、またはユーザートークンか? スコープによって影響範囲と優先順位が変わります。
  • どこで漏洩したか:パブリックリポジトリ、プライベートリポジトリ、ログ、チャット、またはアーティファクトか? 履歴はミラーリングされているか、それともまだアクセス可能か?
  • リスクのあるビジネス呼び出しを行うことなく、有効性をどのように確認できるか?
  • 失効とは、数秒以内に新しいリクエストを拒否することを意味するのか、それともダウンストリームシステム内の古い認証情報も無効化することを意味するのか?
  • 200のサービスは、デプロイ、設定、サイドカー、またはシークレットマネージャー(secrets manager)のパスを共有しているか? 自動更新できないものはどれか?
  • テナントは短いデュアルキーウィンドウを許容できるか? 即座に停止すべき書き込みと、安全にデグレード(縮退運用)できる読み取りはどれか?
  • どの証拠を保持する必要があり、誰が例外や緊急対応(break-glass)アクションを承認できるか?

30秒での回答

「私なら候補を潜在的に漏洩したものとして扱い、スキャナーからシークレットを決して出力しません。認証情報、スコープ、テナント、および最終使用日時を特定し、リスクの高いアクセスを即座に失効または制限し、すべてのゲートウェイが測定可能な伝播目標を満たすようにします。次に、リクエストログを使用して時間枠、ルート、不審な送信元を特定・限定し、シークレットマネージャーを介して代替キーを作成し、バッチでロールアウトして、使用状況を観察した後に古いキーを廃止します。プッシュブロック、履歴スキャン、リクエスト監査、およびローテーション訓練が持続的なループを形成します。監査済みの例外パスに進むことができるのは、無効であることが証明された偽陽性のみです。」

ステップごとの回答

ステップ1:インシデント状態と証拠の境界を確立する

detected → triaged → contained → rotated → verified → closed をモデル化します。各遷移には、インシデントID、公開認証情報識別子、テナント、送信元、スコープ、時刻、および担当者を記録します。スキャナーはハッシュ、フィンガープリント、および場所を保存し、完全なシークレットは決して保存しません。アナリストは権限が付与された内部検証パスを使用します。

候補は、pre-commitスキャン、リポジトリ履歴、パブリックリポジトリイベント、CIログ、アーティファクトスキャン、またはプロバイダー通知から取得される可能性があります。GitHub push protectionは、検出されたシークレットを含むプッシュをブロックし、バイパスに対してアラートを作成します。これにより新しい履歴エントリは減少しますが、履歴スキャンやランタイムモニタリングに代わるものではありません。

ステップ2:有効性を確認し、影響範囲(ブラストラディウス)を算出する

プレフィックス、長さ、チェックサム、またはプロバイダールールをローカルフィルタリングに使用し、シークレットを公開しない検証エンドポイントを呼び出します。レスポンスは validinvalidrevoked、または unknown と安全なメタデータである必要があります。スキャナーに本番環境の書き込み権限を使用させてはなりません。検証が必要な場合は、読み取り専用で低コストの分離されたテナントと監査マーカーを使用します。

確認後、スコープ、テナント、作成者、環境、有効期限、最終使用状況、および200のサービスの依存関係リストを読み取ります。検出から失効までの間のリクエストログをクエリします。通常の送信元と、未知のネットワーク、異常なリージョン、予期しないルート、拒否のスパイク、および価値の高いリソースの読み取りを分離します。ログには公開キーID、テナント、および相関IDのみを含め、Authorizationヘッダーやシークレットは決して含めません。

ステップ3:まず封じ込め、その後に移行を計画する

高特権、書き込み、または金銭移動を伴うキーを最初に失効させます。悪用が確認されない場合でも、読み取り専用キーを漏洩したものとして扱います。信頼できる失効ステータスを書き込み、無効化イベントを発行し、失われたイベントのフォールバックとして短いゲートウェイTTLを使用します。「すべてのゲートウェイが5秒以内に新しいリクエストを拒否する」などの目標を設定し、メッセージ損失、ノード再起動、およびパーティションをテストします。

200のサービスの都合のために、漏洩したキーに長い猶予期間を与えてはなりません。漏洩していない定期的なローテーションではデュアルキーウィンドウを使用できますが、漏洩が疑われる場合はまず失効させます。必要に応じて、低リスクの読み取りエンドポイントは短期間、安全にデグレードされた結果を返すことができます。デグレードによって追加のデータが開示されたり、書き込みが成功したように見えたりしてはなりません。

ステップ4:監査可能なバッチローテーションをオーケストレーションする

古いキー以上の権限を持たない、呼び出し元ごとに独立した代替キーを生成します。短命な認証情報またはワークロードアイデンティティ(workload identity)が望ましいです。共有シークレットマネージャーまたはデプロイ設定を介して、小さなカナリア、次にサービスグループというようにバッチで配信します。各サービスは prepared → deployed → observed → old-revoked などの冪等なステートマシンに従います。再試行によってキーが無制限に発行されたり、古いキーが再アクティブ化されたりしてはなりません。

Stripeは、誰かがキーを見たことを証明できない場合でも、漏洩直後にローテーションすることを推奨しています。制限付きキーと送信元IP制限により、影響範囲が縮小します。OWASPも、作成、使用、ローテーション、削除、目的、および所有権のメタデータを記録し、可能な限り短命または動的な認証情報を使用することを推奨しています。

ステップ5:単なるデプロイではなく、完了を検証する

4つのチェックを実行します:すべてのゲートウェイが一貫して古いキーを拒否していること、新しいキーが許可されたテナントとルートにのみアクセスできること、ログに古いキーIDや不審な送信元が含まれていないこと、および200のサービスすべての健全性、ビジネスメトリクス、エラーループレベル(エラーバジェット)が回復していること。自動更新できないサービスについては、「新しい設定を送信した」ことをもって完了とするのではなく、担当者、期限、および一時的な分離ポリシーを指定します。

クローズする前に、不可逆的な証拠の要約、タイムライン、権限の変更、承認、および代表的な不審なリクエストを保持します。ポリシーに従ってシークレットデータを破棄します。振り返りでは、なぜより早期に検知できなかったのか、なぜ呼び出し元がキーを共有していたのか、どのログにキーIDが欠落していたのか、失効が目標を満たしたかどうかを明らかにする必要があります。その回答をテスト可能なアクションへと変換します。

質の高い模範解答

「私なら読み取り専用キーを漏洩したものとして扱います。スキャナーはキーを決して出力せず、フィンガープリントとリポジトリの場所を保存し、制限付き検証エンドポイントがキーID、テナント、スコープ、および状態を確認します。高リスクの認証情報を即座に失効させ、信頼できる状態を書き込み、無効化イベントを発行し、すべてのゲートウェイが5秒以内に新しいリクエストを拒否することを要求し、メッセージ損失、キャッシュ動作、ノード再起動の条件下でテストします。

検出から失効までのリクエストログをクエリして、200の呼び出し元、ルート、送信元ネットワーク、および不審な読み取りを特定します。ログには公開キーIDのみを含め、Authorizationヘッダーは含めません。サービスごとに独立した最小権限のキーを生成し、シークレットマネージャーを通じてカナリアおよびバッチで配信し、新旧のキートラフィックを監視します。漏洩に対して長い猶予期間は設けません。デュアルキーは定期的なローテーションのためのものです。

検証とは単なるデプロイの成功以上を意味します。すべてのゲートウェイが古いキーを拒否し、新しいキーがテナントとルートの認可を強制し、古いキーのトラフィックがゼロになり、サービスエラーがバジェット内に収まることです。インシデントのタイムラインと安全な証拠を保存し、シークレットデータを破棄し、pre-commitでのブロック、履歴スキャン、ランタイム異常アラート、独立したキー、およびローテーション訓練を追加します。これにより、テナント全体や全サービスをオフラインにすることなく、攻撃ウィンドウを短縮します。」

よくある失敗パターン

  • 一致後に完全なキーをログ出力する → 二次漏洩を引き起こす → フィンガープリント、キーID、および場所のみを保持する。
  • 正規表現のみで漏洩を判断する → 偽陽性や未知のフォーマットにより対応を誤る → 制限付き検証とプロバイダーのメタデータを通じて確認する。
  • 悪用を確認するまで失効を待つ → 静的キーはすでに複製されている可能性がある → 漏洩を侵害の可能性として扱い、まず封じ込める。
  • データベースの行を削除して対応を終了する → ゲートウェイキャッシュやダウンストリームシステムが依然としてキーを受け入れる可能性がある → 伝播を測定し、キャッシュを無効化し、ダウンストリームのローテーションを検証する。
  • テナント全体をアクセス禁止にする → 影響範囲が拡大し、復旧が困難になる → キー、スコープ、ルート、および時間枠で境界を設定する。
  • 漏洩したキーに長いデュアルキーウィンドウを与える → 攻撃者がアクセスを維持し続ける → デュアルキーは漏洩していない定期的なローテーション用に限定する。
  • すべてのサービスを一度に切り替える → 1つの設定ミスがフリート全体の障害を引き起こす → カナリア、バッチ、冪等な状態、およびロールバックを使用する。
  • 配信完了をもって対応完了とみなす → サービスがリロードされず古いキーを使用し続ける可能性がある → 古いキーの拒否、新しいキーの認可、およびビジネスメトリクスをテストする。

フォローアップの質問

フォローアップ1:スキャナーが候補の有効性を証明できない場合、どうしますか?

有効なウィンドウを短縮するため、潜在的に漏洩したものとして扱います。シークレットを返さない検証エンドポイント、リポジトリのコンテキスト、および内部キーメタデータを使用して証拠を追加します。偽陽性のコストが高い場合、承認されたセキュリティレビュアーが理由を付記した期限付きの例外を承認できます。スキャナーが自己承認してはなりません。

フォローアップ2:レガシーシステムが新しいキーのホットリロードに対応していません。どのようにローテーションしますか?

新しいデプロイまたは短期間のデュアルプロセスを準備し、新しいキーを検証し、トラフィックを移行した後に古いキーを失効させます。それが不可能な場合は、サービスの権限と送信トラフィック(egress)を分離し、短い期限を設定し、手動ステップを監査します。レガシーシステムの制約は、漏洩したキーを無期限に有効にしておく理由にはなりません。

フォローアップ3:失効に5秒以上かかります。サービス提供を継続しますか、それともすべて停止しますか?

スコープとビジネスリスクによって階層化します。書き込み、支払い、高価値ルートは、状態が古い場合はフェイルクローズ(fail closed)にします。低リスクの読み取りは、明示的にラベル付けされた短いデグレードを使用できます。分離とスロットリングを強化し、無効化またはキャッシュのパスを修復してから、より広範なブロックが必要かどうかを判断します。

フォローアップ4:攻撃者がすでに古いキーを使用してデータを読み取っていました。次に何をすべきですか?

証拠を保全し、時間、テナント、ルート、およびデータを限定し、影響を受ける関係者に通知し、侵害報告義務を評価します。失効とローテーションによりそれ以上の使用を阻止します。エクスポート、キャッシュ、非同期ジョブ、およびダウンストリームのコピーを調査し、二次的な漏洩がないか確認します。

公開情報ソース

関連する質問