こんにちは。レアジョブ英会話開発グループの越です。
私がよく行くサウナ室にもテレビがありますが、サウナ室のテレビはチャンネルを変更することができないですね。
つまりサウナーには番組を選ぶ権限が無いが、サウナ室の管理者にはチャンネルを変更する権限があるということ。
この「ユーザーができることを制御する」ということを、ITシステム内ではアクセス制御ともいいますね。直近で社内の業務で利用するシステムにロールベースアクセス制御を導入する業務に携わったので、そのときにAuth0を利用したことについての記事を書きたいと思います。
RBAC(ロールベースアクセス制御)とは
Role Based Access Control の略
アクセス制御方式、あるいはアクセス制御モデルの1つ。
RBACはシステムを利用する主体(ユーザーやサービス)に直接パーミッションを設定するのではなく、ロールにパーミッションを設定して、アクセスするシステムを利用する主体にはロールを設定する権限管理方法のことです。
ロールベースアクセス制御とは、情報システムのアクセス制御の方式の一つで、個々の利用者ごとではなく、利用者に割り当てられたロール(role:役割)ごとに権限を付与する方式。
ロールベースアクセス制御(RBAC / 役割ベースのアクセス制御)とは - 意味をわかりやすく - IT用語辞典 e-Words
DAC(任意アクセス制御)
Discretionary Access Control の略
任意アクセス制御は、リソースの所有者にアクセス制御を任せる方式です。
任意アクセス制御の代表的な例としては、Unix 系 OS などで実装されているファイルパーミッション。
MAC(強制アクセス制御)
Mandatory Access Control の略
管理者一人がアクセス制限を行う方法です。
強制アクセス制御は、リソース所有者の意図に関らず、システムの管理者により一定のアクセス制御を強制する方式です。
強制アクセス制御の例としては SELinux。
ロールベースアクセス制御を行うメリット
ユーザーに対して直接パーミッションが与えられるわけではなく、ロールを通して与えられるため、各人のアクセス権の管理はユーザーへのロールの適切な割り当てに単純化され、ユーザーアカウントの追加やユーザーの部門間の異動などにも容易に対応できる。
社内の業務システムには、機密の情報や、利用者を限定したい機能が存在します。それらを保護しようとする際、保護が厳しすぎると業務が滞ります。逆に保護が緩すぎると、致命的なセキュリティの問題が発生する可能性があります。
ロールベースアクセス制御を行うことで、システムを利用するユーザーにパーミッションを割り当てる際のエラーの可能性を減らすことができると、Auth0のドキュメントにも記載があります。
Auth0でロールベースアクセス制御を行ってよかったところ
Auth0という枠組みの中でRBACの導入を進めたので、RBACを導入するにあたって、設計や開発を行う過程で致命的な技術的負債を埋め込まない安心感がありました。
認証には会社のGoolgleアカウントでのログインを行う必要があり、SaaSのサービスを利用した認証機能を検討していました。
Auth0を利用することで、認証と認可について開発や保守の観点でのコストが不要になり、ロールやパーミッションの設計に注力ができたのがよかったです。
加えてライブラリ、ドキュメント、APIが充実しているため、他のメンバーへの情報共有に関してもコミュニケーションコストは少なかった点について、導入して良かったと感じました。
ロールとパーミッションの設計
やることとしては、APIの登録、APIにパーミッションを定義、ロールの作成、ロールをユーザーにアサインの4つを順番に行います。
具体的な手順はドキュメントに記載されているので省略します。
ドキュメントのとおりに進めるだけなので、やることはほとんど無かったのですが、ロールとパーミッションの命名規則だけ、設計してから進めました。
パーミッションの命名規則
パーミッション名は参照、作成・更新、削除の3つの操作で分けて、機能やリソースに対する操作ごとに権限を分けられるようにしています。
read|write|delete:機能名|リソース名
パーミッション名(以下は例です) | 説明 |
---|---|
read:payments | paymentsリソースの参照権限 |
write:payments | paymentsリソースの作成・更新権限 |
delete:payments | paymentsリソースの削除権限 |
ロールの命名規則
ロールの名前で、ある程度どのような人が使用しているか判別できるように、ロールの命名規則は、所属組織・プロダクト名・ロール名の3つをアンダーバーで区切る形で作成しました。
レアジョブ英会話では一部の社内業務を外部に委託しており、業務内容は同じでも所属する組織が異なるというケースがあるため、所属組織ごとにロールを管理できるように設計しました。
所属組織_プロダクト名_ロール名
ロール名(以下は例です) | パーミッション | 説明 |
---|---|---|
rarejob_rarejob-eikaiwa_payment-supervisor | read:payments write:payments delete:payments |
レアジョブ英会話の支払い業務に携わる管理者のロール |
rarejob_rarejob-eikaiwa_payment-staff | read:payments write:payments |
レアジョブ英会話の支払い業務に携わるスタッフのロール |
rarejob-tech_rarejob-eikaiwa_developer | read:payments | レアジョブ英会話の開発に携わる開発者のロール |
実装の観点で意識したこと
ログイン時の権限取得
AccessToken(jwt)を要求したときに、そのclaimにpermissionsという属性が追加されています。
{ ... "permissions": [ "read:payments", "write:payments" ] }
ログイン時に取得したアクセストークンをセッションストレージでキャッシュして、アプリケーション側で機能の出し分けにパーミッションを利用していきます。
Laravelフレームワークとの親和性
LaravelのサンプルアプリケーションやチュートリアルがAuth0側で用意されており、それを参考にすることで簡単に導入できたのも良かったです。
- https://auth0.com/docs/quickstart/backend/laravel/01-authorization
- https://auth0.com/docs/quickstart/webapp/laravel/interactive
各機能のアクセス許可
パーミッションの使い方は各機能のアクセス許可に使用します。セッションストレージでキャッシュしたアクセストークンを参照して、必要なパーミッションを持っているかどうか、Laravelのmiddlewareでチェックします。
メニューやボタンの出し分け
パーミッションの使い方は機能のアクセス許可だけではなく、メニューやボタンの出し分けにも使います。これもセッションストレージでキャッシュしたアクセストークンから必要なパーミッションを持っているかチェックして、ビュー側で出し分けすることができます。
まとめ
個人的に業務で初めてアクセス制御を扱ったので、手探りな中進めていくことに最初は不安がありましたが、Auth0の仕組みに乗せることで、技術的な不安要素はほぼ無くせたのが良かったと感じました。業務を通してアクセス制御に関する理解が深まったのもよかったです。