はじめに
こんにちは、freee の 権限管理基盤マイクロサービスを開発するチームでエンジニアリングマネージャーを務めている sentokun と申します。前職ではできることをできる限りやろうというスタンスで開発チームをリードし、アーキテクチャ設計やチームビルディングなどに取り組んでいました。その後 2022 年に freee へ入社し、freee で初めてエンジニアリングマネージャーの役割に。変わらずできることにできる限り取り組むスタンスでチームビルディングに従事しています。
この記事では、我々のチームが担当している権限管理基盤について語っていこうと思います!
権限管理基盤の成り立ち
freee では、「スモールビジネスを、世界の主役に。」をミッションに掲げ、統合型経営プラットフォームの開発・提供を進めています。最近では freee Togo Panorama を公開するなど、統合に向けて全社的に力を入れています。
このミッションに向かうにあたり、ユーザー体験を統一していくことは重要な要素になります。ユーザーがどのプロダクトを使っていても同じ操作感で機能が使える体験が得られなければ、統合型プラットフォームとしての違和感を与えてしまいます。そんな統一的な体験を与えるために、私の所属している部署ではプロダクト共通のサインアップ画面やマイクロサービス化によるログイン認証の統一といった基盤を開発しているのですが、その中で権限管理に関しては 1 つの課題がありました。それは、権限管理がプロダクトごとに異なることです。
現在 freee の多くのプロダクトでは、権限管理機能を独自に実装しています。そうすると、統一的な体験という観点では以下のような課題がでてきます。
- ユーザーにとって
- 新しいfreee のプロダクトを業務に取り入れるたび、新しく使い方を覚える必要がある
- freee の開発者にとって
- プロダクトごとに複雑な権限管理機能を自分たちで安全に、開発・運用・保守する必要がある
- 事業計画を立てる人にとって
- プロダクトごとの開発に時間とコストがかかる
こういった課題を解決するために登場したのが、freee の権限管理基盤です!
権限管理基盤のコンセプト
権限管理基盤は、ざっくりいうと freee のための社内 SaaS のように権限管理を行えるようにしよう!をコンセプトとして、freee の統合型プラットフォーム開発における基盤のひとつとして作られました。
提供する価値
権限管理基盤のテーマはズバリ 複雑な権限管理を誰にとっても簡単にわかりやすく提供する! です。 このテーマを元に、ユーザー、freee 開発者、プロダクト開発チームに対して以下の価値を提供します。
- ユーザーにとって
- どの freee プロダクトでも業務に沿って安全かつ簡単に権限の運用ができる。これによって管理者は安心して業務ができる。
- freee の開発者にとって
- ユーザーがよく利用する権限管理機能を手軽に安全に導入・運用できる。これによって権限管理機能の実装・導入の手間を最小化することが出来る。
- プロダクト開発チームにとって
- freee プロダクトの統合体験を素早くリーズナブルに提供できる。これによって、ユーザーに価値あるプロダクトの創造的な開発にフォーカスできる体制にできる。
- 事業計画の変更可能性を広げる。
アーキテクチャ
まずは権限管理基盤導入前のプロダクトのアーキテクチャイメージを共有します。
ログイン認証は認証認可基盤で行われるため、freee プロダクトで共通の仕組みとなっています。一方でその後のアクセス可否判定といった権限管理機能はプロダクトアプリケーションごとに実装されており、権限管理に必要な情報もプロダクトごとに持つ形となります。
一方、 権限管理基盤を導入した場合のアーキテクチャは以下となります。中心にある権限管理基盤が統一的に必要な情報を持ち、下にある権限管理プロキシがプロダクトアプリケーションへのアクセスを基盤に転送することでアクセス可否判定を行います。
また、権限管理基盤はバックエンドでのアクセス制御だけでなく、フロントエンドでも表示制御コンポーネントによる権限に合わせた画面制御機能を提供します。フロントエンド目線でのアーキテクチャは以下のようになります。
これまでのアーキテクチャ図で出てきた権限管理基盤の構成要素は以下となります。
- 権限管理基盤本体
- 権限管理機能を実現する本体で、gRPC APIを提供
- プロキシ
- エンドポイントアクセスを保護するためのプロキシ
- アクセスがプロダクトに届く前に本体へ転送し、可否判定を行う
- 表示制御コンポーネント
- ユーザーがどの機能を利用可能かを検証するためのUIコンポーネント
- 権限に合わせたUI表示の制御で利用される
プロダクト内部のソフトウェアアーキテクチャとしてもクリーンアーキテクチャをベースとした golang による実装で、コード生成ツールを活用するなど色々やっているので、そのうちに設計思想や開発方針についての記事もチームで出せたらいいなと思います!
ちなみになぜ権限管理基盤を自前で用意しているかをざっくり共有すると、freee に特化した権限制御が必要とされることも見えており、自社向けのサービスならではのきめ細やかな制御を行う必要があったからです。特化した制御を安全に分かりやすく利用できるようにするには、OSS や外部サービスを使って頑張って実現するよりも自前で作った方がいいという結論になりました。
権限管理基盤の提供する世界
権限管理基盤が目指す世界は以下となります。
- きめ細やかなアクセス制御の定義により、多様なアクセス制御ができる世界
- 多層的なアクセス制御により、幅広い層でセキュリティを担保する世界
- 効率的な機能の提供により、権限管理機能を利用するまでの手間がほとんどない世界
この章では、目指す世界についての簡単な説明と、その世界に向けて現在提供している具体的な機能について紹介します。
きめ細やかなアクセス制御の定義により、多様なアクセス制御ができる世界
多種多様なアクセス制御が権限管理基盤で実現でき、その導入も設定ファイルベースで簡単に定義できる世界を目指しています。 ここでは、提供機能のRBAC (ロールベースアクセス制御) による統一的な権限管理を紹介します。
RBAC (ロールベースアクセス制御) による統一的な権限管理
RBAC の仕組み
権限管理基盤では、 RBAC による権限管理機能を提供しています。RBAC とは、ロールによってアクセス制御を行う仕組みのことです。
ロールに対して使える機能を紐づけ、
ロールをユーザーと紐づけることで、ユーザーの権限が決まり、利用できる機能が制御されます。
プリセットロールとカスタムロール
ロールには、プリセットロール(デフォルトで用意されたロール)と、カスタムロール(ユーザーが作成するロール)の2種類が存在します。
プリセットロールは、プロダクトごとに権限管理基盤の設定ファイルで定義します。この設定を権限管理基盤に投入することで、プリセットロールが利用可能となります。設定ファイルは yaml 形式で記載し、機能とプリセットロールの紐付けを定義します。
また、この機能とは文脈が違いますが、設定ファイルはどのエンドポイントが何の機能で利用可能なのかの定義も持っています。この定義は、後で出てくるエンドポイント保護の機能で利用されます。
カスタムロールは、ユーザーがプリセットロールをコピーすることで利用することができます。
コピーしたロールに対して、名前や使用できる機能を選択することで、カスタムロールとして利用することができます。
以下にプリセットロールとカスタムロールの違いを記載します。
- プリセットロール
- freee プロダクト開発者が設計します。
- プロダクト開発者が設定ファイルを用意し、権限管理基盤に設定投入することで使用することで作成されます。
- ユーザーはデフォルトで利用することができるが、プリセットロールの編集はできません。
- カスタムロール
- ユーザーが設計します。
- カスタムロールの機能を使い、他のロールをコピーし編集保存することで作成されます。
- ユーザーはカスタムロールの機能を使って利用することができ、編集も可能です。
多層的なアクセス制御により、幅広い層でセキュリティを担保する世界
権限管理基盤により複数の層でアクセス制御ができる世界を目指しています。
ここでは、エンドポイントの保護を UI の表示制御機能について紹介します。
エンドポイントの保護
権限管理基盤では、プロダクトへのエンドポイントアクセスに対する保護機能を提供しています。対象のエンドポイントは設定ファイルに記述し、どのエンドポイントが何の機能で利用可能なのかを定義します。イメージ図は RBAC での記載を参照ください。
権限管理基盤はホワイトリスト形式を採用しているため、記載のないエンドポイントは拒否されるようになっています。これは、定義漏れで意図せずアクセスを許可してしまうといった事故を防ぎ、安全に運用できるようにするためです。
また、構成としてもプロキシをプロダクトアプリケーションの前段に位置させ、全てのリクエストに対して一旦プロキシを通すようにしています。これにより、確実にプロダクトへのアクセス可否判定を行うことができるようになっています。
エンドポイントの保護は Webアクセス、モバイルアクセス、freee API に対して行っています。
UI の表示制御
権限管理基盤では、権限の有無の問い合わせをフロントエンドから行えるよう、 表示制御コンポーネントを提供しています。このコンポーネントにより、例えば対象の機能が使える人だけが画面を表示できたりボタンが操作できるといった表示制御が可能となります。
効率的な機能の提供により、権限を利用するまでの手間がほとんどない世界
設定投入や少しの導入実装のみで、安全かつ簡単に権限管理機能が利用できる世界を目指しています。
ここでは、プロダクトごとの権限管理画面開発の簡略化と、設定ファイルによるアクセス制御の定義に関わる仕組みを紹介します。
プロダクトごとの権限管理画面開発の簡略化
権限管理画面を追加するための手順はマニュアル化されており、いくつか定義コードと処理を追加するだけでプロダクト向けにシュッと権限画面を追加できるようになっています。ゆくゆくは設定さえ入れば画面が作られるレベルになったらいいなと思います。
アプリケーションデプロイと同時に設定を更新
権限管理基盤はホワイトリスト形式を採用しているため、プロダクト側で機能やエンドポイント追加があった場合は権限管理基盤に設定を投入する必要があります。リリース当初は設定変更を認証認可基盤チームに依頼をしてもらい投入する流れを組んでいましたが、現在ではプロダクト側のアプリケーションデプロイ時に自動で設定投入ができるようになっています。
最後に
権限管理基盤はまだまだ生まれたてのマイクロサービスで、これから導入プロダクトを広げつつ成長していくフェーズにあります。そんな新基盤プロダクトの新しい機能や内部構造、チームとして取り組んでいることなどなどを今後もアウトプットしていけたらと思いますので、よろしくお願いします!
また、freeeの認証認可基盤・課金基盤では一緒に働く仲間を募集しています。進化していく freee の基盤開発にご興味のある方は是非ご応募ください!