1 分

マルチテナントSaaSの権限:組織・チーム・ロールをわかりやすく

マルチテナントSaaSの権限を、組織・チーム・ロール・所有権のルールをわかりやすく説明。チェックリストとスケールする実例つきで、安全に運用できる設計を紹介します。

マルチテナントSaaSの権限:組織・チーム・ロールをわかりやすく

なぜSaaSの権限はすぐにややこしくなるのか

権限の問題はたいてい小さな面倒ごとから始まります。チケットが来る:「私は管理者なのに請求書が見られません」。別のチケット:「なぜ同僚が設定を編集できるの?」 人はクリックして探し、推測し、時にはアクセスの整理より速いので「オーナー」ログインを共有してしまいます。

すると応急処置が積み重なります。チームは「Admin 2」や「Manager (no delete)」のような役割を作ります。エンジニアは「もしユーザーがSalesに入っていたらエクスポートを許可する」など、その場しのぎのチェックを追加します。1か月後、どのルールが意図されたものか、どれが事故なのか誰にもわからなくなります。

顧客が増えるとさらに悪化します。1社では問題にならなかったルール(「管理者はすべてのデータを見られる」)が、何百もの組織で破綻します。ある顧客は部署間を厳密に分離したい。別の顧客は共有ワークスペースを望む。契約社員はあるプロジェクトだけ見たい。モデルが明確でないと、新しい顧客ごとに例外を作ることになります。

目標は単純です:1分で説明できる予測可能なアクセスルール。例えば:「組織がデータを所有する。チームは人をまとめる。ロールは操作を定義する。リソースは組織、時にチームに属する。共有はいくつかのデフォルトに従う。」これを明瞭に言えなければ、作るのもテストするのも変更するのも難しくなります。

守るべき約束は、ロールを減らし、所有権を明確にし、安全なデフォルトにすることです。実際の職務に結びついた小さなロールセットから始め、すべてのリソースに対して所有者を明示し、最小権限をデフォルトにします。共有は意図的に、事故ではなく許可していくべきです。

平易な地図:組織、チーム、ユーザー、リソース

アプリが複数の顧客にサービスを提供するなら、ルールを書く前にメンタルマップを正しく持ちましょう。マルチテナントSaaSの混乱の多くは、同じ用語が製品の別の場所で異なる意味になってしまうことから生じます。

テナント境界の意味を一つに決め、それを守ってください。多くのプロダクトは「組織」をテナントとし、すべてのデータは組織内にあり、明示的な共有を作らない限り越境しない、という設計を取ります。

成長してもブレないシンプルな語彙:

  • 組織(テナント):顧客アカウントで、データの境界。
  • ユーザー(アイデンティティ):1つのログインを持つ人。
  • メンバーシップ:ユーザーが組織に属することを示す紐付けとそのロール。
  • チーム(任意):組織内の作業単位。日常業務のグループ化に使う。
  • リソース:保護が必要なもの(プロジェクト、請求書、チケット、APIキー)。

「一人が複数の組織に属する」のは普通です。コンサルタントは3つの顧客組織に所属し、それぞれ別のロールを持つかもしれません。だから「ユーザー」と「メンバーシップ」は分けて考え、チェックは通常メンバーシップに依存します。

チームは「サポート」や「経理」のように現実のまとまりを反映すると有益です。チームが2つ目の権限システムになるとノイズになります。テストは簡単です:チームを一文で説明できるか、それが特定の機能ルールに依存していないかを確認してください。

例:Mariaは一度ログインし、Org AとOrg Bを切り替えます。Org AではFinanceにいて請求書を表示でき、Org BではViewerでプロジェクトを閲覧のみできます。同じユーザーでもメンバーシップが違えば権限は明確です。

ロール、権限、スコープを専門用語なしで分ける

マルチテナントSaaSの権限は、次の3つを分けるとわかりやすくなります:

  • ロール:責任を示すラベル。
  • 権限(パーミッション):実際にできること。
  • スコープ:どこでそれができるか。

平易な言葉でのRBAC

