問題とスコープ
本プラットフォームは何百万ものリポジトリに対応します。脆弱性フィードがレコードの追加、改訂、取り消しを行う一方で、リポジトリは lockfile、イメージマニフェスト、または SBOM を送信できます。インジェスチョン、バージョンマッチング、アラートライフサイクル、通知、および修正検証を設計してください。npm、PyPI、Maven をサポート対象とし、コードスキャン、パッチの自動マージ、人手による脆弱性調査はスコープ外とします。
面接官が評価しているポイント
「依存関係のバージョンが脆弱性に一致すること」と「アラートにライフサイクルがあること」を分離できるかです。エコシステムを考慮したバージョン、直接依存関係と推移的依存関係、フィードの改訂、取り消し、重複排除、再生可能な処理(リプレイ)、通知の冪等性、そしてテナント認可がシグナルとなります。スキャン結果はあるスナップショットに対するエビデンスであり、永続的な真実ではありません。
明確化のための質問
- 各マニフェストは正確なバージョンに固定されていますか、それとも許容範囲が設定されていますか?マッチングには解決済みバージョンと宣言のどちらを使用すべきですか?
- 推移的パッケージ、開発用パッケージ、コンテナレイヤーのパッケージ、プライベートパッケージはスコープに含まれますか?
- フィードによる取り消し、エイリアス設定、重要度の改訂は発生しますか?また、どの履歴スナップショットが保持されますか?
- アラートはブランチ単位でスコープ設定されますか?また、ブランチが削除された場合はどうなりますか?
- どのチャネル、クールダウン、組織レベルのスヌーズが必要ですか?
30秒の回答フレームワーク
「不変なマニフェストスナップショットを保持し、エコシステム固有の依存関係グラフをパースして、インデックス化された脆弱性範囲を通じてバージョンを照合します。その結果は、リポジトリ、コンポーネント、脆弱性、およびエビデンススナップショットをキーとする冪等なアラートプロジェクションになります。フィードの改訂によって差分再計算がトリガーされます。インジェスチョン、フィード更新、および通知には永続的でリプレイ可能なキューを使用し、通知は組織ごとに集約されて冪等性キーを付与されます。アラートはエビデンスを保持し、修正済みとしてマークされる前に新しいコミットが再スキャンされます。リコンシリエーション、認可、鮮度メトリクスにより、システムの説明可能性を担保します。」
ステップごとの詳細設計
コントロールプレーンは、組織、リポジトリ、ブランチ、および通知ポリシーを保存します。インジェスチョン API はコミットハッシュを含むマニフェストを受け取り、オリジナルオブジェクトとメタデータを書き込んだ後、manifest_received を発行します。同一のリポジトリ、ブランチ、コミット、マニフェストダイジェストが繰り返された場合は、既存のスナップショットを返します。大容量の SBOM にはマルチパートアップロードとチェックサムを使用し、テナントごとのクォータでパーサーを保護します。
パーサーは各エコシステムに従って名前とバージョンを正規化し、ロックされた推移的グラフを展開します。スナップショットには、コンポーネントの座標、ソースパス、開発または本番のスコープが記録されます。パース失敗時は元のファイル、エラー位置、再試行状態を保持します。「パースできなかった」を「脆弱性なし」にしてはなりません。
フィードインジェスターは OSV などのソースから差分をプルまたは受信し、スキーマ、ソース署名、フィードバージョンを検証した上で、影響を受けるエコシステム、パッケージ名、バージョン範囲、エイリアス、重要度、修正バージョン、タイムスタンプ、および取り消しマーカーを保存します。範囲マッチングには文字列ソートではなくエコシステム固有のセマンティクスを使用します。転置インデックスにより、大量のコンポーネントに対する処理を増分化します。
アラートには、alert_id、組織、リポジトリ、ブランチ、コンポーネント座標、脆弱性 ID、エビデンススナップショット、ステータス、初回検知時刻、最新の確認時刻、修正コミット、ルールバージョンが含まれます。(repository, branch, component, vulnerability_id, vulnerable_version) に対する一意性制約により重複を防ぎます。エイリアスはこのキーが構築される前に正規化されます。ステータスには OPEN、FIXED、DISMISSED、REOPENED があり、すべての遷移に対して監査イベントが記録されます。取り消しが行われると新規通知は停止されますが、履歴とその理由は保持されます。
通知はスキャントランザクションの外部で行われます。アラートイベントは組織ごとにパーティショニングされたキューに入ります。アグリゲーターが類似のアラートをグループ化し、クールダウンを適用して、安定した通知キーを発行します。メール、コードホストのコメント、チャットのアダプターにはそれぞれ制限、リトライ、配信レシートがあり、コンシューマーはキーによって重複を排除します。スヌーズにはスコープ、有効期限、所有者、理由が設定され、重要度のエスカレーションによって期限切れまたは無効なスヌーズをバイパスできます。
修正検証では、新しいコミットまたは定期的なスナップショットを受け入れ、現在のグラフを再パースして同じマッチングルールを適用します。現在のアラートがクローズされるのは、デフォルトブランチの現在のスナップショットが一致しなくなった場合、または組織がリスクを明示的に受け入れた場合のみです。提案された修正バージョンは修正の証明にはなりません。削除されたブランチは監査履歴を消去することなく終了イベントを生成します。
耐久性はリプレイ可能なイベントとリコンシリエーションによって実現されます。保存されたマニフェストをパース結果、マッチング結果、アラートプロジェクション、フィードバージョン、期待される通知、アダプターレシートと比較します。マニフェストからアラートまでの p95 レイテンシ、パース失敗、フィードの遅延、マッチングスループット、重複率、取り消しの伝播、通知のリトライ、スヌーズのヒットを監視します。キューの重複、フィード改訂中のクラッシュ、インデックスの陳腐化、アダプターのタイムアウト、データベースのリカバリ失敗を注入してテストします。
高品質な回答例
「コミットハッシュとともに元のマニフェストを保存し、エコシステム固有の依存関係グラフをパースして、脆弱性範囲に対する転置インデックスを維持します。マッチングにより、エビデンススナップショットとルールバージョンを持つ冪等なアラートが作成され、一意のキーによって同一のリポジトリ、コンポーネント、脆弱性に対する重複アラートを防ぎます。取り消しが行われた場合は新規通知を停止しますが、過去のエビデンスは保持します。
通知イベントは永続キューによってスキャンから分離され、組織ごとに集約され、安定したキーでリトライされます。スヌーズには有効期限があり監査されます。重要度のエスカレーションによってスヌーズを解除することも可能です。新しいコミットはすべて再スキャンされ、実際に一致しなくなった場合にのみアラートが修正済みとしてマークされます。リコンシリエーションによってマニフェスト、フィード、アラート、通知の境界をチェックし、メトリクスによって可視性、取り消しの伝播、バックログ、重複、アダプターの障害をカバーします。これにより、1日あたり数百万件のマニフェストにスケールし、アラートが表示、変更、または再オープンされた理由を説明可能にします。」
よくある間違い
- パッケージ名のみを比較する → エコシステムと範囲セマンティクスによって誤検知が発生する → エコシステム座標と範囲比較を使用する。
- パース失敗を安全と見なす → 壊れた lockfile がリスクを暗黙的に隠蔽する → 失敗エビデンスを保持してリトライする。
- スキャンごとに新しいアラートを作成する → 1つの問題で開発者に通知が殺到する → 冪等なアラートキーを構築する。
- フィードの改訂を上書きする → 過去の重要度や取り消しが説明不可能になる → ソースをバージョン管理し、エビデンスを保持する。
- スキャン内で通知を送信する → 低速なチャネルが検知処理をブロックする → 永続イベントで分離する。
- 提案された修正バージョンでクローズする → 実際のコミットがまだ一致している可能性がある → 現在のコミットを再スキャンする。
- 恒久的なスヌーズを許可する → リスクの所有者が失われる → 有効期限、理由、リマインダーを必須にする。
- エイリアスに対して個別にアラートを出す → 1つの脆弱性が何度も表示される → まずエイリアスを正規化する。
フォローアップの質問と回答
フォローアップ1:影響を受ける範囲が改訂された場合、どのように処理しますか?
フィード更新をバージョン管理し、影響を受けるコンポーネントセットを計算して、一致するスナップショットのみを再計算します。各アラートにルールバージョンとエビデンスを保持し、すべてのステータス変更を記録します。
フォローアップ2:なぜ元のマニフェストを保持するのですか?
パーサーやルールは進化するためです。元のファイルがあれば、新しいルールでのリプレイが可能になり、どのアラートがどのコミットによって生成されたかを証明できます。
フォローアップ3:通知の疲弊をどのように軽減しますか?
組織、脆弱性、コンポーネントごとに集約し、クールダウンとサマリーを適用します。スヌーズにはスコープと有効期限を設定して監査対象とし、重要度のエスカレーション時には即時通知できるようにします。
フォローアップ4:推移的依存関係の間違いをどのように防ぎますか?
ロックされたグラフを使用し、親パスと依存関係のスコープを保持し、lockfile から解決済みバージョンを特定できない場合は「unknown」と表示します。
フォローアップ5:ブランチをどのようにモデル化しますか?
ブランチをスナップショットのディメンションとして扱い、アラートキーに含めます。削除時は将来の処理を終了させますが、監査履歴は消去しません。
フォローアップ6:脆弱性フィードが利用できない場合はどうしますか?
データの鮮度に関する明示的な警告とともに、最後に検証されたバージョンを使用します。結果が安全であるとは主張しません。バックオフを行い、ミラーへフェイルオーバーし、復旧後にバージョンの差分をリプレイします。