Upgrade to Pro — share decks privately, control downloads, hide ads and more …

『自分のデータだけ見せたい!』を叶える──Laravel × Casbin で複雑権限をスッキ...

『自分のデータだけ見せたい!』を叶える──Laravel × Casbin で複雑権限をスッキリ解きほぐす 25 分

PHPカンファレンス2025での登壇資料です。

「権限管理って、どうしてこんなに複雑なんだ…」
M&Aという機密性の高い情報を扱うDXツールの開発で、私たちは20万パターン近くに及ぶ「権限の組み合わせ爆発」に直面しました。

この資料では、その複雑に絡み合った要件の糸を、私たちがどのように「スッキリ解きほぐした」のか、その全貌を解説します。

【この資料で学べること】
◆ 課題設定力:複雑な要件を整理し、本質的な仕様に落とし込むまでの思考プロセス
◆ 課題解決力:
・Laravel × CasbinによるABAC(属性ベースアクセス制御)の実装パターン
・責務分離を用いた見通しの良いアーキテクチャ設計
・Contextパターンによるパフォーマンス最適化

【こんな方におすすめです】
・Laravelで大規模な権限管理の実装に悩んでいる方
・Casbinの具体的な活用事例やアーキテクチャを知りたい方
・保守性と拡張性の高いバックエンド設計に興味がある方

Laravelで権限管理に立ち向かう、すべての方に贈る実践的な記録です。

#PHP #Laravel #Casbin #権限管理 #認可処理 #アーキテクチャ #設計パターン #ABAC #PHPカンファレンス

Avatar for AkitoTsukahara

AkitoTsukahara

June 28, 2025
Tweet

More Decks by AkitoTsukahara

Other Decks in Programming