RBAC(ロールベースのアクセス制御)は、ユーザーにロールを与え、そのロールが許可されたアクションを与える仕組みです。ロール名は状態ではなく責任を表すべきです。「Billing Admin」は明確ですが「Power User」は議論が起きがちです。

権限は動詞として扱い、一貫性を保ちます:

  • 表示(読み取り)
  • 作成
  • 編集
  • 削除
  • 管理(招待、設定、エクスポートなど特別な操作)

同じ動詞を異なる場所で使えるようにスコープを加えます。これで似たようなロールを20個作るのを避けられます。

よく使われる読みやすいスコープ例:

  • 組織全体(Org-wide)
  • チームのみ(Team-only)
  • 自分のアイテム(Own items)
  • 割り当てられたもの(Assigned)

スコープで解決できる場合にロールを増やさない

「Project Editor」と「Project Editor (Own)」のようなロールが増えるとしたら、それはたいていスコープの問題です。

例:CRMでは「Sales Rep」に案件の作成・編集を許可するが、スコープを「own items」に制限します。「Sales Manager」は同じ動詞を持ちながら「team-only」や「org-wide」のスコープを持たせます。そうすればロールは少なく、ルールは明確になります。

良いデフォルトは:ロールは動詞を与え、所有権(または割り当て)がどこでそれが作用するかを制限する、です。

数百の組織にスケールするシンプルなルールセット

1つの顧客では動くモデルが10だと壊れるなら、「誰が見られるか」と「誰ができるか」と「誰が所有するか」を混ぜてしまっている可能性があります。これらを分ければシステムは予測可能になります。

スケールするルール例:

  • すべてのレコード(プロジェクト、請求書、チケット、APIキー)は正確に1つの所属組織を持つ。
  • ユーザーは自分がアクティブメンバーである組織のデータしか見られない。メンバーでない組織はUIもAPIも存在しないかのように振る舞うべき。
  • ロールはアクション(作成、編集、削除、エクスポート)を制御するが、ユーザーがすでに見られる組織内でのみ作用する。
  • 所有権はタイブレーカー(優先権)として働く。許可されたスコープ内で追加権限を与える(自分の下書きを編集する、自己のAPIトークンを管理する)一方で、他のデータへのアクセスを拡大しない。
  • 管理者アクセスは狭く明示的な例外とする。"admin"ができることを定義し、管理者ロールは少数にする。

例:SamはOrg AとOrg Bに所属。Org AではMemberで自分のレポートを作成・編集できるが請求は触れない。Org BではBilling Managerで支払い方法を更新し請求書をダウンロードできるが、メンバーシップにその領域が含まれていない限りプライベートプロジェクトは見られない。

こうすると成長が「つまらない」ほど楽になります。新しい組織を追加するのはメンバーシップとロールを追加するだけで、コアルールは変わりません。

ステップバイステップ:1ページで権限モデルを設計する

チームメイトが2分で読める1ページを書いてください。コードを開かずに説明できるなら良い状態です。

1) ルールの前に入力を決める

部品は意図的に小さく保ちます:

  • オーナー、管理者、メンバー、ビューアーの4つのユーザータイプを選ぶ。
  • 日常的に触るリソースを3~6個リストする(プロジェクト、顧客、レポート、請求など)。
  • 各リソースに対して2~4のアクションを列挙する(表示、作成、編集、削除、招待、エクスポート)。
  • 新規メンバーにデフォルトで何を与えるか決める(通常はviewerかmember、adminは不可)。
  • 「チーム」が何を変えるかを決める。可視性、割り当て、レポーティングに留め、驚きの権限は与えない。

2) ルールを単純な表にする

スコープを使えばロールの爆発を避けられます。多くのプロダクトは3つのスコープで足ります:own、team、org。

RoleViewEditInvite usersBillingScope note
OwnerYesYesYesYesOrg-wide, can transfer ownership
AdminYesYesYesNo/YesOrg-wide, no ownership changes
MemberYesLimitedNoNoOwn + team (where assigned)
ViewerYesNoNoNoRead-only in assigned scope

