Railsにおいてユーザがプラットフォーム(多対多)となるシステムを作るときの権限モデルを設計
概要
Ruby on Rails における複雑な認可の設計と実装するための一例を紹介する。
背景
手元で作っている Rails の B2B サービスの権限に関連する要件が複雑化してきたので、権限モデルをちょっと整理する。
権限が複雑になる原因は、アクターや操作対象といった権限に関するメトリックが多くなること。要件レベルでどれだけメトリックを減らせるかが重要。
ビジネスで利用するサービスの場合、細かい権限設定が要求されるのでメトリックが増えやすい。
今回扱わなければいけないメトリックは以下
- アクター種別
- ロール種別
- ステータス遷移
- Web or API による操作
問題
メトリックが 3 つ以上になった時点で直交表が作成できなくなってしまうため、権限表を作るのが難しくなる。
- メトリックが 3 つであれば、直交表を複数作ればギリギリ対応できる
- 4 つになると表現が厳しい。そもそも理解、暗記、比較も困難。
例えば、Web から操作できる内容と API からできる操作を同様にすることによってメトリックを 1 つ減らせる。
この権限に関する問題は、システム上で表現は可能だしテストケースも作成して担保できる。しかしながら、人間が理解する時や説明するときに困難。
また、細かい要件定義を繰り返してミクロな議論によって実装要件を決めていくといつの間にか複雑に陥っているケースが多い。技術的負債とはまさにこのことである。
理想
あるべき論は 以下のスライドに書いてあるとおりと考える。

しかしながら既存のワークフローを DX してリプレースをかける場合はすでに複雑な要件が決まっていたりするので要件を単純化する余地が少なかったりもする。
どの程度の複雑性になったら複雑と呼べるのか、複雑さを表現するための評価軸を持っておく必要がある。
アプローチ
クリーンアーキテクチャのレイヤと比較して、このような感じで考える。これ以上メトリックが増える場合は、独自にビジネスロジックのレイヤーを追加するなりして対応する必要がある。
背景にあるメトリックを管理するために、Rails にて利用したミドルウェアとスタックを図にまとめた。

- AASM によるステータス遷移
- ロールごとに pundit で管理
- API 用、アクターごとに設定を用意する
このように図に整理するとどうやって権限を整理するときれいにできるかが見えてくる。 pundit の設定ファイルごとにまとめることによって権限はきれいに表現できそうということがわかる。
まとめ
Rails のシステムにおいて認可をまとめるには以下のようにまとめるのが良さそう。
- AASM ではビジネスロジックのステータス遷移についてまとめる
- アクターやアクセスする手段ごとに pundit を用意して pundit の設定ファイルごとに権限表を作成