
ケース面接
2026/11/03
技術設計面接(システムデザイン面接)のお題「SaaSの権限分離」を題材に、事前に押さえておく知識、面接で引き出せる前提、論点、模範解答、よくあるつまずきを順に解説します。
ほかのお題の解説は技術設計面接の解説と模範解答まとめにあります。
この記事で使う設計の基礎は、日本語のシステムデザイン面接の教材 SystemDesign InterviewCat で詳しく学べます。この記事の各節に関係する章は次のとおりです。
InterviewCat の章 | この記事で関係する節 |
|---|---|
SystemDesign InterviewCat の全体像 | |
面接で見られることと進め方 | |
事前知識、6. 判定の置き場所 | |
5. テナントの境界 | |
4. 全体構成(入口で必ず通す判定)、代わりの案 | |
6. 判定の置き場所(権限データのキャッシュと反映) | |
2. 見積もり、6. 一覧の絞り込み | |
5. テナントの境界(検索の境界) | |
3. データモデル(権限の変更と変更履歴を同時に書く) |
設計面接では、お題を聞いた時点で「たぶんこの作りだろう」という仮説を持ち、前提を聞くたびにそれを確かめたり崩したりします。権限の仕組みのお題なら、まず「誰が、どのデータに、どの操作をしてよいか」をどういう形のデータと規則で表すかの選択肢を押さえておきます。この表し方を権限モデルと呼びます。あわせて、他社のデータをどこで止めるかも押さえておきます。
経理担当の佐藤さんが、営業第一課の鈴木さんが出した申請を開こうとしたとします。開いてよいかを決めるとき、判定は次のデータをたどります。権限モデルの違いは、このうちどこまでを見るかの違いです。