健康診断:このページを非技術の同僚に見せて「SupportメンバーはSalesのレポートを編集できるか?」と聞いてみてください。ためらうなら、スコープかチーム定義が不明瞭です。

理にかなったリソースの所有権と共有ルール

権限を理解しやすくするため、まず各リソースの所有者を決め、共有オプションは限定してください。

デフォルトの所有モデル

多くのリソースは組織所有にします。顧客は会社単位で考えることが多く、請求書、プロジェクト、連絡先、チケット、自動化は組織に属すると期待します。

チームは有用ですが、ワークフローのラベル(ルーティングや可視性のデフォルト)として扱い、重要なセキュリティロジックにしないでください。チームタグはフィルタ、ダッシュボード、通知、キューに使えますが、アクセスはロールとスコープから来るべきです。

ユーザー所有のリソースは例外にし、真に個人的なもの(下書き、プライベートノート、保存ビュー、APIトークン、個人設定)に限定します。ユーザーが離れたときの扱いを決めておきましょう:削除、移譲、保持のいずれか。

読みやすさを保つ小さな共有ルール:

  • デフォルトは組織所有:項目は1つのorganization_idの下に保存する。
  • ワークフロー用にチームタグ付け:ルーティング用にチームをタグ付けするが、強固なアクセス制御には使わない。
  • 個人所有は個人的項目のみ:明示的に共有されない限りプライベート。
  • 共有レベルは限定:Private(所有者)、Team、Org。初期段階では項目ごとのカスタムACLは避ける。
  • 「割り当て」と「アクセス」を分離:割り当ては責任であり、権限ではない。

シンプルに保てる共有

「アクセスが必要だ」と言われたら、それが個人のプライベートかチームか組織全体かを詰めてください。それが3つのどれにも当てはまらないなら、スコープが不明瞭なサインです。

例:サポートチケットは組織所有(マネージャーが全チケットを集計できる)、Supportにチームタグ付け(適切なキューに表示)、Jordanに割り当て(責任者)。割り当ては他の許可されたロールの閲覧をブロックしてはいけません。

招待、メンバー変更、組織切替の扱い

権限はしばしば「人が関わるイベント」で破綻します:招待、チーム移動、アクセス削除。これらのフローがモデルを予測可能に保てるかを決めます。

招待

招待はメンバーシップ作成のリクエストと扱い、招待自体が即時アクセスを与えるものではありません。招待は、承認時に付与される組織、チーム(任意)、ロールを明示すべきです。

ルールを厳しく:

  • 招待できるのは特定のロールだけ(例:OwnerとAdmin)。チームリードを許す場合は自分のチームに招待を限定する。
  • 招待者は自分と同等かそれ以下のロールしか付与できない。
  • 有効期限切れの招待は無効。
  • 招待先のメールが既にアカウントを持っていれば、承認で組織に紐付く。持っていなければ、承認でアカウント作成→組織紐付けする。

一時的なアクセスはここで扱えます。"temp user"ロールを作る代わりに、ロール付与に終了日を設定し、期限が来たら自動でアクセスを落とすとよいです。

退出と所有権の扱い

誰かが組織を離れるとき、資源を勝手に処理しないでください。ルールが「リソースは組織所有」であれば、それを守ります。作成者は履歴として残しても組織が所有者です。

ユーザー所有のリソースがあるなら、削除前に移譲を要求する(プロジェクト、ドキュメント、APIキーなど重要なもの)。

安全な組織切替

1つのログインが複数の組織に属しても、アプリは常に「現在の組織」を持つべきです。UIで明確に示し、すべての操作をそれにスコープします。

非アクティブ化は削除より優れます。今すぐアクセスを外しつつ、過去の操作は監査できる状態を保ちます。

避けるべきよくあるミスと罠

多くの権限モデルはルールより速く成長するため失敗します。基本(テナント境界、所有、スコープ)を守り、その他は詳細として扱ってください。

