Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
「技術負債にならない・間違えない」 権限管理の設計と実装
Search
naro143
September 27, 2025
Technology
1
220
「技術負債にならない・間違えない」 権限管理の設計と実装
Kaigi on Rails 2025 Day2
https://kaigionrails.org/2025/talks/naro143/#day2
naro143
September 27, 2025
Tweet
Share
More Decks by naro143
See All by naro143
Bulletproof Reactで始める!ESLintで強化する! 効果的なプロダクト開発
naro143
0
550
Other Decks in Technology
See All in Technology
QuasiなCyclicを笑いながらハミング
mitsu1119
0
170
2025/09/16 仕様駆動開発とAI-DLCが導くAI駆動開発の新フェーズ
masahiro_okamura
0
330
Создание мультиагентной системы на базе AI Studio
shwars
0
150
RevOps実践で学んだ俺が最強のデータ基盤になることの重要性 / revops-practice-learned
pei0804
1
720
C# 14 / .NET 10 の新機能 (RC 1 時点)
nenonaninu
0
110
2重リクエスト完全攻略HANDBOOK / Double Request Handbook
shoheimitani
0
530
今改めてServiceクラスについて考える 〜あるRails開発者の10年〜
joker1007
1
1.2k
kaigi_on_rails_2025_設計.pdf
nay3
3
850
エンジニアがデザインまで担うための AI駆動UIデザイン/フロントエンド開発実践
kitami
4
790
High performance GIF playback/iOSDC25
noppefoxwolf
1
120
App Clip 5年史: 萌動と停滞のクロニクル
judau
0
120
Rust In Python
lycorptech_jp
PRO
3
310
Featured
See All Featured
Being A Developer After 40
akosma
90
590k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
Reflections from 52 weeks, 52 projects
jeffersonlam
352
21k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
870
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Into the Great Unknown - MozCon
thekraken
40
2k
The Power of CSS Pseudo Elements
geoffreycrofte
78
6k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Why Our Code Smells
bkeepers
PRO
339
57k
For a Future-Friendly Web
brad_frost
180
9.9k
Transcript
「技術負債にならない‧間違えない」 権限管理の設計と実装 Kaigi on Rails 2025 @naro143(Yusuke Ishimi)
Yusuke Ishimi 2 株式会社プレックス テックリード @naro143 @naro143
持ち帰っていただきたいこと • 権限管理の重要性とアンチパターンの理解 • 権限管理の要素を適切に分割することで技術負債と間違いが減らせる • 具体的な実装例(今後の議論のきっかけになれば幸いです) 3
⽬次 • 権限管理の重要性 • よくある実装とアンチパターンと対処法 • 権限管理の要素の整理(Punditを例に) • 要素を適切に分割したModuleの実装の解説 •
改善後の事業とサービスへの影響 4 ModuleのサンプルはGitHubで公開しています
権限管理 5
権限管理の例 • 運営アカウントだけ特殊なボタンが表⽰される • 管理者アカウントだけメンバーを招待できる • 追加プランの契約ユーザーだけ機能が増える 業務⽀援SaaSだと... • 管理者アカウントだけお⾦の情報(契約⾦額や給与)が⾒れる
• 外部アカウント(業務委託)は担当のプロジェクトの情報だけ⾒れる(取引先は⾒れ ない) 6
権限管理の例 • 運営アカウントだけ特殊なボタンが表⽰される • 管理者アカウントだけメンバーを招待できる • 追加プランの契約ユーザーだけ機能が増える 業務⽀援SaaSだと... • 管理者アカウントだけお⾦の情報(契約⾦額や給与)が⾒れる
• 外部アカウント(業務委託)は担当のプロジェクトの情報だけ⾒れる 7 権限管理のミス
権限管理の例 • 運営アカウントだけ特殊なボタンが表⽰される • 管理者アカウントだけメンバーを招待できる • 追加プランの契約ユーザーだけ機能が増える 業務⽀援SaaSだと... • 管理者アカウントだけお⾦の情報(契約⾦額や給与)が⾒れる
• 外部アカウント(業務委託)は担当のプロジェクトの情報だけ⾒れる 8 給与を公開しちゃった 取引先を公開しちゃった
権限管理の例 • 運営アカウントだけ特殊なボタンが表⽰される • 管理者アカウントだけメンバーを招待できる • 追加プランの契約ユーザーだけ機能が増える 業務⽀援SaaSだと... • 管理者アカウントだけお⾦の情報(契約⾦額や給与)が⾒れる
• 外部アカウント(業務委託)は担当のプロジェクトの情報だけ⾒れる 9 サービスへの信頼が下がる 事業への損失が⼤きい
権限管理の例 • 運営アカウントだけ特殊なボタンが表⽰される • 管理者アカウントだけメンバーを招待できる • 追加プランの契約ユーザーだけ機能が増える 業務⽀援SaaSだと... • 管理者アカウントだけお⾦の情報(契約⾦額や給与)が⾒れる
• 外部アカウント(業務委託)は担当のプロジェクトの情報だけ⾒れる 10 権限管理のミスは許されない
レビューする気持ちで⾒てください 11
よくある実装① 12
よくある実装② 13
よくある実装③ 14
よくある実装③ 15 なんだよ super_admin って...
よくある実装③ 16 そもそも admin? の判定は アンチパターン
役割は変わり⾏く 17
事業やサービスの変化 事業 • ターゲットとする市場(業種)の変化 • ターゲットとする企業規模の変化 • ターゲットとするユーザーの変化 サービス •
提供する機能の変化 18
事業やサービスの変化 事業 • ターゲットとする市場(業種)の変化 • ターゲットとする企業規模の変化 • ターゲットとするユーザーの変化 サービス •
提供する機能の変化 19 建設業と運送業の 管理者は同じ業務と責務?
事業やサービスの変化 事業 • ターゲットとする市場(業種)の変化 • ターゲットとする企業規模の変化 • ターゲットとするユーザーの変化 サービス •
提供する機能の変化 20 10名と100名の企業の 管理者は同じ業務と責務?
事業やサービスの変化 事業 • ターゲットとする市場(業種)の変化 • ターゲットとする企業規模の変化 • ターゲットとするユーザーの変化 サービス •
提供する機能の変化 21 同じ admin?
事業やサービスの変化 事業 • ターゲットとする市場(業種)の変化 • ターゲットとする企業規模の変化 • ターゲットとするユーザーの変化 サービス •
提供する機能の変化 22 役割に依存した判定は アンチパターン
事業やサービスの変化 事業 • ターゲットとする市場(業種)の変化 • ターゲットとする企業規模の変化 • ターゲットとするユーザーの変化 サービス •
提供する機能の変化 23 役割の種類も 提供する機能も 増えていく
事業やサービスの変化 事業 • ターゲットとする市場(業種)の変化 • ターゲットとする企業規模の変化 • ターゲットとするユーザーの変化 サービス •
提供する機能の変化 24 だから、権限管理は複雑になる いつか、技術負債になる
リファクタリング 25
よくある実装① 26
よくある実装① 27 プロジェクトを作成できるのか?
よくある実装① 28 プロジェクトを作成できるのか? わからない...
admin? からの卒業 • 役割に依存した実装は、権限が暗黙的になる ◦ レビュワーは、常に役割の権限を知らないといけない ◦ 判定箇所が散らばり、どのような権限が定義されているのかわからない • 役割に依存した実装は、変化に弱い
◦ 役割の権限が変化した際に、多くの判定箇所を⾒ないといけない ◦ 権限の整合性を確認するために、多くの判定箇所を⾒ないといけない 29
役割でなく、権限に依存する 30
役割でなく、権限に依存する 31 プロジェクトを作成できるのか?
役割でなく、権限に依存する 32
役割でなく、権限に依存する 33 これだけでも、だいぶ良くなる
役割でなく、権限に依存する 34 ここまでが導⼊
役割でなく、権限に依存する 35 より深みへ
権限管理で⼤事なこと 36
間違えない 1. 実装で間違えない a. 追加、変更をするとき 2. 利⽤で間違えない a. 処理の中で判定をするとき 3.
理解で間違えない a. コードリーディングのとき b. お問い合わせの回答のとき 37
間違えない 1. 実装で間違えない a. 追加、変更をするとき 2. 利⽤で間違えない a. 処理の中で判定をするとき 3.
理解で間違えない a. コードリーディングのとき b. お問い合わせの回答のとき 38 権限はお問い合わせが多い
RBACとABAC 39
RBACとABAC RBAC(Role-Based Access Control) • 運営アカウント • 管理者アカウント • 外部アカウント
ABAC(Attribute-Based Access Control) • 作成者 • 担当者 40
RBACとABAC RBAC(Role-Based Access Control) • 運営アカウント • 管理者アカウント • 外部アカウント
ABAC(Attribute-Based Access Control) • 作成者 • 担当者 41 役割 条件(役割以外)
権限管理を整理する 42
具体例で整理 • 「プロジェクトの更新は、管理者か担当者ならできる」 43
具体例で整理 • 「プロジェクトの更新は、管理者か担当者ならできる」 • 「対象の、操作は、役割か条件ならできる」 44
具体例で整理 • 「プロジェクトの更新は、管理者か担当者ならできる」 • 「対象の、操作は、役割か条件ならできる」 • 「Modelの、CRUDは、RoleかScopeならできる」 45
Punditで実装 46
Pundit 47
Pundit 48 まだパッとわかる
Pundit 49 プロジェクトの更新は、 管理者か マネージャーかつ 担当者か作成者ならできる 外部アカウントは どんな場合もできない
Pundit 50
Pundit 51 「通常ユーザーは、プロジェクトの更新ができますか?」と 聞かれたら回答するのに何秒必要ですか?
Pundit 52 「通常ユーザーは、プロジェクトの更新ができますか?」と 聞かれたら回答するのに何秒必要ですか? 全部読みましたね? 5~10秒くらいかな
Pundit 53 「通常ユーザーは、プロジェクトの更新ができますか?」と 聞かれたら回答するのに何秒必要ですか? 実際のサービスでは より判定は複雑になる
Pundit 54 「通常ユーザーは、プロジェクトの更新ができますか?」と 聞かれたら回答するのに何秒必要ですか? どうしてパッとわからないのか
具体例で整理 • 「プロジェクトの更新は、管理者か担当者ならできる」 • 「対象の、操作は、役割か条件ならできる」 • 「Modelの、CRUDは、RoleかScopeならできる」 55
Pundit 56 対象 操作 役割 条件
RBACとABAC RBAC(Role-Based Access Control) • 運営アカウント • 管理者アカウント • 外部アカウント
ABAC(Attribute-Based Access Control) • 作成者 • 担当者 57 役割 条件(役割以外)
Pundit 58 対象 操作 役割 条件
Pundit 59 対象 操作 役割 条件
Pundit 60 対象 操作 役割 条件 役割と条件を分けよう
Pundit 61 対象 操作 役割 条件 つくりました
Moduleの設計と実装 62
63
64 対象 操作 役割 条件
65 Project / Manager def update assignee? || author?
66 なんとなくわかった⼈🙋
67 英語と論理演算がわかれば🙆
68 どうやって実現しているか ⾒ていきます
ざっくり概要 1. 対象と役割から権限のクラスを特定 2. 判定モードの指定 3. 操作名の関数を実⾏ 4. 条件の判定 69
70
71 対象 Modelと1対1
72 役割 Userのroleと1対1
73 操作
74 条件
75 対象 役割 操作 条件
ここまでの整理 • 対象ごとにディレクトリを作成、役割ごとにファイルを作成 ◦ 役割と条件を分ける • 権限のクラスの特定でメタプログラミングを活⽤ ◦ 権限の変更が容易 •
対象の基底クラスでCRUD以外の操作を追加 ◦ 対象ごとに異なる操作の拡張に対応 • 対象の基底クラスで条件を定義、条件を論理演算で使⽤ ◦ 判定は英語と論理演算がわかれば⼗分 ◦ 対象によって異なる条件の処理に対応 76
77 エントリーポイント
78
使い⽅ 1. レコードに対して権限があるかを判定する(recordモード) 79 対象と操作が明⽰されている👍
使い⽅ 2. 権限があるレコードのみに絞り込む(scopeモード) 80 対象と操作が明⽰されている👍
使い⽅ 3. 権限の⼀覧を取得する(listモード) 81 主にクライアントに渡して利⽤する
82 Context.newして関数を実⾏
83 権限のクラスを特定して判定を⾏う
84
85
86 対象と役割から 権限のクラスを特定する
87 対象と役割から 権限のクラスを特定する
88
使い⽅ 1. レコードに対して権限があるかを判定する(recordモード) 89 対象と操作が明⽰されている👍
90 権限のクラスを recordモードでnew
91 権限のクラスを recordモードでnew 操作名の関数を実⾏
92
使い⽅ 2. 権限があるレコードのみに絞り込む(scopeモード) 93 対象と操作が明⽰されている👍
94 権限のクラスを scopeモードでnew
95 権限のクラスを scopeモードでnew 操作名の関数を実⾏
96
使い⽅ 3. 権限の⼀覧を取得する(listモード) 97 主にクライアントに渡して利⽤する
98 Policy::{対象}で定義されている 対象名を全て取得
99 Policy::{対象}で定義されている 対象名を全て取得 権限のクラスを listモードでnew
100 Policy::{対象}で定義されている 対象名を全て取得 権限のクラスを listモードでnew 権限のクラスで定義されている 全てのpublicメソッドを実⾏
ここまでの整理 • 対象ごとにディレクトリを作成、役割ごとにファイルを作成 ◦ 役割と条件を分ける • メタプログラミングを活⽤ ◦ 権限の変更が容易 •
対象の基底クラスでCRUD以外の操作を追加 ◦ 対象ごとに異なる操作の拡張に対応 • 対象の基底クラスで条件を定義、条件を論理演算で使⽤ ◦ 判定は英語と論理演算がわかれば⼗分 ◦ 対象によって異なる条件の処理に対応 101
102 権限の基底クラス
103
104 判定に必要な情報 判定のモード
105 操作のデフォルトとしてCRUDを定義
106 対象の基底クラス
107
108 recordモード⽤の条件を定義
109 scopeモード⽤の条件を定義
110 CRUD以外の操作の追加
ここまでの整理 • 対象ごとにディレクトリを作成、役割ごとにファイルを作成 ◦ 役割と条件を分ける • 権限のクラスの特定でメタプログラミングを活⽤ ◦ 権限の変更が容易 •
対象の基底クラスでCRUD以外の操作を追加 ◦ 対象ごとに異なる操作の拡張に対応 • 対象の基底クラスで条件を定義、条件を論理演算で使⽤ ◦ 判定は英語と論理演算がわかれば⼗分 ◦ 対象によって異なる条件の処理に対応 111
112 権限の具体クラス
113
114 対象の基底クラスで定義した条件 を使⽤して判定を表現する 条件がない場合は Booleanを記述する
115 対象の基底クラスで定義した条件 を使⽤して判定を表現する 条件がない場合は scopeかscope.noneを記述する
116 具体的なレコードが必要な場合は or条件のキーを配列で返す 条件がない場合は Booleanを記述する
117 追加した操作の条件も 同様に記述
ここまでの整理 • 対象ごとにディレクトリを作成、役割ごとにファイルを作成 ◦ 役割と条件を分ける • 権限のクラスの特定でメタプログラミングを活⽤ ◦ 権限の変更が容易 •
対象の基底クラスでCRUD以外の操作を追加 ◦ 対象ごとに異なる操作の拡張に対応 • 対象の基底クラスで条件を定義、条件を論理演算で使⽤ ◦ 判定は英語と論理演算がわかれば⼗分 ◦ 対象によって異なる条件の処理に対応 118
ざっくり概要 1. 対象と役割から権限のクラスを特定 2. 判定モードの指定 3. 操作名の関数を実⾏ 4. 条件の判定 119
Q. 問題 120
121
122 対象 役割 操作 条件
123 なんとなくわかった⼈🙋
124 明⽇から弊社で お問い合わせ対応できます
使⽤例 125
126 readできるprojectsに絞り込む
127 readできるprojectsに絞り込む updateできるprojectか判定
128 readできるprojectsに絞り込む updateできるprojectか判定 権限に依存しているので明⽰的 役割の変化に影響されない
129 パッとわかる パッとわかる
130 パッとわかる
間違えない 1. 実装で間違えない a. 追加、変更をするとき 2. 利⽤で間違えない a. 処理の中で判定をするとき 3.
理解で間違えない a. コードリーディングのとき b. お問い合わせの回答のとき 131
間違えない 1. 実装で間違えない a. 追加、変更をするとき 2. 利⽤で間違えない a. 処理の中で判定をするとき 3.
理解で間違えない a. コードリーディングのとき b. お問い合わせの回答のとき 132 間違えない👏
良い設計の影響 133
事業への影響 • サービスの信⽤が向上した ◦ Module導⼊から1年が経過したが、不具合の発⽣件数がゼロ • 社内からのお問い合わせがゼロになり、開発⽣産性が向上した ◦ CSやPdMがGitHubの1次情報を⾒て理解できるようになった ◦
エンジニアは質問されたら、全部調べてしまい10分ほど使ってしまう 134
クライアント(Next.js)への影響 • RailsだけでなくNext.jsの技術負債も防げている ◦ 権限の⼀覧を渡すため、Next.jsも役割でなく権限に依存する実装に⾃然となった 135
クライアント(Next.js)への影響 • RailsだけでなくNext.jsの技術負債も防げている ◦ 権限の⼀覧を渡すため、Next.jsも役割でなく権限に依存する実装に⾃然となった 136 projectのupdateの権限がない場合は 編集ボタンは表⽰されない
クライアント(Next.js)への影響 • RailsだけでなくNext.jsの技術負債も防げている ◦ 権限の⼀覧を渡すため、Next.jsも役割でなく権限に依存する実装に⾃然となった 137 projectのupdateの権限がない場合は 編集ボタンは表⽰されない 権限によるUIの制御を 宣⾔的に記述できるようにしている
おまけ:Railsから外の世界へ 138
Next.jsからRailsへリクエスト 139 データの取得 データの変更
Next.jsからRailsへリクエスト 140 Moduleによる判定 recordとscopeモード
Next.jsからRailsへリクエスト 141 判定済みのデータ
Next.jsからRailsへリクエスト 142 判定済みのデータ Web Dev Tool でも⾒れない
Next.jsの権限管理 143
Next.jsの権限管理 144 ユーザーの指定
Next.jsの権限管理 145 Moduleによる判定 listモード
Next.jsの権限管理 146 権限の⼀覧を渡す Moduleによる判定 listモード
Next.jsの権限管理 147 権限の⼀覧を渡す Moduleによる判定 listモード 権限によるUI制御
Next.jsでの権限管理 148
149
150 対象
151 操作
152 操作 具体的なレコードが必要な場合は or条件のキーの配列
153
154 権限のクラスを特定
155
156 権限のクラスを特定
157
158 ユーザーの管理
159 操作のデフォルトとして CRUDを定義
160
161
162
163 条件を定義
164 判定がBooleanの場合
165 具体的なレコードがない場合
166 or条件の判定を⾏う
ここまでの整理 • Railsから渡ってきた権限の⼀覧のJSONを使ってMapをつくっている • そのMapをNext.jsで管理することでNext.jsの権限管理を実現している • Next.jsでも権限のクラスの定義と特定をしている • 具体的なレコードが必要な判定はNext.jsで⾏っている 167
168
169 対象がない場合
170 操作がない場合
171 具体的なレコードが指定されている場合
172 具体的なレコードが指定されていない場合
173
174 対象と操作が明⽰されている👍
175
176 権限によるUIの制御を 宣⾔的に記述できるようにしている
177 projectのupdateの権限がない場合は 編集ボタンは表⽰されない 権限によるUIの制御を 宣⾔的に記述できるようにしている
178 権限によるUIの制御を 宣⾔的に記述できるようにしている 対象と操作が明⽰されている👍
179 権限によるUIの制御を 宣⾔的に記述できるようにしている 具体的なレコードが必要な判定に対応
180 権限によるUIの制御を 宣⾔的に記述できるようにしている 権限がない場合の表⽰
ここまでの整理 • Railsから渡ってきた権限の⼀覧のJSONを使ってMapをつくっている • そのMapをNext.jsで管理することでNext.jsの権限管理を実現している • Next.jsでも権限のクラスの定義と特定をしている • 具体的なレコードが必要な判定はNext.jsで⾏っている •
権限のMapを活⽤することでNext.jsでも対象と操作が明⽰された間違えないを実現 • 権限によるUIの制御を宣⾔的に記述できるようにしている 181
まとめ • 権限管理を間違えると、事業とサービスへの損失が⼤きい • 権限管理が技術負債になるのは、役割が事業とサービスの成⻑と共に変化することと 役割に依存した実装が原因 • 権限の実装は、役割(admin?)でなく権限に依存しよう • 権限管理は、対象と操作と役割と条件の4つに分けられる
• 4つを分割をしたModuleの設計と実装の解説 • 良い設計の事業とクライアント(Next.js)への影響 182 ModuleのサンプルはGitHubで公開しています
「技術負債にならない‧間違えない」 権限管理の設計と実装 Kaigi on Rails 2025 @naro143(Yusuke Ishimi)