佐藤さんが鈴木さんの申請を開いたとき、方式ごとに判定で起きることを並べます。
RBAC(ロールベースのアクセス制御):利用者にロールを割り当て、ロールに操作を持たせます。図の 1 本目の線のとおり、判定は「佐藤さんのロールのどれかが『申請を見る』を含むか」で終わるので速く、各社の管理者にも仕組みが分かりやすいです。弱いところは、どのデータに対して許すかを表せないことです。佐藤さんは営業部の申請も開発部の申請も同じように開けます。「自部署の申請だけ見られる経理」を作るには「営業部の経理」「開発部の経理」のように部署の数だけロールを作ることになり、部署が増えるたびにロールも増えます。
範囲つきの RBAC:RBAC の割り当てに範囲を持たせます。図の 2 本目の線のとおり、判定は範囲の箱まで進み、申請の部署(営業第一課)が佐藤さんの範囲(営業部とその配下)に入るかを見ます。ロールは経理担当 1 つのまま「自部署だけ」「特定プロジェクトだけ」を表せます。一覧の絞り込みも「申請の部署がこの部署 ID のどれかに入る」という SQL の条件にそのまま変えられます。RBAC と比べて管理者が選ぶものは範囲が 1 つ増えるだけです。弱いところは、データ 1 件ごとに変わる関係を表せないことです。「自分の申請だけ編集できる」「申請者の上位役職者だけが承認できる」は、どの割り当てを作っても書けません。
ABAC(属性ベースのアクセス制御):利用者、データ、操作、環境(時刻や接続元など)の属性を、規則に当てはめて判定します。図の 3 本目の線のとおり申請の属性まで見るので、「申請の部署が、佐藤さんの所属部署の配下にあり、佐藤さんの役職が鈴木さんより上」のような条件も規則として書けます。表せる条件は RBAC よりずっと広いです。RBAC と比べると、管理者が規則を条件式で書く必要があり、「この人は何ができるか」を一覧で答えにくくなります。また、規則が複雑になると一覧の絞り込みを SQL の条件に変えにくくなります。
ReBAC(関係ベースのアクセス制御):利用者とデータの関係(作成者、共有された人、上位の部署など)をグラフとして持ち、図の上の線のように佐藤さんと申請の関係をたどって判定します。Google の Zanzibar が代表例で、共有の多い文書サービスのように、データごとに見てよい人が変わるサービスに向いています。弱いところは、関係のデータを業務データとは別に持つと、両者をそろえ続ける仕組みが要ることです。一覧の絞り込みにも「見てよい ID の一覧」を取り出す処理が別に要ります。1 つのモノリスと 1 つの RDB に入れるには、仕組みが大きくなります。
方式名は分類の名前で、実際のサービスは組み合わせて使います。設計面接で比べたいのは名前ではなく、各社の管理者が設定する部分と、開発者がコードで決める部分をどこで分けるかです。
方式の違いは、このお題で出てくる 2 つの要望と、1,000 件の一覧、管理者による設定の 4 つで比べると分かりやすくなります。
方式 | 自部署の申請だけ見られる経理 | 申請者の上位役職者だけが承認 | 1,000 件の一覧を絞る | 各社の管理者が設定できるか |
|---|---|---|---|---|
RBAC | 部署の数だけロールを作る | 表せない | ロールで決まるので全件か 0 件 | できる |
範囲つきの RBAC | 割り当ての範囲で表せる | 表せない | 範囲の部署 ID を SQL の条件にできる | できる(範囲を選ぶだけ) |
ABAC | 規則で表せる | 規則で表せる | 規則を SQL の条件に変える仕組みが要る | 難しい(条件式を書かせることになる) |
ReBAC | 部署との関係で表せる | 部署の上下はたどれる。役職の上下の比較は別に要る | 見てよい ID の一覧を取り出す処理が要る | 関係の種類は開発者が決め、管理者は関係を結ぶだけ |
表から分かるとおり、管理者が設定しやすい方式(RBAC、範囲つきの RBAC)はデータ 1 件ごとの関係を表せません。それを表せる方式(ABAC、ReBAC)は、規則を条件式で書くか、関係のデータを別に持つ必要があり、一覧の絞り込みにも別の仕組みが要ります。そのため、管理者が設定するのはロールと範囲までにし、データ 1 件ごとの関係は開発者が書く少数の規則に任せる組み合わせが、このお題の出発点になります。
権限モデルとは別に、このお題で一番重いのは他社のデータを見せないことです。テナントは、SaaS を契約した単位のことで、このお題では顧客の企業です。多くの企業のデータを 1 つの DB に入れ、どの表にも企業 ID の列を持たせる作りでは、企業 ID の条件をどこで足すかがテナントの境界になります。条件に使う企業 ID は、ログインのときに外部の認証サービス(IdP)が渡す証明(トークン)に、利用者 ID と一緒に入っています。
止める場所 | 何が起きるか | 書き忘れたとき |
|---|---|---|
各 SQL に企業 ID の条件を書く | API ごとに書く | 1 か所忘れると他社の行が返る |
DB を読み書きする共通処理(リポジトリ層)で条件を足す | 共通処理を通る SQL には必ず付く | 共通処理を通らない SQL と、DB の外(検索、ファイル)が残る |
DB の行レベルセキュリティ(DB 自身が、接続ごとに設定した企業 ID と違う行を返さない機能) | アプリが条件を忘れても DB が絞る | 制限を有効にして方針を書き忘れた表は何も返さない。有効にし忘れた表は絞られない |
上の 2 つはアプリの中で止め、3 つ目は DB が止めます。止める場所を 2 か所以上に分けておけば、1 か所で書き忘れても他社の行は返りません。
お題文だけを読んだ段階では、次の仮説を置きがちです。どれも筋は悪くありませんが、前提を聞くと一部が崩れます。答え合わせは「隠れていた前提を見直す」で行います。
仮説 | 中身 | 確かめること |
|---|---|---|
1 | 企業ごとにカスタムのロールを作れる RBAC にすればよい | ロールで表せない条件の要望があるか、設定するのは誰か |
2 | 判定を共通の関数にまとめ、各 API の先頭で呼べばよい | API の数、開発の体制、確認漏れの事故があったか、一覧の速さ |
3 | トークンの企業 ID を各 SQL の条件に書けば、他社のデータは見えない | 書き忘れの事故があったか、1 人が複数の企業を扱う場面、DB 以外の置き場所、代理ログイン |
4 | 権限はログインのときに読み、セッションの間は使い回せばよい | 変更の反映までの許容時間、変更履歴の保存 |
面接官から示されるお題は次のとおりです。
本日はシステムの設計方法についてディスカッションしたいと思います。今、経費精算SaaSで、顧客の会社ごとに誰が何をできるかを細かく設定できる権限の仕組みを作ることを考えています。今は管理者と一般の2つのロールしかないので、申請・承認・差し戻し・支払いデータの出力・マスタの設定などの操作ごとに、誰に許すかを企業ごとに設定できるようにしたいです
▼このお題は CaseMatch の AI 面接で、面接官に前提を質問しながら練習できます。
前提は質問すれば答えてもらえます。面接で引き出せる前提を、権限モデルの選び方に関わるものとそれ以外に分けて並べます。種類の列は、機能要件、非機能要件、制約、将来のどれにあたるかです。設計への影響の列は、次の節の問いを考えてから読んでください。
事前知識の比較表の 4 つの比べ方(自部署だけ、上位役職者だけ、一覧の絞り込み、管理者による設定)と、判定の速さ、反映の速さを決める前提です。
種類 | 前提 | 値 | 設計への影響 |
|---|---|---|---|
機能 | 要望 | 大口企業から「自部署の申請だけ見られる経理」「特定プロジェクトの申請だけ承認できる人」の要望がある | ロールだけでは表せず、割り当てに範囲が要る |
機能 | 承認者 | 承認できるのは申請者の所属部署の上位役職者に限る。部署は最大6階層で、異動や兼務(1人が複数部署)がある | 申請ごとに変わる関係で、開発者が書く規則になる |
機能 | 自社定義 | 経理担当・承認者などを自社定義したい大口企業が多い | 企業ごとのカスタムのロールが要る |
制約 | 設定する人 | ロールを設定するのは各社の管理者で、ITに詳しくない人が多い | 管理者に規則を書かせられない |
非機能 | 操作の数 | 約150操作、新機能で増加 | 操作を画面で 1 つずつ選ばせると管理者が迷う |
非機能 | 操作の増え方 | 新機能は月に2〜3個増え、そのたびに操作が増える | 新しい操作を誰に許すかの既定値が要る |
非機能 | 性能 | 判定10ms以内、1,000件一覧1秒以内 | 一覧を 1 件ずつ判定できない |
非機能 | 反映 | ロール・割り当て変更は1分以内に反映 | 権限をセッションの間ずっと使い回せない |
制約 | 移行 | 今の「管理者」「一般」の利用者は、移行後も今と同じ操作ができる必要がある | 今の 2 つを標準のロールとして再現する |
テナントの境界、判定の置き場所、移行の進め方のように、どの権限モデルを選んでも別に設計が要る前提です。
種類 | 前提 | 値 | 設計への影響 |
|---|---|---|---|
機能 | 目標 | 新しい操作を足すたびに権限チェックを書き忘れる事故を、仕組みで起きないようにしたい | 判定を呼ぶかどうかを各 API に任せない |
制約 | 範囲 | ログインや認証の仕組みは変えない | トークンの中身を前提に作る |
非機能 | 規模 | 400社、最大2万人 | 1 人分の権限データは小さく、利用者ごとにキャッシュできる |
非機能 | 企業の大きさ | 1社あたりの平均は約50名、1万人を超える企業が5社 | 大きな企業では範囲の部署が多く、一覧の条件が重くなる |
制約 | DB | DBはRDB 1つで、全テーブルに企業IDの列がある | 企業 ID の絞り込みを書き忘れると他社の行が返る |
制約 | API | バックエンドはモノリスで、APIは約400本 | 判定は同じプロセスの中のモジュールで足りる |
制約 | 認証 | 認証は外部のIdPで、トークンには利用者IDと企業IDが入っている | 企業 ID は 1 つしか入っていない |
制約 | モバイル | 承認用のモバイルアプリも同じAPIを使い、古い版のアプリが残り続ける | 画面でボタンを隠すことを守りにできない |
制約 | 今の判定 | APIごとのif文で判定、確認漏れで別企業データが見えた事故が1件 | 書き忘れても漏れない作りが要る |
非機能 | 漏えい | 他社データの漏えいを絶対に許さない | 判定とは別の層でも他社の行を止める |
非機能 | 履歴 | 権限の変更履歴は7年保存する(SOC2の取得を予定) | 変更と同時に、書き換えない履歴を残す |
機能 | 代理ログイン | サポート担当が、顧客の許可を得て代理でログインする運用がある | 誰が誰として操作したかを両方残す |
制約 | 体制 | 開発はバックエンド8名で、機能ごとのチームが並行して開発している | 判定の書き方をチームごとにばらつかせない |
機能 | 会計事務所 | 会計事務所が、顧問先の複数の企業を1つのアカウントで操作したい | トークンの企業 ID だけでは操作中の企業が決まらない |
制約 | 移行期間 | 移行は1年かけて段階的に進め、その間も機能開発は止めない | 古い判定と新しい判定を並べて切り替える |
お題文は「操作ごとに、誰に許すかを企業ごとに設定したい」としか言っていません。前提の表は、質問して初めて出てきたものです。設計への影響を見る前に、あらためて前提を読み直し、お題文の裏に何が隠れていたかを考えます。先に次の問いを考えてから、前提の表の「設計への影響」の列と見比べてください。
前提の多くは単独では難しくありません。難しいのは 2 つが互いに逆を向いているところで、このお題では次の 3 組です。これがそのまま、面接の後半で詳しく問われる 3 つの論点(深掘り)になります。
ぶつかる前提 | なぜぶつかるか | 解き方 |
|---|---|---|
他社データの漏えいを許さない × 会計事務所が複数企業を 1 つのアカウントで操作、サポートの代理ログイン | 1 人が複数の企業に入れるようにすると、トークンの企業 ID で絞るだけでは足りず、境界の決め方が緩くなる | 1 つのリクエストで扱う企業を 1 つに決め、その企業 ID の条件をリポジトリ層と DB の 2 か所で必ず付ける |
判定を 1 か所に集めて書き忘れをなくす × 1,000 件の一覧を 1 秒以内 | 1 か所の判定関数を 1 件ずつ呼ぶと、一覧では判定が 1,000 回になる | 同じ規則から、1 件の判定と一覧の SQL の条件の両方を作る |
大口企業の細かい要望 × 設定するのは IT に詳しくない管理者 | 表せる条件を増やすほど、管理者が設定する項目が増えて難しくなる | 管理者が選ぶのはロールと範囲だけにし、データ 1 件ごとの関係は開発者が書く規則にする |
仮説 | 崩した前提 | 置き換え |
|---|---|---|
1. カスタムのロールを作れる RBAC | 自部署だけ、特定プロジェクトだけ、上位役職者だけ | カスタムのロールは残す。割り当てに範囲を持たせ、上位役職者や自分の申請のような関係は開発者が書く規則にする |
2. 共通の関数を各 API の先頭で呼ぶ | API 400 本、8 名が並行開発、確認漏れの事故、1,000 件一覧 1 秒 | 呼ぶかどうかを各 API に任せず、操作の宣言が無い API は動かないようにする。一覧は SQL の条件で絞る |
3. トークンの企業 ID を各 SQL に書く | 会計事務所、代理ログイン、確認漏れの事故 | 操作中の企業は、全 API が最初に通る共通処理(入口)で 1 つに決めてから絞る。絞り込みはリポジトリ層と DB の両方で行い、検索やファイル置き場にも企業 ID を持たせる |
4. ログイン時に読んで使い回す | 1 分以内の反映 | 企業ごとの権限の更新番号をキャッシュのキーに入れ、変更のたびに番号を上げる |
このお題はロールの種類を増やす話に見えます。しかし実際に問われるのは、400 社が 1 つの DB を使う中で、絞り込みを 1 つ書き忘れても他社のデータが出ない作りと、判定を 1 か所に集めて一覧や画面と食い違わない作りです。
論点は 3 つあり、重さの順にテナントの境界、判定の置き場所、権限モデルです。一番重いのは他社のデータが見えないことで、DB、検索、キャッシュ、ファイル置き場のどこで境界を守るかを決め、条件を 1 つ書き忘れても漏れない作りにできるかが問われます。次に、判定を 1 か所に集め、API、一覧の絞り込み、画面の表示が食い違わないようにできるかです。権限モデル(標準とカスタムのロール、ロールで表せない条件の扱い)はその次で、ログインの方式には深入りしなくて構いません。
模範解答の深掘り(5〜7)では、論点ごとに「弱い答え」「よい答え」「より良い答え」を並べ、何が足りないかを示しています。
面接での問答の順には合わせず、このお題への答えを 1 つの設計としてまとめた解答例です。設計の筋は、判定を 1 つの認可モジュールに集めて API の入口で必ず通し、他社のデータはそれとは別にリポジトリ層と DB の 2 か所でも止め、管理者にはロールと範囲だけを設定させる、というものです。前提に無いことは仮定として置き、その旨を書いています。
前提を確かめたうえで、最初に作る範囲を次のように切ります。
判定は 1 つのモジュールに集めますが、他社のデータを止める役目だけはそのモジュールに任せきらず、リポジトリ層と DB にも持たせます。
見積もりで出すのは、構成を決める 3 つの数字だけです。どれも前提の値から計算できます。
見積もり | 計算 | 決まること |
|---|---|---|
一覧の判定 | 1,000 件を 1 件ずつ判定すると、判定 10ms × 1,000 件 = 最大 10 秒 | 一覧は 1 件ずつ判定せず、SQL の条件にして 1 回で絞る |
移行の速さ | API 400 本 ÷ 約 50 週 = 週に約 8 本 | 一度に切り替えられないので、新旧の判定を並べ、API ごとに切り替える |
操作の数 | 約 150 操作に、新機能が月に 2〜3 個 × 12 か月 = 年に 24〜36 個加わる | 管理者が 1 つずつ選べないので業務のまとまりで並べ、新しい操作の既定値を決める |
1 分以内の反映はキャッシュの期限で満たせますが、権限を外したら次のリクエストから拒否したいので、変更のたびに企業ごとの更新番号(権限のデータを変えるたびに 1 つ増やす番号)を上げます(6)。
操作の一覧はコードで宣言し、DB には「どのロールがどの操作を持ち、誰にどの範囲で割り当てたか」と、規則が使う所属と部署の上下だけを置きます。中心になる表は次の 4 つで、どれも企業 ID の列を持ちます。
表 | 主な項目 | 書き換え |
|---|---|---|
ロール | 企業 ID、ロール ID、名前、標準かカスタムか、許す操作の一覧 | 管理者が変えるたびに企業の更新番号を上げる |
割り当て | 企業 ID、利用者 ID、ロール ID、範囲の種類(全社、部署とその配下、プロジェクト)、範囲 ID | 管理者が変えるたびに企業の更新番号を上げる |
所属 | 企業 ID、利用者 ID、部署 ID、役職(兼務は複数行) | 異動のたびに企業の更新番号を上げる |
部署の上下 | 企業 ID、上位の部署 ID、配下の部署 ID、階層の差 | 部署の構成を変えたときに作り直す |
部署の上下は、ある部署とそのすべての配下の組を前もって展開した表です。6 階層あっても「この部署の配下すべて」が 1 回の検索で取れるので、範囲の判定にも一覧の条件にも使えます。ロール、割り当て、所属を変えるときは、変更前と変更後の値、操作した人、日時を、同じトランザクションの中で追記のみの変更履歴に書き、7 年残します。
利用者のリクエストは、必ず入口と認可モジュールを通ってからデータに届きます。データを取り出すときは、認可モジュールとは別にリポジトリ層と DB が企業 ID で絞ります。

