はじめに
RBAC(Role-Based Access Control)は、ユーザーに直接権限を付与するのではなく、ロールを介して権限を管理するアクセス制御の考え方です。
シンプルに書くと、次の構造です。
図1. RBACの基本構造
[ユーザー] → [ロール] → [権限]
例:
田中さん → support_operator → ticket:read / ticket:update_status
佐藤さん → billing_viewer → billing:read
山田さん → user_role_admin → user_role:update
一見すると、RBACは「ロールを作って権限を割り当てるだけ」に見えます。
ただ、現場で実際に設計してみると、単なる技術設計ではなく、業務理解・組織理解・リスク理解が必要になります。
この記事では、部署の垣根を越えて権限設計に関わった経験をもとに、RBAC設計で特に重要だと感じた次の3つについて整理します。
- 最小権限
- 職務分離
- ロール設計の考え方
きっかけ:CSチームの「管理者権限がないと対応できない」問題
あるプロジェクトで、CSチームから次のような相談を受けました。
顧客からの問い合わせ対応で、契約情報や利用状況を確認したい。
でも今の権限だと見られない項目が多く、結局エンジニアや管理者に確認を依頼している。
一方で、管理者側には別の悩みがありました。
問い合わせ対応のたびに管理者が確認するのは非効率。
ただし、CS全員に管理者権限を付与するのは怖い。
現場の状態を整理すると、こんな構図でした。
図2. 現場で起きていたこと
CS:
必要な情報が見られない
↓ その結果
管理者:
毎回確認依頼が来る
↓ 暫定対応
開発:
個別に権限を追加する
↓ でも
セキュリティ観点:
不要な権限まで広がっていく
最初は「CS向けのロールを作ればよい」と考えていました。
しかし実際に話を聞いてみると、単純に cs_role を作るだけでは解決しないことがわかりました。
CSの中にも、一次対応をする人、エスカレーション対応をする人、チームリーダー、請求関連まで見る人がいます。
さらに、顧客情報の中にも「見てもよい情報」と「マスクすべき情報」があります。
ここで初めて、RBAC設計は画面やAPIの権限制御だけではなく、現場の業務フローを理解するところから始まるのだと実感しました。
RBAC設計でまず整理すべきこと
RBACを設計するとき、いきなりロール名を考えるのは危険です。
先に整理すべきなのは、次の問いです。
- 誰が
- どの業務で
- どのリソースに対して
- どの操作を
- どの範囲まで
- 実行できるべきか
たとえば、「顧客情報を見る」という権限も、分解するとかなり粒度があります。
- 顧客の基本情報を見る
- 契約プランを見る
- 請求情報を見る
- 個人情報を見る
- 利用ログを見る
- 社内メモを見る
- 問い合わせ履歴を見る
さらに、操作も分かれます。
- 閲覧できる
- 作成できる
- 更新できる
- 削除できる
- 承認できる
- エクスポートできる
- 権限を変更できる
この分解をせずにロールを作ると、だいたい次のようなロールが生まれます。
admin
manager
operator
staff
最初は便利ですが、時間が経つとこうなりがちです。
-
operatorなのに請求情報も見られる -
managerなのに削除権限がない -
staffでは足りないのでadminを付ける -
adminが増えすぎて誰が何をできるのかわからない
RBAC設計では、ロール名よりも先に、業務・リソース・操作・範囲を整理することが重要です。
型1:最小権限
最小権限とは、ユーザーやロールに対して、業務上必要な最小限の権限だけを付与する考え方です。
ポイントは、「できるだけ権限を減らす」ではありません。
業務を止めずに、不要な権限を持たせないことです。
悪い例:とりあえず管理者権限を付ける
現場でありがちなのが、次のような対応です。
問い合わせ対応で顧客情報が見られない
↓
一時的に admin 権限を付ける
↓
対応できるようになる
↓
そのまま放置される
短期的には解決します。
ただし、これはリスクが高いです。
管理者権限には、問い合わせ対応に不要な操作が含まれていることが多いからです。
- ユーザー削除
- 権限変更
- 請求設定変更
- データエクスポート
- システム設定変更
CS担当者が顧客情報を確認したいだけなのに、ユーザー削除や権限変更までできてしまうのは、明らかに過剰です。
良い例:業務に必要な操作だけを切り出す
実際の設計では、CS担当者に必要な操作を分解しました。
- 顧客基本情報の閲覧
- 契約プランの閲覧
- 問い合わせ履歴の閲覧
- 問い合わせステータスの更新
- 社内メモの追加
一方で、不要な操作は除外しました。
- 顧客データの削除
- 請求情報の変更
- 権限変更
- 全件エクスポート
- システム設定変更
図3. 最小権限の考え方
悪い例:
support_operator = customer:* / ticket:* / billing:* / user_role:*
良い例:
support_operator =
- customer:read_basic
- contract:read_plan
- ticket:read
- ticket:update_status
- ticket:add_internal_note
ロールとしては、たとえば次のような形です。
role: support_operator
permissions:
- customer:read_basic
- contract:read_plan
- ticket:read
- ticket:update_status
- ticket:add_internal_note
このように、ロールを「部署名」ではなく「業務上必要な操作の集合」として設計すると、最小権限に近づきます。
最小権限の設計ポイント
| 観点 | 確認すること |
|---|---|
| 業務上必要か | その操作がないと業務が止まるか |
| 代替手段はあるか | 承認フローや一時権限で代替できるか |
| 範囲は限定できるか | 全顧客ではなく担当顧客だけでよいか |
| 操作は限定できるか | 更新ではなく閲覧だけでよいか |
| 期間は限定できるか | 常時権限ではなく一時権限でよいか |
特に重要なのは、範囲の限定です。
全顧客を閲覧できる
よりも、
担当顧客のみ閲覧できる
の方が安全です。
全データをエクスポートできる
よりも、
担当範囲のデータだけエクスポートできる
の方が安全です。
RBACだけで範囲制御が難しい場合は、ロールに加えて属性ベースの制御を組み合わせることもあります。
ロール: CS担当者
属性: 担当顧客、所属チーム、担当地域
RBACは強力ですが、すべてをロールだけで表現しようとするとロールが爆発します。
必要に応じて、スコープや属性を組み合わせるのが現実的です。
型2:職務分離
職務分離とは、重要な操作について、申請・承認・実行を同じ人に集中させない考え方です。
たとえば、請求金額の変更や返金処理のような操作では、1人ですべて完結できると不正やミスのリスクが高くなります。
返金を申請する
返金を承認する
返金を実行する
この3つを同じロールに持たせると危険です。
現場であった例:返金対応の権限
別の場面で、返金対応に関する権限設計に関わったことがあります。
最初の要望はシンプルでした。
経理担当者が返金処理できるようにしたい。
しかし、実際に業務を聞いてみると、返金には複数のステップがありました。
- CSが顧客から返金依頼を受ける
- CSが返金申請を作成する
- 経理が内容を確認する
- マネージャーが承認する
- 経理が返金処理を実行する
ここで「経理担当者ロール」にすべての権限を持たせると、次のことができてしまいます。
- 返金申請を作る
- 自分で承認する
- 自分で実行する
これは業務としては便利ですが、内部統制の観点では避けたい状態です。
そこで、ロールを次のように分けました。
role: refund_requester
permissions:
- refund:create_request
- refund:read_own_request
role: refund_reviewer
permissions:
- refund:read_request
- refund:comment_request
role: refund_approver
permissions:
- refund:approve
- refund:reject
role: refund_operator
permissions:
- refund:execute
さらに、ルールとして次のような制約を入れました。
- 自分が作成した返金申請は、自分で承認できない
- 承認されていない返金申請は実行できない
- 一定金額以上はマネージャー承認が必要
図4. 職務分離のイメージ
[CS担当者]
│ 返金申請を作成
▼
[経理担当]
│ 内容確認
▼
[マネージャー]
│ 承認 / 却下
▼
[経理担当]
│ 返金実行
▼
[完了]
RBACだけでは、「自分が作成した申請を自分で承認できない」といった条件を表現しづらい場合があります。
その場合は、ロールによる権限制御に加えて、業務ルールとしてアプリケーション側で制御します。
RBAC:
approve 権限を持っているか
業務ルール:
申請者と承認者が同一人物ではないか
この組み合わせが大切です。
職務分離で特に注意する操作
- お金が動く操作
- 個人情報を扱う操作
- 権限を変更する操作
- データを削除する操作
- 外部にデータを出す操作
- システム全体に影響する設定変更
これらの操作では、1人のロールにすべてを持たせるのではなく、役割を分けます。
| 業務 | 分離したい役割 |
|---|---|
| 返金 | 申請者、承認者、実行者 |
| 権限変更 | 申請者、承認者、設定者 |
| データ削除 | 依頼者、承認者、実行者 |
| 請求変更 | 入力者、確認者、承認者 |
| 本番反映 | 作業者、レビュー担当、承認者 |
職務分離は、現場から見ると「手間が増える」と感じられることもあります。
そのため、ただ制限を増やすのではなく、なぜ分離するのかを説明することが重要です。
誰かを疑うためではなく、ミスや事故からチームを守るために分ける。
この説明をしたことで、現場の納得感がかなり変わりました。
型3:ロール設計の考え方
RBACで一番難しいのは、ロール設計だと思います。
権限を細かくしすぎると管理が大変になります。
逆に大きくしすぎると、過剰権限になります。
悪い例:個人に合わせたロール
現場でよくあるのが、個人ごとにロールを作ってしまうパターンです。
tanaka_special_role
sato_admin_plus
suzuki_read_only_custom
短期的には便利です。
しかし、時間が経つと管理不能になります。
- なぜこのロールがあるのかわからない
- 誰が使っているのかわからない
- 他の人にも使ってよいのかわからない
- 退職・異動後も残り続ける
ロールは個人ではなく、業務上の役割に対して作るべきです。
良い例:業務ロールとして設計する
たとえばCS業務であれば、次のように分けられます。
support_viewersupport_operatorsupport_leadsupport_admin
それぞれの違いは、業務上の責務で説明できます。
| ロール | 想定する役割 | 主な権限 |
|---|---|---|
| support_viewer | 問い合わせ内容を確認する人 | 閲覧のみ |
| support_operator | 一次対応を行う人 | 問い合わせ更新、社内メモ追加 |
| support_lead | エスカレーション対応する人 | 担当者変更、重要対応の承認 |
| support_admin | CS設定を管理する人 | テンプレート管理、カテゴリ設定 |
このようにすると、ロールの意味が説明しやすくなります。
この人はなぜ support_lead なのか?
→ エスカレーション判断と担当者変更を行うため
説明できるロールは、棚卸しもしやすいです。
ロール名の付け方
ロール名は意外と重要です。
個人的には、次のような形式が扱いやすいと感じています。
{domain}_{responsibility}_{level}
例:
support_ticket_operator
support_ticket_lead
billing_invoice_viewer
billing_refund_approver
admin_user_manager
ロール名から、次の情報が読み取れるようにします。
- どの領域のロールか
- 何を担当するロールか
- どのレベルの権限か
避けたいロール名は、意味が曖昧なものです。
general
normal
member
staff
power_user
super_user
special
特に power_user や special は、後から見たときに何ができるロールなのかわかりづらくなります。
ロール爆発を防ぐ
RBAC設計では、ロールが増えすぎる問題にも注意が必要です。
たとえば、部署・役職・地域・担当サービスをすべてロール名に入れると、すぐに増えます。
tokyo_support_operator
osaka_support_operator
fukuoka_support_operator
tokyo_support_lead
osaka_support_lead
fukuoka_support_lead
さらにサービス単位まで入れると、もっと増えます。
tokyo_service_a_support_operator
tokyo_service_b_support_operator
osaka_service_a_support_operator
osaka_service_b_support_operator
こうした場合は、ロールとスコープを分けて考えます。
図5. ロールとスコープを分ける考え方
ロール = 何ができるか
スコープ = どこまでできるか
例:
role : support_operator
scope : region=tokyo, service=service_a
この考え方にすると、ロールの数を抑えつつ、権限範囲を柔軟に制御できます。
role: support_operator
permissions:
- ticket:read
- ticket:update_status
scope:
region: tokyo
service: service_a
実際に使った整理フォーマット
権限設計を進めるとき、私は次のような表で整理しました。
| 業務 | 対象リソース | 操作 | 必要な人 | 条件 | ロール候補 |
|---|---|---|---|---|---|
| 問い合わせ確認 | ticket | read | CS担当者 | 担当チケットのみ | support_operator |
| 問い合わせ更新 | ticket | update | CS担当者 | 担当チケットのみ | support_operator |
| 顧客基本情報確認 | customer | read_basic | CS担当者 | 担当顧客のみ | support_operator |
| 請求情報確認 | billing | read | 経理、CSリード | 必要時のみ | billing_viewer |
| 返金申請 | refund | create_request | CS担当者 | 顧客対応時 | refund_requester |
| 返金承認 | refund | approve | マネージャー | 自分の申請は不可 | refund_approver |
| 返金実行 | refund | execute | 経理 | 承認済みのみ | refund_operator |
| 権限変更 | user_role | update | 管理者 | 申請・承認後 | user_role_admin |
この表を作ると、会話がかなりスムーズになります。
エンジニアだけで考えると、どうしてもAPIや画面単位で考えがちです。
しかし、CSや経理の方と一緒にこの表を埋めると、実際の業務フローに沿った権限設計になります。
まさに、部署を越境して初めて見える情報がありました。
RBAC設計の進め方
現場で使いやすかった進め方は、次の流れです。
1. 業務フローを聞く
まず、誰が何をしているのかを聞きます。
- 問い合わせは誰が受けるのか
- どの情報を確認するのか
- どのタイミングで更新するのか
- 誰にエスカレーションするのか
- 承認が必要な操作はあるか
この段階では、まだロール名を決めません。
2. リソースと操作に分解する
次に、業務をリソースと操作に分解します。
customer:read_basic
customer:read_sensitive
ticket:update
refund:create_request
refund:approve
user_role:update
ここで粒度を決めます。
粒度が粗すぎると過剰権限になります。
粒度が細かすぎると管理が大変になります。
3. 最小権限でロール候補を作る
業務に必要な操作だけをまとめて、ロール候補を作ります。
support_operator
refund_requester
refund_approver
billing_viewer
このとき、「念のため付ける」は避けます。
- 必要になったら追加する
- 不要になったら外す
この姿勢が大切です。
4. 職務分離の観点で見直す
次に、危険な組み合わせがないかを確認します。
- 申請と承認を同じ人ができないか
- 承認と実行を同じ人ができないか
- 権限変更を自分で完結できないか
- 削除と監査ログ削除を同じ人ができないか
必要であれば、ロールを分けます。
5. 棚卸ししやすい名前にする
最後に、ロール名と説明を整えます。
ロールには説明文を付けるとよいです。
support_operator:
description: CS一次対応者向け。担当チケットの閲覧・更新、顧客基本情報の閲覧が可能。
説明が書けないロールは、役割が曖昧な可能性があります。
設計時に意識しているチェックリスト
RBAC設計では、最終的に次のチェックをしています。
- そのロールは業務上の役割として説明できるか
- 個人名や例外対応のためだけのロールになっていないか
- 不要な更新・削除・エクスポート権限が含まれていないか
- 申請・承認・実行が同じ人に集中していないか
- 退職・異動時に外すべきロールがわかるか
- ロール数が増えすぎていないか
- 権限変更の履歴を追えるか
- 定期的に棚卸しできるか
特に、次の3つは毎回確認します。
- なぜ必要か
- 誰に必要か
- いつまで必要か
この3つに答えられない権限は、見直し対象です。
越境して学んだこと
今回の経験で一番学んだのは、RBAC設計はエンジニアだけでは完結しないということです。
エンジニアだけで考えると、どうしても次のような観点に寄りがちです。
- APIをどう制御するか
- DB上の権限をどう持たせるか
- 画面表示をどう切り替えるか
もちろん、それらは重要です。
しかし、現場の人が本当に困っていることは、コードだけを見てもわかりません。
- なぜその情報が必要なのか
- どのタイミングで必要なのか
- 誰が判断しているのか
- どこからがリスクなのか
- 何を制限すると業務が止まるのか
これらは、CS、経理、管理者、セキュリティ担当など、普段あまり関わらない人たちに話を聞いて初めて見えてきました。
部署の垣根を越えて話を聞くことで、単に「権限を絞る」のではなく、安全に業務を進めるための設計に近づけたと思います。
まとめ
RBAC設計では、次の3つの型が重要です。
1. 最小権限
業務に必要な最小限の権限だけを付与する。
とりあえず admin を付ける
ではなく、
必要なリソースと操作だけを付与する
を意識します。
2. 職務分離
重要な操作では、申請・承認・実行を分ける。
1人ですべて完結できる状態
を避け、
ミスや不正が起きにくい業務フロー
を設計します。
3. ロール設計
ロールは個人ではなく、業務上の役割に対して作る。
tanaka_special_role
ではなく、
support_operator
refund_approver
billing_viewer
のように、役割として説明できるロールにします。
おわりに
RBAC設計は、境界を引く作業のように見えます。
- 誰が何をできるか
- どこから先はできないか
- どの操作には承認が必要か
ただ、現場で感じたのは、RBACは単に人を制限するためのものではないということです。
むしろ、適切に設計された権限は、チームが安心して業務を進めるための土台になります。
そして、その設計には越境が必要です。
- エンジニアがCSの業務を聞く
- CSがセキュリティリスクを理解する
- 経理がシステム上の制約を知る
- 管理者が現場の困りごとを知る
そうやって部署や役割の境界を越えて話すことで、初めて「使いやすくて安全な権限設計」に近づけるのだと思います。
RBAC設計で迷ったときは、まずロール名を考えるのではなく、現場に聞いてみる。
その権限は、誰が、何のために、いつ必要なのか?
この問いから始めることが、よいRBAC設計の第一歩だと思います。