ロールの爆発は典型的な罠です。エッジケースが現れ新しいロールを作ると、数か月後に「Manager Plus」が何を意味するかわからなくなります。頻繁に必要なら第一級の権限にし、稀なら期限付きの一時付与で対応しましょう。

**権限の乖離(permission drift)**は静かに進みます。「ちょっと例外を追加」してモデルを更新し忘れると、1年後にドキュメントと実システムが一致しません。まずモデルを更新してから実装してください。

チームを偽のセキュリティ境界にすると常に混乱します。リソースが組織内でチームを越えて共有できるなら明確に伝える。できないならコードで強制し、名前で誤解させないでください。

早めに見つけるべきレッドフラッグ:

  • デフォルトで全顧客組織のデータを見られる"super admin"
  • UIだけの保護(ボタンを隠す)でサーバー側チェックがない
  • メンバーシップルールを無視するAPIキーやサービスアカウント
  • 役職名で定義されたロール(動作で定義しない)
  • 一文で説明できない例外

サポートが助けるために「グローバル管理者を1分だけ付与する」はテナント分離の漏洩につながります。代わりに、明示的でログ済みのアクセス(特定組織、時間枠、操作)を好みます。

リリース前のクイックチェック

各リクエストはまずアクティブな組織コンテキストを解決し(サブドメイン、ヘッダ、セッション、ルートから)、一致しないものは拒否してください。

組織コンテキストの後は一貫した順序でチェックします:メンバーシップ(この組織にいるか?)、ロール(ここで何が許可されるか?)、所有権や共有(このレコードにアクセス権があるか?)。所有権を先にチェックすると、その存在を漏らす可能性があります。

エンドツーエンドの小さなテストセットを実際のアカウントで回してください(単なるユニットテストではなく):

  • 新規メンバーが表示、作成、エクスポートを試す
  • チームリードが自チームだけを管理できるか試す
  • 組織管理者がロール変更後に機密操作(削除、エクスポート)を試す
  • 削除されたユーザーが開いた古いタブで再試行する
  • 招待済み(未承認)ユーザーが古い招待を使ってアクセスを試みる

ロール変更、メンバー削除、エクスポート、削除、設定更新など、権限を変える・データを動かす操作には基本的な監査イベントを追加してください。完璧である必要はありませんが、「誰が何をいつしたか」に答えられる必要があります。

デフォルトを見直すこと。新規組織や新規メンバーは成功に最低限必要なアクセスから始めるべきです。サポートや営業向けの内部FAQも役立ちます(例:「チームリードは他チームを見られるか?」「削除後のアクセスはどうなる?」など)。

例:1つの組織から200まで再設計せずに広げる

まずは小さな実例で始めてください:1社(1組織)に2つのチーム、SalesとOps。全員一度サインインして自分の属する組織を選ぶ。Salesは顧客情報と見積が必要、Opsは請求と内部設定が必要。

ステージ1:1組織、2チーム

チームはグルーピングとワークフローに留め、主な権限のスイッチにしないでください。デフォルトやルーティングには使えますが、唯一のゲートにしない。

ステージ2:安定したロール、予測可能なスコープ

Admin、Member、Viewerなど少数のロールを選び、機能追加後も安定させます。ロールは「この組織で何ができるか」を答え、スコープは「どこでそれができるか」を答えます。

ステージ3:所有権で編集判断が簡単に

1つの所有ルールを追加:各リソースは組織と所有者(多くは作成者)を持つ。編集はAdminであれば可、または所有者でかつロールが「edit own」を含む場合に可。閲覧はそのリソースタイプに対してロールが「view」を含めば可。

例:Sales Memberが見積を作成。別のSales Memberは閲覧はできるが、チーム共有や再割り当てが無ければ編集はできない。Ops Viewerはルールが許せばSalesリソースを見られる。

ステージ4:200の組織、同じルール

200の顧客組織をオンボードしても、同じロールと所有ルールを再利用します。変更するのはメンバーシップだけでモデルはそのまま。