色を付けた認可モジュールがこの設計の要で、可否を決める規則はすべてここにあります。
バックエンドはモノリスで DB も 1 つなので、認可モジュールは同じプロセスの中のライブラリとして置きます。権限データも業務データと同じ RDB に置けるので、両者をそろえ続ける仕組みが要りません。
実例:Airbnb は、モノリスからサービスに分けたときに認可の確認を画面側のサービスに置いたところ、同じ確認があちこちに重複して管理しにくくなりました。そこで確認をデータ側のサービスに移し、判定を集めた Himeji を作っています(InfoQ, 2021)。Figma は、モノリスの中に散らばった権限の判定が DB の負荷の約 2 割を占め、HTTP の API とリアルタイムの API で判定を別々に書いて食い違っていました。規則を宣言的に書く仕組みを作り、規則とデータの読み込みを分けて、どちらの API も同じ規則を使うようにしています(Figma, 2024)。
代わりの案:認可を別のサービスに切り出し、Zanzibar のように関係のデータを専用の保存先に持つ構成もあります。複数のプロダクトで権限を共有したい場合や、サービスを分けたあとで判定を 1 か所に集めたい場合には有力です。今回は、モノリスで DB が 1 つ、開発が 8 名なので、関係のデータを業務データと別に持ってそろえ続ける手間のほうが大きくなります。認可モジュールの関数を「判定」と「一覧の条件」の 2 つに絞っておけば、あとで中身を別サービスに入れ替えても呼び出し側は変わりません。
他社のデータは、認可の判定とは別に、リポジトリ層と DB の 2 か所で止めます。どちらか一方で絞り込みを書き忘れても、もう一方が他社の行を返しません。最初の仮説の 3 は、ここで崩れます。
答えの段階 | 答え | 足りないところ |
|---|---|---|
弱い答え | トークンの企業 ID で、各クエリに WHERE を付けます | 1 か所書き忘れると漏れる。前提にある事故がまさにこれ |
よい答え | 企業 ID の絞り込みをリポジトリ層の共通処理にまとめます | 共通処理を通らない SQL と、DB の外(検索、キャッシュ、ファイル置き場)が残る |
より良い答え | 共通処理と DB の 2 か所で絞り、DB の外にも企業 ID を持たせます | なし(中身は下の 6 つ) |
より良い答えの中身は次のとおりです。
会計事務所と代理ログインは、1 人が自分の企業以外を扱う場面です。どちらも「1 つのリクエストで扱う企業は 1 つ」を守ったまま扱います。
実例:AWS の SaaS のテナント分離の解説は、認証のときにテナントの文脈を返し、その文脈が以降のすべての処理に渡って、DB などへのアクセスの範囲を決める形を基本に置いています(AWS, 2020)。PostgreSQL の行レベルセキュリティでテナントを分ける方法は、AWS のブログが
current_settingで接続ごとのテナント ID を読む方針の例とともに解説しており、テーブルの所有者で接続すると方針が適用されないこと、接続プールとの組み合わせに注意が要ることも挙げています(AWS, 2020)。行レベルセキュリティを有効にして方針が 1 つも無い表は、どの行も見えない状態になります(PostgreSQL)。方針を付け忘れた表は、他社の行を返すのではなく何も返さないということです。
判定は認可モジュールに集め、API の入口で必ず通します。呼ぶかどうかを各 API に任せず、操作の宣言が無い API は動かないようにします。最初の仮説の 2 と 4 は、ここで崩れます。
答えの段階 | 答え | 足りないところ |
|---|---|---|
弱い答え | 認可を共通の関数にまとめます | どこで呼ぶかが決まっておらず、呼び忘れは残る |
よい答え | API の入口で、操作の宣言を見て判定します | 一覧の絞り込みが別の場所に残り、判定と食い違う |
より良い答え | 操作の宣言を必須にし、1 件の判定と一覧の条件を同じ規則から作ります | なし(中身は下の 6 つ) |
移行は 1 年かけて API ごとに進めます。新しい認可モジュールを今の if 文と並べて動かし、結果が食い違ったら記録だけします。食い違いが無くなった API から新しい判定に切り替え、今の if 文を消します。機能チームは新しい API から宣言の形で書くので、移行の間も機能開発は止まりません。
実例:OWASP の認可のチートシートは、既定で拒否すること、すべてのリクエストで権限を確かめること、認可の処理に単体テストと結合テストを書くことを挙げています(OWASP)。一覧の絞り込みについては、Oso の文書が、1 件ずつ判定するのではなく見てよいものだけを 1 回で取り出す方法として、認可の規則から SQL の WHERE 句を作ってアプリの DB で絞る形を説明しています(Oso)。Airbnb の Himeji は判定の結果をキャッシュで返し、権限のデータが変わると変更を検出してキャッシュを消しています(InfoQ, 2021)。
管理者が選ぶのはロールと範囲だけにし、データ 1 件ごとの関係(自分の申請、上位役職者)は開発者が操作の定義に添える規則にします。最初の仮説の 1 は、ここで崩れます。
答えの段階 | 答え | 足りないところ |
|---|---|---|
弱い答え | RBAC にして、要望が来るたびにロールを増やします | 「自部署だけ」を部署の数だけのロールで表すことになる |
よい答え | 操作、ロール、割り当てを分けて持ち、企業ごとにカスタムのロールを作れるようにします | 「自部署だけ」「自分の申請だけ」のような条件を扱えない |
より良い答え | 割り当てに範囲を持たせ、データごとの関係は開発者が書く規則で判定します | なし(中身は下の 6 つ) |
実例:NIST は ABAC を、利用者、データ、操作、環境の属性を規則に当てはめて可否を決める方式と定義しています(NIST SP 800-162)。AWS の規範ガイダンスには、RBAC のロールに ABAC の条件(データがその利用者のテナントに属すること)を組み合わせ、1 つの規則の保存先を全テナントで共有する例があります(AWS 規範ガイダンス)。Auth0 のブログは、マルチテナントの RBAC ではロールをテナントごとに持たせ、同じ人がある企業では管理者、別の企業では閲覧者になれるようにする形を説明しています(Auth0, 2024)。
部署やプロジェクトのような関係がさらに増え、データごとに共有相手が変わる機能(申請を特定の人だけに共有するなど)が出てきたら、ReBAC が次の手になります。Google の Zanzibar は、関係のデータを 1 つのデータモデルで表し、数兆のアクセス制御リストを 95 パーセンタイル 10ms 未満で判定しています(Google, 2019)。範囲つきの RBAC で表せなくなったときの次の手として挙げられると、弱いところとその手当てまで言えます。
判定に要るものが読めないときは、許すのではなく拒否します。他社のデータが見えるより、操作が一時的にできないほうを選びます。
止まるもの | 利用者に見えること | 手当て |
|---|---|---|
権限データのキャッシュ | 少し遅くなる | RDB から読み直す。RDB も読めなければ拒否する |
更新番号の更新 | 権限の変更が反映されない | 更新番号の更新を権限の変更と同じトランザクションに入れ、キャッシュの期限でも 1 分以内に切り替わるようにする |
認可モジュールの規則の誤り | できるはずの操作が拒否される、または許されすぎる | 他社の ID のテストと規則のテストを CI で通してからデプロイし、拒否の急増を監視する |
リポジトリ層の書き忘れ | 変わらない(DB の制限が同じ企業で絞る) | 行レベルセキュリティの対象外の DB ユーザーで流すテストで見つけて直す |
外部の IdP | 新しくログインできない | 認証は変えない前提なので、今の運用のまま |
監視するのは、API ごとの拒否の数、判定にかかる時間、代理ログイン中の操作です。権限の変更履歴は、変更と同じトランザクションで書くので、変更だけが残って履歴が欠けることはありません。
面接の後半では、運用で起きた不具合や将来の要望という形で条件が足されます。答え方は、今の設計でなぜ起きたか、何をきっかけに何をどう処理して直すか、変えずに済むところはどこか、の順です。
例 1:異動した人が、異動のあとも前の部署の申請を承認できていた
例 2:申請を特定の人だけに共有したい(範囲の外にいる他部署の担当者に、この 1 件だけ見せる)
判断 | 選んだ案 | 捨てた案、代わりの案 | 理由 |
|---|---|---|---|
テナントの境界 | 操作中の企業を 1 つに決め、リポジトリ層と DB の 2 か所で絞る | 各クエリの WHERE、リポジトリ層だけ | 1 か所の書き忘れで漏れない |
判定の置き場所 | 入口で操作の宣言を必須にし、認可モジュールに規則を集める | 各 API の if 文、共通の関数を各自で呼ぶ | 新しい API で書き忘れても拒否されるだけで済む |
一覧 | 規則から SQL の条件を作って 1 回で絞る | 1 件ずつ判定する | 1,000 件を 1 秒以内に返し、詳細の判定と食い違わない |
権限モデル | 範囲つきの RBAC と、開発者が書く固定の規則 | RBAC だけ、管理者が書く ABAC | 要望を表せて、IT に詳しくない管理者でも設定できる |
反映 | 企業ごとの更新番号つきのキャッシュ | ログイン時に読んで使い回す | 判定 10ms と 1 分以内の反映を両方満たす |
認可の置き場所 | モノリスの中のモジュール | 代わりの案:Zanzibar 型の別サービス | DB が 1 つで 8 名なので、関係のデータを別に持つ手間が見合わない |
移行 | 新旧の判定を並べて比べ、API ごとに切り替える | 一度に全 API を切り替える | 1 年の間も機能開発を止めない |
つまずき | なぜ弱いか | 抜け出す一手 |
|---|---|---|
面接の最初から権限モデルの話を始める | 他社データの漏えいや確認漏れの事故など、設計を決める条件を取りこぼす | テナントの数、DB の形、今の判定の仕方、反映の速さを先に聞く |
ロールの種類を増やす話だけをする | 「自部署だけ」を部署の数だけのロールで表すことになる | 割り当てに範囲を持たせる |
企業 ID で絞る、とだけ言う | 1 か所の書き忘れで漏れる。前提に事故がすでに 1 件ある | リポジトリ層と DB の 2 か所で絞り、DB の外にも企業 ID を持たせる |
認可を共通化する、とだけ言う | どこで呼ぶかが無く、呼び忘れが残る | 入口で操作の宣言を必須にし、宣言の無い API は拒否する |
一覧も 1 件ずつ判定する | 1,000 件で最大 10 秒かかる | 規則から SQL の条件を作って 1 回で絞る |
画面のボタンを隠して権限を守る | 古い版のモバイルアプリや API の直接の呼び出しは通ってしまう | 判定はサーバーで行い、画面は応答に入れた操作の一覧で出し分ける |
会計事務所のために複数の企業 ID をまとめて扱う | 境界の決め方が緩み、他社の行が混ざる余地ができる | 操作中の企業を 1 リクエストに 1 つだけ決める |
新しい判定に一度に切り替える | 今と同じ操作ができなくなる人が出ても気づけない | 新旧の判定を並べて比べ、食い違いが無くなった API から切り替える |
▼解説を読んだら、同じお題を AI 面接官を相手に通しで解いてみましょう。
海外の技術ブログ、論文、公式の技術文書です。どれも開いて内容を確かめています。Oso と Auth0 の記事は自社製品の紹介を兼ねています。
節 | 記事 | 参照した内容 |
|---|---|---|
4, 6 | Airbnb Builds Himeji - a Scalable Centralized Authorization System(InfoQ, 2021) | 画面側のサービスに置いた確認の重複、データ側への移動、変更の検出によるキャッシュの削除 |
4 | How we built a custom permissions DSL at Figma(Figma, 2024) | 判定が DB の負荷の約 2 割、2 つの API で判定が食い違った、規則とデータの読み込みの分離 |
5 | SaaS Tenant Isolation Strategies: Identity and isolation(AWS, 2020) | 認証で得たテナントの文脈を以降の処理に渡して範囲を決める |
5 | Multi-tenant data isolation with PostgreSQL Row Level Security(AWS, 2020) | 接続ごとのテナント ID で絞る方針、所有者で接続すると適用されない、接続プールの注意 |
5 | Row Security Policies(PostgreSQL) | 方針で除いた行は知らせずに結果から外す、方針の無い表はどの行も見えない、所有者と BYPASSRLS は対象外 |
6 | Authorization Cheat Sheet(OWASP) | 既定で拒否、すべてのリクエストで確かめる、認可のテスト |
6 | List Filtering(Oso) | 1 件ずつではなく 1 回で取り出す、規則から WHERE 句を作る |
7 | Guide to Attribute Based Access Control (ABAC) Definition and Considerations(NIST SP 800-162) | ABAC の定義 |
7 | 例 4: RBAC と ABAC を使用したマルチテナントアクセスコントロール(AWS 規範ガイダンス) | ロールにテナントの条件を組み合わせ、規則の保存先を共有する |
7 | How to Choose the Right Authorization Model for Your Multi-Tenant SaaS Application(Auth0, 2024) | テナントごとのロール、RBAC、ABAC、ReBAC の比べ方 |
事前知識, 7 | Zanzibar: Google's Consistent, Global Authorization System(Google, USENIX ATC 2019) | 関係のデータを 1 つのモデルで表す、数兆のリスト、95 パーセンタイル 10ms 未満 |
▼ほかのお題の解説
公式アカウント
CaseMatch編集部
CaseMatch編集部は、就活・転職における面接対策やキャリア選択に役立つ情報を発信する編集チームです。AI面接練習サービス「CaseMatch」の運営で得た知見や、企業選考・ケース面接・自己分析に関する実践的なノウハウをもとに、候補者が納得感を持って選考に臨めるコンテンツをお届けします。
1分で完了