Transcript

  1. Copyright© M&Aクラウド システム構成 7 • バックエンド:PHP, Laravel • フロントエンド:SvelteKit, TypeScript

    • アーキテクチャ:レイヤードアーキテクチャを採⽤ • 主要なエンティティ:Company,Deal,Sourcingなど
  2. Copyright© M&Aクラウド プロジェクト概要 8 • 期間:企画 1ヶ⽉+開発 1.5ヶ⽉ • 体制:エンジニア

    3⼈+PdM 1⼈ • ⽬的:部署 / 担当者 / 外部パートナー間で”閲覧できるデータ”を分離 • スコープ in:権限基盤 / UI制御 • スコープ out:権限管理GUI
  3. Copyright© M&Aクラウド どのようなデータ設計になるのか?先⼈たちの知恵を借りる • 権限モデル ◦ RBAC(Role Base Access Control)

    ▪ ロール〈=職種‧部署など〉に権限を付与 ◦ ABAC(Attribute Base Access Control) ▪ ユーザー‧オブジェクト‧環境の属性で動的判定 権限管理のモデル:先⼈たちの知恵を借りる 11
  4. Copyright© M&Aクラウド 単純に変数を掛け合わせると 24 * 4 * 8 * 20

    * 13 = ???パターン 組み合わせ爆発💣💥 16
  5. Copyright© M&Aクラウド 実装検討へ 23 要件、仕様も固まってきて、対応する権限パターンも⾒えてきた この権限機能をどう実装するのか • Laravel 標準のGate /

    Policy では難しそう ◦ RBACは対応できるが、ABACの対応が困難であった • 複雑な属性ベース制御が必要になる • RBACとABACの両⽅に対応する必要がある
  6. Copyright© M&Aクラウド Casbinとは? 24 宣⾔的アクセス制御エンジン • RBAC,ABAC, ACLを同⼀DSLで定義 • Go⾔語製、多⾔語バインディング

    ◦ 今回はPHP-Casbinを利⽤ • Model (ルール) と Policy (データ) 分離 • DB, Redis, CSVファイル なんでもポリシー保存可
  7. Copyright© M&Aクラウド Casbinの基本4ブロック 26 1. request_definition  (r = sub, obj,

    act ) a. リクエスト引数の並びを宣⾔ 2. policy_definition (p = sub, obj, act) a. ポリシー⾏の列順を宣⾔ 3. role_definition (g = _, _) a. ロール継承 (RBAC) を有効化 4. matcher (m = g(r.sub,p.sub) && r.obj==p.obj && r.act==p.act) a. r.* と p.* をどう⽐べるかを論理式で定義
  8. Copyright© M&Aクラウド Casbinモデル設計:最初の挑戦とシンプルな過ち 30 ▼ 最初の設計案(失敗例) • オブジェクト Company +

    スコープ ALL ◦ Casbinの obj には 'Company_ALL' という⽂字列を渡す。 • オブジェクト Company + スコープ OWN ◦ Casbinの obj には 'Company_OWN' という⽂字列を渡す。
  9. Copyright© M&Aクラウド 権限管理における課題解決の具体的なアプローチ 39 実装の壁を乗り越える3つの技術戦略+α • 権限チェック処理の責務分離とテスト容易性の向上 • 属性ベースアクセス制御 (ABAC)

    の実現 • データフィルタリングとパフォーマンス最適化 • フロントエンドでの動的UI制御(時間ないので付録で) • 品質向上への取り組み(時間ないので付録で)
  10. Copyright© M&Aクラウド 権限チェック処理の責務分離とテスト容易性の向上 41 解決策:権限チェック処理の責務分解 • Middlewareは「リクエストの受付」「Checkerへの処理委譲」に専念 • PermissionChecker: ◦

    オブジェクトの属性を解釈し、Casbinへの問い合わせ内容を組み⽴て る司令塔 • EnforcerAdapter: ◦ Casbinのenforceメソッドを呼び出すだけの、シンプルな橋渡し役
  11. Copyright© M&Aクラウド Step 1:徹底的に「分けて」考える 65 巨⼤で捉えどころのない問題を、扱えるサイズに「分け」ていきました。 • 要件を「分けて」可視化する ◦ 権限要件を5軸に分け、課題の⼤きさを数値で明確に

    • モデルを「分けて」シンプルにする ◦ 当初⼀体化して失敗した「オブジェクト」と「スコープ」を分離 • 問題発覚時の迅速な⽅向転換 ◦ 肥⼤化したMiddlewareを「⾨番」「司令塔」「専⾨家」に分け、各ク ラスが単⼀責務を持つように設計
  12. Copyright© M&Aクラウド Step 2:正しく「繋いで」動かす 66 次に、分離したコンポーネントを、あるべき姿に「繋ぎ」合わせました。 • 強⼒なエンジンで「繋ぐ」 ◦ 分離した権限ルールを、Casbinというエンジンで繋ぎ、判定ロジック

    のコアをシンプルに保ちました • 疎なインターフェースで「繋ぐ」 ◦ ObjectIdentifierなど、各クラスをインターフェースで疎に繋ぐこと で、拡張性とテスト容易性を両⽴ • Contextでレイヤー間を「繋ぐ」 ◦ PermissionContextを導⼊し、MiddlewareとRepositoryという異な る関⼼事を疎に繋ぎ、DBへの権限フィルター移譲を実現
  13. Copyright© M&Aクラウド 想定Q&A 70 • Q: ⽐較検討したライブラリは他には何があったのか? • Q: 全体の流れを把握したいです

    • Q: キャッシュ戦略は? • Q: フロントエンドでの権限制御は? • Q: 品質向上の取り組みは?
  14. Copyright© M&Aクラウド Q: ⽐較検討したライブラリは他には何があったのか? 71 ライブラリ モデル対応 主な対象⾔語 ⻑所 短所

    適合度 Casbin ACL / RBAC / ABAC / 任意拡張 Go (core) 他に PHP, Java, Node など 10 以上 マルチモデル‧軽量 組込‧⾼性能;PHP バインディングあり DSL 構⽂が独特で学 習コストやや⾼ ◎(採⽤) Laravel Policy & Gate ACL(基本的なアクセ ス制御) PHP / Laravel 標準機 能 追加パッケージ不要 ‧学習コスト低 ‧Eloquentモデルと の親和性⾼ 複雑なRBAC/ABAC不 可‧階層的権限管理 困難‧⼤規模権限管 理には機能不⾜ △(基本的な権限管 理のみ) Spatie laravel-permission RBAC(ロール+パー ミッション) PHP / Laravel Laravel Gate との親 和性∕学習コスト低 ABAC不可‧階層/属 性表現が弱い ◦(Laravel 単体なら ⼿軽) Bouncer RBAC + きめ細かい "ability" 概念 PHP / Laravel 否定権限・モデル単位 許可など表現力高 ABAC不可・階層/属性 表現が弱い ◦(Laravel 単体なら手 軽) Oso / Oso Cloud RBAC / ABAC / ReBAC(Polar DSL) Node, Go, Rust, Python, Java ほか "Polar" DSL が可読性 高い・クラウド/ローカル 混在可 PHP バインディング無 し、SaaS 料金高め △(言語制約)
  15. Copyright© M&Aクラウド Q: キャッシュ戦略は? 73 • バックエンドでは、利⽤していない。 ◦ 権限機能はセキュリティが重要であり、キャッシュは正しく実装しない と漏洩のリスクが伴うため、現時点では利⽤していない

    ◦ パフォーマンス最適化のためにいずれ利⽤する可能性はある • フロントエンドでは、利⽤している。 ◦ コンポーネントの表⽰判定のために、権限データを毎回バックエンドに リクエストしていては、パフォーマンスに影響するため ◦ もし意図しないコンポーネントを表⽰してしまっても、バックエンドで 防ぐことができるので、リスクは少ない
  16. Copyright© M&Aクラウド Q: フロントエンドでの制御は? 74 A. 制御しています。 なぜ制御しているのか?:UXを損なう不適切なUI表⽰になるため • バックエンドで権限エラーになる前に、ユーザーに「できないこと」を明⽰

    することで、UXを向上させたい • しかし、UIの表⽰制御ロジックがフロントエンドに散らばったり、バックエ ンドの権限ロジックと乖離するリスクがある
  17. Copyright© M&Aクラウド Q: フロントエンドでの権限制御は? 75 解決策:権限APIとクライアントサイドでの制御 • 特定の操作(「編集」「削除」「新規作成」など)に対して現在のユーザー が権限を持っているか否かを返すAPIエンドポイントを⽤意 •

    フロントエンド(SvelteKitなど)がこのAPIを呼び出し、その結果に基づい てUI要素(ボタン、メニュー、フォームフィールドなど)を動的に⾮表⽰ 化、⾮アクティブ化、または表⽰する
  18. Copyright© M&Aクラウド フロントエンド権限制御設計のポイント 76 • セキュリティ ◦ フロントエンド:UI制御のみ ◦ バックエンド:実際のセキュリティ担保

    • パフォーマンス ◦ ポリシーキャッシングで⾼速化 ◦ 重複リクエストの防⽌ • 保守性 ◦ コンポーネントベースで再利⽤可能 ◦ 宣⾔的な権限制御
  19. Copyright© M&Aクラウド DoD(Definition of Done)チェックリスト 84 コンポーネント Unit DB Integration

    Feature 新規Object追加時 ObjectIdentifier実装 ✅ ー ー ✅ 新規作成 SQLフィルタリング ー ✅ ー ✅ 更新 APIエンドポイント ー ー ✅ ✅ 更新
  20. Copyright© M&Aクラウド Q: 品質向上の取り組みは? 85 • ⽬的: 実装の⼿間や抜け漏れを防ぐための包括的アプローチ • 3つの柱

    ◦ テスト戦略 ▪ テストピラミッドによる効率的なテスト設計 ◦ DoD(Definition of Done)チェックリスト ▪ 新規権限対象追加時の必須項⽬ ◦ ⽣成AI活⽤による効率化 ▪ テンプレートクラスの⾃動⽣成
  21. Copyright© M&Aクラウド DoD(Definition of Done)チェックリスト 86 • アジャイル開発でのDoD運⽤体制 ◦ PBI完了条件:

    JIRAのPBIにDoD条件を明記 ◦ チームルール: DoD未達成のPBIはDone扱いしない