代表的な面接トピック

システムデザイン面接:安全なサービス間コンテキスト伝播の設計

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

質問

あなたの会社では、実験ID、テナント、トレース相関などのリクエストコンテキストを500のサービス間で伝播させたいと考えています。伝播、検証、サイズ制限、信頼境界、オブザーバビリティ、および障害発生時の挙動を設計してください。

プロンプトとスコープ

コンテキストの伝播によりサービス境界を越えてリクエストを把握しやすくなりますが、すべてのダウンストリームサービスが伝播された値を受信してログに記録する可能性があります。OpenTelemetryでは、Baggageをトレースコンテキストに隣接する名前/値コンテキストとして定義し、セキュリティ上の影響について警告しています。ここでの中核となるスキルは分散境界の設計であるため、これは system-design に関する質問です。

面接官が評価するポイント

優れた回答では、トレースコンテキストをアプリケーションメタデータから分離し、フィールドの許可リスト(allowlist)と所有権を定義し、機密性の高い値が信頼できない境界を越えないようにします。また、ヘッダーサイズ、正規エンコーディング、サンプリング、リトライ、非同期メッセージ、およびコンテキストが不正または欠落している場合の処理を網羅します。さらに、伝播を制御不能なデータチャネルに変えることなく、その有用性を証明するメトリクスを含めます。

最初に確認すべき明確化のための質問

  • コンテキストを伝達するプロトコルは何か:HTTP、gRPC、キュー、またはスケジュールされたジョブか?
  • どのフィールドが診断用で、どのフィールドが動作に影響を与え、各フィールドの所有者は誰か?
  • テナント、リージョン、サードパーティサービス間にどのような信頼境界が存在するか?
  • 値はログ、メトリクスラベル、またはトレースのみのいずれに含めることが許可されているか?
  • ヘッダーサイズ、レイテンシ、可用性の最大許容量(バジェット)はどれくらいか?
  • 不正な形式のコンテキストは、拒否、除去(ストリップ)、または新しいルートへの置換のいずれを行うべきか?

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

「トレースコンテキストと承認されたビジネスフィールドを分離した、小さくバージョン管理されたエンベロープを定義します。各境界において、ポリシーライブラリが名前、サイズ、エンコーディング、テナントスコープ、および送信先の信頼性を検証し、許可されていない値を除去または拒否し、シークレットは決して転送しません。伝播は、制限されたヘッダーと明確なコンテキスト欠落時の動作を備え、同期的および非同期的なエッジの両方で機能する必要があります。抽出失敗、切り捨て、伝播カバレッジ、クロステナント違反、およびトレース結合率(trace join rate)を測定します。」

ステップごとの回答

ステップ 1: コンテキスト契約(コントラクト)の定義

所有者、型、最大長、機密性、保持期間、および許可された送信先を含むフィールドのレジストリを作成します。トレース識別子はトレースプロトコル内に保持し、承認されたビジネスメタデータのみを個別のbaggageのようなキャリアに配置します。コンシューマーが未知の重要なフィールドを拒否できるように、エンベロープをバージョン管理します。

ステップ 2: 境界ポリシーの適用

キャリアをパースし、エンコーディングとサイズを検証し、テナントと信頼ゾーンをチェックして、サニタイズされたキャリアを出力する共有ミドルウェアまたはサイドカーポリシーを使用します。任意のインバウンドヘッダーをアウトバウンドリクエストにそのままコピーしてはなりません。明示的なポリシーで転送が許可されていない限り、サードパーティおよびクロステナントの呼び出しは新しい信頼ルートとして扱います。

ステップ 3: トランスポートとリトライの処理

HTTP、gRPCメタデータ、およびメッセージ属性に対して同等のキャリアを定義します。非同期ジョブを相関させるために必要なフィールドのみを永続化し、シークレットをキューにシリアライズしないでください。リトライ時には、オリジナルのトレース関係を維持しながら、再検証なしに重複した、または古いビジネス上の決定が信頼されるのを防ぎます。

ステップ 4: 障害動作の設計

不正な形式またはサイズ超過のコンテキストは、エンドポイントのリスクに応じて除去または拒否されるべきですが、安全な場合は新しいローカルトレースルートを使用してリクエスト自体のオブザーバビリティを維持します。生の値ではなく、理由コード付きのカウンターを公開します。ポリシーのバージョンと適用結果をオペレーターが確認できるようにします。

ステップ 5: 運用と価値の証明

トレース結合率、抽出および注入の失敗、追加されたバイト数、切り捨て、ポリシーによる拒否、境界越えの違反、およびキューシリアライゼーションエラーを追跡します。安全にサンプリングを行い、無制限で高カーディナリティなメトリクスラベルを回避します。サポートされているすべてのプロトコルに対してコントラクトテストを追加し、拒否を適用する前にポリシーのカナリアロールアウトを実施します。

モデル回答

「伝播されるコンテキストは信頼できないデータチャネルとして扱います。バージョン管理されたレジストリにより、伝達可能な診断およびビジネスフィールド、それらの機密性、サイズを定義します。ミドルウェアが各ホップで検証とサニタイズを行い、サードパーティおよびクロステナントの呼び出しにはより厳格なルールを適用します。シークレットがキャリアやキューに入ることは決してありません。トレースコンテキストはビジネス用のbaggageとは分離されたままにします。HTTP、gRPC、非同期属性をサポートし、除去と拒否を定義し、結合率、ポリシー障害、バイト数、違反を測定します。カナリアロールアウトと理由コード付きメトリクスにより、オブザーバビリティを損なうことなくポリシーを厳格化できます。」

よくある間違い

  • すべてのインバウンドヘッダーを転送する → 信頼できないデータが境界を越える → 許可リストとサニタイザーを使用する。
  • トークンやPIIをbaggageに含める → ダウンストリームのログやサービスがそれらを露出させる可能性がある → 機密データは除外する。
  • baggageをメトリクスラベルとして使用する → カーディナリティとコストが爆発的に増加する → 制限された理由コードとディメンションを記録する。
  • キューとリトライを無視する → 非同期処理がコンテキストを失うか古いコンテキストを信頼してしまう → トランスポート固有の契約を定義して再検証する。
  • すべての不正なリクエストを拒否する → オブザーバビリティと可用性が低下する → エンドポイントのリスクに応じて除去または拒否を選択する。
  • サイズバジェットがない → ヘッダーがプロキシの障害を引き起こす → 各フィールドとキャリア全体のサイズに上限を設ける。

フォローアップの質問

フォローアップ 1: テナントIDは伝播されるべきですか?

宛先がそのテナントに対して認可されており、値が認証されたIDに対して検証されている場合にのみ伝播されるべきです。それ自体が権限となってはなりません。

フォローアップ 2: トレースコンテキストとbaggageの違いは何ですか?

トレースコンテキストはスパンと伝播状態を接続します。Baggageはアプリケーション定義の名前/値データを伝達するため、より厳格な機密性、所有権、宛先ポリシーが必要です。

フォローアップ 3: ヘッダーの肥大化をどのように防ぎますか?

フィールドごとおよび合計のバジェットを設定し、理由コード付きメトリクスを伴って拒否または切り捨てを行い、より大きなコンテキストが避けられない場合はサーバー側の状態への制限付き参照を優先します。

フォローアップ 4: 信頼できない境界では何が起こりますか?

未承認のフィールドを除去し、ポリシーで許可されたトレース情報のみを作成または継続し、機密性の高い値を記録することなくポリシー決定をログに記録します。

公開情報ソース

関連する質問

関連面接ツール

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

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

ツールを見る