質問とシナリオ
エンタープライズ顧客があなたの SaaS をサービスプロバイダーとして利用しており、そのアイデンティティプロバイダーがユーザーとグループの変更を送信してきます。リクエストは重複、順序の入れ替わり、遅延、またはタイムアウト後のリトライが発生する可能性があります。このサービスは、SCIM 2.0 のリソースおよびエラーセマンティクスを維持しながら、テナント、外部識別子、グループメンバーシップ、論理削除、監査可能性、および迅速な失効をサポートする必要があります。
面接官がテストしていること
- 候補者は SCIM の User、Group、
schemas、フィルタリング、および PATCH セマンティクスを理解しているか? - 外部リソースマッピング、冪等性キー、同時更新、およびリトライを単一のデータフローに結び付けることができるか?
active=false、削除リクエスト、およびアプリケーションセッション失効を区別できているか?- テナント分離、トークンスコープ、監査、レート制限、および機密フィールドの保護を適用できるか?
最初に確認すべき明確化のための質問
アイデンティティプロバイダーがプロファイルの権威(Authoritative)であるか、グループがプッシュされるか、物理削除が許可されているか、同期レイテンシの目標、およびテナントの規模を確認します。外部の userName が不変であるか、メールアドレスの変更が発生するか、グループサイズの上限、一括処理(Bulk)サポート、および無効化後に既存のセッションがどれだけ迅速に失効する必要があるかを明確にします。メールアドレスを変更不能な主キーとして使用しないでください。
30秒の回答フレームワーク
SCIM の外部リソースとローカルアカウントをテナントスコープのマッピングに保存し、安定した外部識別子を内部 ID と分離して管理します。リクエストフィンガープリントとバージョンを用いて、作成、更新、PATCH、削除、およびクエリを冪等にします。古い書き込みは明示的に拒否します。active=false は無効化とセッション失効をトリガーし、削除はテナントの保持ポリシーに従います。すべてのリクエストでテナント、トークンスコープ、および監査コンテキストを検証し、リトライ可能な非同期処理によって権限が重複して付与されないようにします。
ステップごとの詳細解説
- リソース境界を定義する。
/Users、/Groups、/ResourceTypes、/Schemas、/ServiceProviderConfigなど、実際にサポートする SCIM 機能を公開します。schemasを各リソースタイプと整合させ、サポートされていないフィルターには正規化されたエラーを返します。 - アイデンティティマッピングを構築する。 テナントごとに、外部リソース ID、ローカルユーザー ID、送信元システム、および現在のバージョンを保存します。
userNameやメールアドレスなどの可変フィールドは検索や表示のためのものであり、安定したマッピングを置き換えるものではありません。競合が発生した場合は、サイレントにマージするのではなくレビューを要求します。 - 冪等性と並行性制御を実装する。 重複した POST は既存のリソースを返すか、リクエストフィンガープリントから安全に再実行します。PATCH 操作は個別に適用し、結果を記録します。サポートされている場合は、
ETagまたはバージョン条件を要求し、古い書き込みが新しいデータを上書きできないようにします。 - ユーザーとグループのライフサイクルを処理する。
active=falseはアプリケーションの権限を取り消し、新しいログインをブロックし、現在のセッションを失効させます。物理削除は保持および監査ルールに従います。グループメンバーシップは差分(Set difference)によって更新します。部分的な障害によって、確認されていないすべてのメンバーが削除されてはなりません。 - 非同期処理を分離する。 API がローカルのファクトテーブルに書き込んだ後、権限の同期、ウェルカム通知、および監査イベントをキューに追加します。メッセージにはテナント、リソースバージョン、および冪等性キーを含めます。コンシューマーの重複によってアクセス権が付与されたり通知が二重送信されたりしないようにします。
- サービスを保護および運用する。 SCIM トークンはローテーション、失効、および有効期限を設けて、1つのテナントと操作スコープに制限します。ページネーション、フィルター、および一括サイズを制限します。完全なトークンや機密属性をログに記録することなく、成功、拒否、競合、リトライ、および無効化レイテンシを記録します。
質の高い模範解答
SCIM API を、外部のアイデンティティソースからローカルアカウントへの同期境界として扱います。各テナントは独自のトークン、リソースマッピング、および監査証跡を取得します。User リソースと Group リソースは安定した外部 ID と内部 ID を保持し、SCIM スキーマに従います。サポートされていないフィルター、PATCH 操作、または返却可能性(returnability)ルールは、推測するのではなく明示的なエラーを生成します。
書き込みはまずローカルのファクトテーブルに書き込まれ、次にリソースバージョンごとにリトライ可能な権限反映処理がキューに追加されます。外部 ID、リクエストフィンガープリント、および条件付きバージョンにより、リトライが冪等になります。古いバージョンが新しいデータを上書きすることはできません。active=false は権限を取り消し、新しいログインをブロックし、セッションを失効させ、削除は保持ポリシーに従います。グループの更新には差分を使用し、未確認のメンバーをクリアすることなく部分的な障害をリトライします。テナントごとの同期レイテンシ、競合、無効化からセッション失効までの時間、およびデッドレターを監視します。参考資料には RFC 7643、RFC 7644、および Okta の SCIM 実装ガイダンスが含まれます。
よくある間違い
/ServiceProviderConfig、フィルター、PATCH、エラータイプ、およびページネーションを考慮せずにPOST /Usersのみを実装すること。- メールアドレスを唯一のキーとして使用し、重複を作成したり、改名後に誤ったアカウントにリンクしたりすること。
- タイムアウトのリトライを新しいコマンドとして扱い、権限を二重に付与したり、通知を二重に送信したり、より新しいフィールドを上書きしたりすること。
- トークン、権限、および現在のセッションを取り消すことなく、
active=falseの後にユーザーを非表示にするだけにとどめること。 - 部分的な同期障害の後にすべてのローカルグループメンバーをクリアし、一時的なネットワーク問題を広範なアクセス喪失や過剰な権限付与に変えてしまうこと。
フォローアップの質問と回答
アイデンティティプロバイダーが同じ作成リクエストを繰り返した場合はどうなりますか?
テナントと外部リソース ID を検索し、リクエストフィンガープリントまたはバージョンを保持します。既存のリソースに対して安定した表現を返します。ペイロードが競合する場合は、ローカルの変更をサイレントに上書きするのではなく、診断可能なエラーを返して監査します。
メールアドレスが変更された後、アカウントの継続性をどのように維持しますか?
メールアドレスを可変属性とし、安定した外部リソース ID とローカルアカウント ID のマッピングを使用します。テナントレベルの一意性を確認し、表示およびログイン用のエイリアスを更新し、メールアドレスに基づいて新しいアカウントを作成したり、テナント間でマッチングを行ったりしてはなりません。
無効化とログインが同時に到着した場合、どのように安全性を確保しますか?
認可は、線形化可能なアカウント状態または失効バージョンを読み取ります。無効化によってバージョンが進み、セッションが失効します。ログインは資格情報を発行する前にもう一度それを確認し、古い非同期権限タスクがまだ実行中であっても、無効化されたアカウントを拒否します。