サポートの要望「Xにアクセス付与できますか?」はチェックリストになります:組織とリソースを確認、ユーザーのその組織でのロールを確認、所有権と共有を確認、ロール変更か共有を行う。ワンオフの例外は避け、監査ノートを残してください。

次のステップ:実装、テスト、そして安全に改善

1ページのモデルを契約として扱ってください。すべてのAPI呼び出しとUI画面で強制できるルールだけを実装しなければ、権限は「場合による」に堕ちます。

小さく始める:少数のロール、明確なスコープ、単純な所有権。新しい要求が来たら(「Editor-Managerを追加できますか?」)、まず所有権やスコープで解決できないか検討してください。新しいロールは稀にするべきです。

新しいリソースを追加するたびに基本を一貫させる:

  • org_id を保存する(チーム適用なら team_id も)
  • 可視性ルールを持つ(private、team、org)
  • 機密操作(招待、ロール変更、エクスポート)で監査イベントを記録する
  • クエリごとにスコープでフィルタする(UIだけでなく)
  • 作成直後に誰が見られるかの予測可能なデフォルトを持つ

エッジケースを磨く前に実際のフロー(招待、組織切替、管理画面、アクセス喪失中の挙動)をテストしてください。

チャットベースのアプリビルダーで作る場合、権限モデルを平易な言葉で先に書き、製品仕様と並べて置くと便利です。Koder.ai (koder.ai) の Planning Mode やスナップショット、ロールバックは、これらのシナリオを試してルールがウェブ、バックエンド、モバイルで一貫することを確認する実践的な方法です。

よくある質問

マルチテナントSaaSアプリにおける組織とは何ですか?

組織とは、顧客アカウントであり、そのデータに対する明確な境界です。保護対象のレコードはすべて1つの組織に属するようにし、表示や変更の前にメンバーシップを確認します。

ユーザーとメンバーシップを分けるべき理由は何ですか?

ユーザーは、1つのログインを持つ1人の人物です。メンバーシップには、その人が特定の組織内で担う役割が記録されます。そのため、同じ人物でも顧客アカウントごとに異なるアクセス権を持てます。

チームはいつ作成すべきですか?

組織内の日常的なグループ分け、振り分け、レポート作成にはチームを使います。チームが説明のつかない第2の権限システムにならないようにしてください。

ロール、権限、スコープの違いは何ですか?

ロールは責任を表し、権限は実行できる操作を表し、スコープはそれらの操作を適用できる範囲を制限します。たとえば、営業担当者は自分が所有する商談を編集でき、マネージャーはチームの商談を編集できます。

SaaSプロダクトは最初にいくつのロールを用意すべきですか?

まずは、オーナー、管理者、メンバー、閲覧者といった少数のロールから始めます。新しいロールを増やす前に、自分、チーム、組織といったスコープを追加してください。

アプリ内のリソースは誰が所有すべきですか?

プロジェクト、請求書、チケット、連絡先を含む大半の業務レコードは、組織所有にします。下書き、保存済みビュー、APIトークンなど、本当に個人的な項目だけをユーザー所有にしてください。

リソース共有はどのように機能させるべきですか?

共有レベルは、非公開、チーム、組織のようにシンプルに保ちます。割り当ては業務の責任を示すものとして扱い、関連するすべてのレコードを表示または編集する自動的な権限にはしないでください。

誰かを招待したとき、何が起こるべきですか?

組織、ロール、任意のチームを明記した招待を、招待された人が承諾した後にのみアクセスを作成します。招待する側が付与できるのは、自身と同等以下のロールだけにし、未使用の招待は期限切れにします。

誰かが組織を離れたとき、何が起こりますか?

その人の過去の操作は監査履歴に残したまま、メンバーシップを直ちに削除または無効化します。誰に渡すべきかを推測するのではなく、削除前に機密性の高いユーザー所有項目を移管してください。

すべての権限リクエストで、どのような確認を行うべきですか?

最初に現在の組織を特定し、次にメンバーシップ、ロール、最後に所有権または共有設定を確認します。インターフェースだけでなく、すべてのAPIリクエストで同じ順序を強制してください。

Related posts