代表的な面接トピック

システムデザイン面接:改ざん検知可能な監査ログサービスをどのように設計するか?

システム設計難しい
Offer.cc 編集チーム公開日 更新日

質問

セキュリティおよびコンプライアンス調査のためのマルチテナント監査ログサービスを設計してください。イベントスキーマ、取り込みの耐久性、改ざん検知性、アクセス制御、保持、クエリの分離、エクスポート、および障害処理について説明してください。

プロンプトと対象範囲

サインイン、権限の変更、データアクセス、設定の更新など、セキュリティおよびコンプライアンスに関連するアクションを記録するマルチテナント監査ログサービスを設計します。調査担当者には検索可能な履歴と検証可能なエクスポートが必要であり、ロギングの停止中もアプリケーショントラフィックは利用可能であり続ける必要があります。

完全性の保証内容を正確に定義してください。AWS CloudTrailは不変で検索可能なイベント履歴を記述し、OpenTelemetryは共通の構造化ログモデルを提供しますが、いずれもイベントが出力される前に正しかったことまでは主張しません。設計では、サービスが何を証明できるかを明記する必要があります。

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

耐久性のある取り込み、追記専用(append-only)ストレージ、完全性検証、テナント分離、保持ポリシー、および運用のトレードオフをテストしています。優れた回答は、監査証拠を通常のデバッグログと区別し、過負荷時にセキュリティイベントの損失や改ざんを回避する方法を説明します。

回答する前に確認すべき質問

  • どのアクションが必須であり、予想される秒あたりイベント数(EPS)とバーストサイズはどのくらいか?
  • 要件は改ざん検知(tamper-evident)、耐改ざん性(tamper-resistant)、それとも外部証明可能(externally attestable)か?
  • 監査イベントを受け入れられない場合、アプリケーションリクエストを失敗させる必要があるか?
  • 各テナントはイベントをどのくらいの期間保持する必要があり、リテールホールド(法的な保持要件)は削除より優先されるか?
  • 他のテナントのデータを検索、エクスポート、または検証できるのは誰か?
  • 調査担当者はどのようなクエリディメンションとエクスポート形式を必要としているか?

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

「アプリケーションの呼び出しが検索インデックスに依存しないよう、リージョン単位の取り込みAPIとローカルの耐久性バッファを公開します。各イベントには、テナント、アクター、アクション、対象、リクエストの関連付け、イベント発生時刻、取り込み時刻、スキーマバージョン、およびソースを含めます。追記専用ログをテナントと時間でパーティショニングして複製し、ハッシュチェーンまたは署名付きセグメントマニフェストを作成して後からの編集を検知できるようにします。ホットな検索可能インデックスと不変の保持ストレージを分離します。テナントスコープの認可、保持およびリーガルホールドを適用し、検証メタデータを伴うエクスポートを提供します。受け入れ済みイベントとドロップされたイベント、取り込みラグ、完全性チェック、およびエクスポートの完了を監視します。」

ステップごとの詳細解説

ステップ 1: イベント規約を定義する

イベントID、テナントID、アクターと認証コンテキスト、アクション、対象、結果、ソースサービス、リクエストID、イベント時刻、取り込み時刻、スキーマバージョン、および選択された属性を必須とします。シークレットや不要なペイロードはレコードから除外し、代わりに参照またはマスキング(redact)されたサマリーを記録します。

ステップ 2: 受け入れとインデックス作成を分離する

イベントが耐久性のあるバッファまたは複製されたログに到達した後にのみ、成功を返します。コンシューマーはその後、非同期で検索インデックスとエクスポートを構築します。これにより、検索クラスターのインシデントによって証拠がサイレントに削除されたり、すべてのアプリケーションリクエストがインデックス作成を待たされたりするのを防ぎます。

ステップ 3: 完全性を検証可能にする

各イベントを正規化し、前のイベントまたはセグメントルートとともにハッシュ化し、マニフェストに対して定期的に個別の信頼ドメインで署名またはアンカー(固定)を行います。シーケンスの欠落と検証結果を保存します。ハッシュチェーンは取り込み後の変更を検出しますが、アップストリームサービスが真実のイベントを出力したことを証明するものではありません。

text
append(event):
    canonical = canonicalize(event)
    record.hash = H(previous_hash || canonical)
    durable_log.append(record)
    return accepted(record.event_id, record.hash)

ステップ 4: パーティショニングとレプリケーション

テナントと時間でパーティショニングし、ハッシュまたはテナントキーを使用してアクセスが集中するテナント(hot tenants)を分散させます。耐久性の目標に従って応答(ACK)を返す前に、障害ドメインを越えてレプリケーションを行います。テナント単位または集約単位での順序付けを維持しますが、コストが見合わない限りグローバルな順序付けは保証しません。

ステップ 5: ホット検索とコールド保持の構築

調査担当者のクエリ用に最近のイベントをインデックス化し、古いセグメントは不変のオブジェクトストレージにコンパクション(圧縮統合)します。インデックスはログから再構築できるように維持します。保持ジョブはテナントごとのポリシーとリーガルホールドを尊重する必要があり、削除の際は保護されたペイロードを保持することなく、監査可能なポリシーレコードを残す必要があります。

