プロンプトとコンテキスト
複数のビジネスサービスが同じ問いに答える必要があります。「誰が、どのリソースに対して、どのアクションを実行できるか?」サブジェクト、アクション、リソース、コンテキストを受け取り、ALLOW または DENY を返し、ユーザー、サービスアカウント、階層型リソース、テナント境界、ポリシー変更をサポートする共通の判定サービスを設計してください。
面接の前提条件として以下を使用します:ベースラインで毎秒 100,000 件の認可チェック、ピーク時は平均の 3 倍、p99 で 20 ms のレイテンシ目標、ポリシーの書き込みは読み取りに比べて大幅に低頻度、呼び出し元は明示的な拒否と認可サービスの一時的な利用不可を区別できる必要があります。これらは問題設定上の前提条件であり、業界のベンチマークではありません。決済処理、キー発行、ビジネスデータベースへの書き込みは本サービスの対象外とします。
面接官が見ているポイント
優れた回答は、「RBAC サービスを追加する」とだけ答えるのではなく、認可を 4 つの要素のタプルおよび整合性契約として捉えます。
- サブジェクト、リソース、アクション、コンテキスト、階層、テナント間参照の境界のモデリング
- ACL、RBAC、ABAC、関係ベースのポリシー(ReBAC)がそれぞれ適する場面と、サービス間でポリシーロジックが乖離するのを防ぐ方法
- 判定読み取りパス、ポリシー書き込みパス、キャッシュ、無効化イベントがどのように連携するか
- ポリシー変更がいつ反映されるか、古いキャッシュによってアクセスが誤って許可され続けないか
- リスク分類ごとに、障害時にフェイルオープンとするかフェイルクローズとするか
- ログ、判定理由、リプレイ、フォールトインジェクションを用いて、テナント間の情報漏洩なしに正しく拒否できることをどう証明するか
確認すべき明確化のための質問
設計を左右する制約について質問します:
- 整合性ウィンドウはどのくらいですか? 権限剥奪を 5 秒以内に反映させる必要がある場合、キャッシュのリースとバージョントークンは 5 秒を満たす必要があります。分単位の許容範囲であれば、より長い TTL が可能です。
- チェックは単一リソースの検索ですか、それとも関係クエリですか? 「このユーザーはこのドキュメントを閲覧できるか?」は、メンバーシップ、グループ継承、親リソースに依存する場合があります。これにより、関係グラフが必要かバッチチェックが必要かが決まります。
- 障害時には何が許可されますか? 公開コンテンツはフェイルオープンが許容される場合がありますが、決済、個人データ、管理操作は通常フェイルクローズにします。慣習ではなくリスクに基づいて選択してください。
- 誰がポリシーを作成・レビューしますか? ビジネスチームが直接公開する場合は、バージョン管理、承認、静的チェック、ロールバックが必要です。セキュリティチーム専用の作成フローであれば、管理対象の範囲を狭めることができます。
- 呼び出し元は判定理由を必要としますか? デバッグには一致したルール ID が必要な場合がありますが、クライアント向けの説明で別テナントのリソースやポリシーを漏洩させてはなりません。
30秒の回答フレームワーク
次の構成から始めます:
「リクエストを (principal, action, resource, context) としてモデル化します。ポリシーエンジンは、許可(allow)、拒否(deny)、ポリシーバージョン、および制御されたデバッグに必要な場合の内部ルール ID を返します。コントロールプレーンはテナントスコープのポリシーと関係データを管理し、データプレーンはローカルの読み取り専用キャッシュ内の不変でバージョニングされたスナップショットを評価します。公開時にはリプレイ可能な無効化イベントを発行し、呼び出し元が最小ポリシーバージョンを送信することで、古いスナップショットが新しい判定を暗黙的に上書きしないようにします。機密性の高いパスは認可が利用できない場合にフェイルクローズとし、低リスクの読み取りは明示的なプロダクトポリシーに基づく場合のみグレースフルに縮退させます。権限剥奪の伝播、テナント間境界、キャッシュ競合、依存関係の障害は、フォールトインジェクションとリプレイによって検証します。」
これにより、フォローアップで特定の領域を深掘りする前に、モデル、データフロー、整合性、障害時の動作を提示できます。
ステップバイステップの詳細設計
まずポリシーのセマンティクスを定義する。 サブジェクトはユーザー、サービスアカウント、またはグループです。リソースはテナント、プロジェクト、または階層内のドキュメントです。アクションは read、write、share などの限定された語彙にする必要があります。コンテキストにはデバイスの状態、アクセス元、時間を含めることができますが、未検証のクライアントフィールドは信頼できる事実ではありません。NIST の ABAC ガイドラインでは、サブジェクト、オブジェクト、環境の属性を判定の入力として扱います。関係ベースのポリシーでは、メンバーシップを探索可能なエッジとして表現します。
コントロールプレーンとデータプレーンを分離する。 コントロールプレーンは、ポリシーの編集、検証、承認、バージョニング、ロールバックを行います。データプレーンは公開済みの不変スナップショットのみをロードし、チェックに応答します。ビジネスサービスごとに異なるポリシーパーサーを実装すべきではありません。公開により単調増加するバージョンと無効化イベントが生成され、データプレーンはスナップショットをアトミックにスワップするため、中途半端に公開されたルールセットが参照されることはありません。
チェック API を設計する。 内部インターフェースは次のようになります:
Check(principal, action, resource, context, min_policy_version)
-> decision, policy_version, rule_id, expires_at
BatchCheck(principal, [(action, resource, context)...])
-> decisions[]rule_id は制御されたログおよびデバッグ用です。テナントをまたぐ呼び出し元がエラーの詳細を通じてリソースの存在を特定できてはなりません。バッチチェックはラウンドトリップを削減しますが、バッチサイズと評価コストの制限が必要です。
整合性とキャッシュを処理する。 ローカルキャッシュにより 20 ms の目標を達成できますが、権限剥奪を TTL だけに頼ることはできません。呼び出し元は自身が確認した最新のポリシーバージョンを送信できます。ローカルバージョンが遅れている場合、サービスは共有レプリカを読み取るか、「一時的に判定不能」を返します。無効化イベントにはリプレイカーソルと定期的な調整(reconciliation)が必要であり、通知の欠落によって古い allow が残存しないようにします。機密性の高いリソースについては、リソースバージョンまたは短いリースを含めることで、権限とオブジェクトのバージョンが同時にチェックされるようにします。
障害時の動作を選択する。 データプレーンがコントロールプレーンに到達できない場合でも、期限内のロード済みスナップショットは処理を継続できます。期限切れ後は、決済、個人データ、管理アクションはフェイルクローズにする必要があります。公開静的コンテンツは、承認されたプロダクトルールがある場合のみフェイルオープンにできます。タイムアウトは偽装された DENY ではなく、明示的な UNAVAILABLE である必要があります。そうでなければ、ビジネスロジックがインフラの障害とユーザーの権限不足を混同してしまいます。
テナントの分離と不正利用の防止。 すべてのポリシーオブジェクトとキャッシュキーにテナント ID を付与します。サーバーは任意のリクエストボディのフィールドを信頼するのではなく、検証済みのアイデンティティからテナントを導出します。サブジェクト、テナント、バッチごとにクォータを適用し、関係の深さとポリシーの複雑さに上限を設けて、単一のテナントが評価リソースを枯渇させないようにします。
監査と検証。 リクエストハッシュ、サブジェクト、アクション、リソースタイプ、判定結果、ポリシーバージョン、レイテンシ、障害クラスを記録します。機密な値は不可逆な識別子として保持します。権限剥奪後の古いキャッシュ、グループ継承の循環、テナント間での同一リソース ID、公開中のクラッシュ、無効化イベントの重複や欠落、データプレーンの再起動、依存関係のタイムアウトをテストします。受け入れ条件として、単に DENY を返すだけでなく、ポリシーバージョンをリプレイして判定理由を説明できることが求められます。
ボトルネックを見積もる。 ベースラインで毎秒 100,000 チェック、ピーク時で 300,000 チェックの場合、リクエストあたり 2 KB とするとピーク時のイングレスは約 600 MB/s になります。リクエストごとにポリシー全体を送信するとレイテンシと帯域幅が増大するため、ローカルスナップショット、バッチチェック、リードレプリカを優先します。関係のトラバーサルがボトルネックになる場合は、テナントまたはリソースごとにシャーディングし、探索の深さとファンアウトを制限します。負荷テストによってこれらの前提条件をどのように置き換えるかを述べてください。
質の高い回答例
「まず、権限剥奪の目標時間と障害時の安全境界を確認します。ピーク時に毎秒 300,000 チェック、p99 目標 20 ms、権限剥奪が 5 秒以内に有効化されると仮定します。コントロールプレーンとデータプレーンを分離します。コントロールプレーンはテナントスコープの ACL、グループ関係、ABAC 条件を保存し、公開前に構文、循環、テナント間参照をチェックした上で、不変スナップショットと単調増加するバージョンを作成します。各リージョンのデータプレーンは、ローカルの読み取り専用キャッシュから (subject, action, resource, context) を評価します。無効化イベントはカーソルを持ちリプレイ可能です。呼び出し元は min_policy_version を送信できるため、キャッシュが遅延している場合は共有レプリカを読み取るか UNAVAILABLE を返します。
決済、個人データ、管理アクションについては、スナップショットの期限切れや依存関係の利用不可時にフェイルクローズします。公開コンテンツの縮退にはプロダクトの明示的な承認が必要です。結果にはポリシーバージョンと内部ルール ID が含まれます。ログには他テナントのデータを反映させることなく、判定、レイテンシ、エラークラスを記録します。機密性の高いオブジェクトは、リソースバージョンまたは短いリースによって、権限剥奪後に古い allow が適用されるのを防ぎます。負荷テストはピークトラフィックと最深の関係トラバーサルをカバーし、フォールトインジェクションは無効化の欠落、権限剥奪の競合、テナント間 ID、リージョンの再起動をカバーします。定期的な調整とバージョニングされたリプレイにより、説明できない allow が存在しないことを証明する必要があります。」
これは、前提条件、モデル、整合性、障害処理、検証を結びつけています。面接では制約の変更に応じて詳細を調整してください。毎秒 300,000 チェックや 5 秒という数値は、すべての本番環境で一律に適用される事実ではありません。
よくある間違い
- すべてのケースを RBAC に単純化してしまう。 ロールは階層、継承された関係、環境条件を自然に表現できません。モデルを選択する前に権限のセマンティクスを定義してください。
- 権限剥奪の手段として固定 TTL だけを使用する。 TTL は古さの一形態を制限するだけで、通知の欠落やバージョンの競合は解決しません。バージョン管理、リプレイ可能な無効化、調整メカニズムを追加してください。
- 常にフェイルオープンまたは常にフェイルクローズにしてしまう。 リソースのリスクは異なります。セキュリティ基準、スナップショットの鮮度、ビジネス上の可逆性から動作を定義してください。
- ポリシーロジックを各サービスにコピーしてしまう。 複数のパーサーが存在すると実装が乖離し、異なる拒否判定が発生します。ポリシーをバージョニングし、単一の判定インターフェースを呼び出してください。
- 「リソースが存在しません」や詳細なルールを返してしまう。 これによりテナント間の情報が漏洩します。安定した外部エラーと制御された内部ルール ID を使用してください。
- 通常の allow パスのみをテストする。 認可が破綻するのは、権限剥奪、リプレイ、循環参照、テナント境界においてです。フォールトインジェクションとバージョニングされたリプレイを活用してください。
フォローアップの質問と回答
権限剥奪を即時に反映させる必要がある場合でも、ローカルキャッシュを維持できますか?
はい、ただしキャッシュ単体で判定を完結させることはできません。権限剥奪によってグローバルに観測可能なバージョンまたはリースの無効化を作成する必要があります。機密性の高いリクエストには最小ポリシーバージョンを含め、遅延しているキャッシュはローカルデータをバイパスするか確認を待ちます。許容時間内に確認が取れない場合は、古い allow を暗黙的に使用するのではなく、UNAVAILABLE を返すか deny とします。
親グループを介した関係のトラバーサルで循環が見つかった場合はどうなりますか?
公開時に循環を拒否した上で、実行時にも最大深度、ノード数、時間予算を強制します。評価エンジンは訪問済みノードを追跡し、重複したブランチを停止して、診断可能な内部エラーを返します。循環によって 1 回のチェックが無制限の処理になってはなりません。
テナント間で認可の混混同(不正アクセス)がないことをどのように証明しますか?
ポリシーの名前空間とキャッシュキーのプレフィックスでテナントスコープを必須とし、サブジェクトのテナントをサーバー側のアイデンティティから導出します。プロパティテストを用いて異なるテナント間で同一のリソース ID を生成し、すべての allow がサブジェクト、リソース、ポリシーのテナントの一致を満たしていることを検証します。ログのサンプリングと deny パスのリプレイを追加します。
Zanzibar の外部整合性モデルを必ず模倣する必要がありますか?
いいえ。権限剥奪の目標とビジネスリスクに基づいて、バージョントークン、リース、またはより強い整合性を選択してください。削除されたばかりのメンバーが古いオブジェクトを閲覧し続けられないことをプロダクトとして保証する必要がある場合、因果順序付けとオブジェクトバージョンが妥当です。リスクの低い公開コンテンツであれば、より弱い整合性と長めのキャッシュの方がシンプルな場合があります。保証内容とそれにかかるコストを明確に説明してください。