ステップ 6: アクセス制御とエクスポート制御の強制

すべてのクエリをテナント、ロール、目的、および時間範囲によって認可します。読み取りとエクスポートも監査イベントとしてログに記録します。受信者が完全性を検証し、改変を検出できるように、フィルター、イベント数、セグメントハッシュ、およびタイムスタンプを含む署名付きマニフェストを生成します。

ステップ 7: 障害および過負荷時の動作を定義する

制限付きのローカルバッファ、バックプレッシャー、および必須イベントに対する明確なポリシーを選択します。重要度の低いテレメトリの場合はサンプリングや配信遅延が許容される場合がありますが、セキュリティイベントの場合は元の変更リクエストを拒否するか、隔離された緊急チャネルにルーティングします。イベントが揮発性メモリにしか保持されていない状態で受け入れ完了を報告してはなりません。

ステップ 8: 信頼境界の運用

取り込みラグ、耐久性のある受け入れレイテンシ、コンシューマーラグ、拒否されたイベント、シーケンスの欠落、ハッシュ検証の失敗、インデックスの鮮度、エクスポートの所要時間、および保持ジョブのエラーを測定します。キーへのアクセスを制限し、署名キーをローテーションし、復元と検証をテストし、監査ログ自体の監査証跡に対してアラートを発報します。

高品質な回答例

「私は監査ログを独立した証拠システムとして扱います。ビジネスサービスは、イベントID、テナント、アクター、認証コンテキスト、アクション、対象、結果、リクエストID、およびスキーマバージョンを含む正規化されたイベントを出力します。サービスは、イベントが複製された高耐久ログに到達した後にのみ受信完了を通知します。非同期コンシューマーが検索インデックスとエクスポートを構築するため、インデックスが失われても証拠から再構築できます。

証拠ログはテナントと時間によってセグメント化され、レコードをハッシュでリンクし、セグメントヘッダーに定期的に署名またはアンカーします。クエリはテナント、ロール、目的、および時間範囲によって認可され、クエリとエクスポート自体も監査されます。エクスポートには、そのフィルター、イベント数、セグメントハッシュ、および署名付きマニフェストが含まれます。取り込み障害時、セキュリティイベントは制限付きの耐久性緊急パスに入るか、元の高リスクなアクションが拒否されます。メモリ内バッファのみの状態は受け入れられたイベントとはみなしません。運用面では、取り込みレイテンシ、シーケンスの欠落、ハッシュの失敗、インデックスの鮮度、拒否されたイベント、保持エラーを監視し、インデックス再構築、キーローテーション、および高負荷テナントの分離を定期的に訓練します。このサービスは受信後の完全性を証明します。アップストリームのイベントが真実であったかどうかは、アイデンティティ、認可、およびビジネストランザクションによって別途確立されます。」

よくある間違い

  • 耐久性ストレージに記録される前にイベントを受け入れ完了とし、プロセスクラッシュ後にサイレントな欠落を生じさせる。
  • 変更可能なデータベーステーブルや通常のデバッグログを監査証拠として扱う。
  • 検索インデックスを唯一のコピーにしてしまい、破損時に再構築できなくする。
  • クエリ、エクスポート、保持期間の変更、キーローテーションにも監査が必要であることを忘れる。
  • ハッシュチェーンによってアップストリームのイベントが真実であったことまで証明できると主張する。

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

検索インデックス全体が失われた場合はどうなりますか?

証拠の取り込みは継続して利用可能な状態を保ち、不変のセグメントからインデックスを再構築し、イベント数、シーケンス、および署名付きマニフェストを使用して再構築された範囲を検証します。

取り込み障害中もビジネストラフィックを継続すべきですか?

イベントの重要度によって判断します。低リスクのアクションは制限付きの耐久性バッファに入ることが許容されます。確実に記録できない高リスクのセキュリティアクションは、拒否するか隔離された緊急パスを介してルーティングする必要があり、決してサイレントに許可してはなりません。

特定の高負荷テナントが他のテナントに悪影響を与えるのを防ぐにはどうすればよいですか?

テナントと時間でパーティショニングし、取り込み、クエリ、エクスポートのクォータを適用し、コンシューマーリソースを分離します。負荷テストを実施し、影響を受けていないテナントの耐久性およびクエリのサービスレベル目標(SLO)を検証する必要があります。

プライバシー保護のための削除と監査ログの保持はどのように共存しますか?

リーガルホールドとテナントポリシーによってフィールドを分類し、マスキングされたダイジェストや管理された参照を優先し、インデックス、オブジェクトセグメント、バックアップ全体に一貫して削除を適用し、ポリシーに基づいたアクションの検証可能な記録を保持します。

公開情報ソース

関連する質問

関連面接ツール

システム設計の回答には「回答する」を使用

まず要件を明確にし、スケール、アーキテクチャ、コンポーネント選定、トレードオフの順に進めます。

ツールを見る