こんにちは。 この記事は freee Developers Advent Calendar 2024 - Adventar 12/09(9日目)の記事です。
今日は「共通管理基盤開発チーム」の "にいおか" が担当します。
昨日は shikakun さんの freeeで1年間働いてわかった「ふつう」のアクセシビリティ - freee Developers Hub でした。shikakun さんが入社して1年弱の間に実感した freee のアクセシビリティへの取り組みについて書かれています。私も入社してそれなりの年月が経ちますが、アクセシビリティへの向き合い方・重要視する姿勢は一貫して変わっていないなと感じます。これは freee の凄さであり強みであるなと改めて実感した記事でした!
本記事では「共通管理基盤サービス」に SAML 認証の仕組みを作成し、既存の「管理機能」への認証機能を置き換えた話を書きます。*1
はじめに
freee にはプロダクト内に実装された「管理機能」なる社内向けの機能が存在しています(以下、管理機能とします)。 割と古の実装が残されている秘境だったり、プロダクト内に実装されているが故にプロダクトへの依存性が高い状態で存在しています。
この管理機能をプロダクト共通で利用できるようにマイクロサービスに分離した「共通管理基盤サービス」を現在作っています(以下、共通管理基盤とします)。 プロダクトに依存しない情報は横断的に管理できるような、そのような社内向けのサービスです。
従来の管理機能へのアクセス認証はパスワード認証によって賄われていました。 従来の管理機能では独自のユーザー管理を行なっており、人の手による定期的な棚卸しが必要であったり、管理機能へアクセスするためのパスワードを覚えておく必要があるなどの運用上の課題を抱えていました。
今回はその認証機能を SAML 認証に置き換えることで運用上の課題解消を目指した話です。
この記事で出てくる言葉
この記事では以下の言葉が出てきます。
用語 | 説明 |
---|---|
Identity Provider | IdP と略す。SAML 認証においてユーザーが利用するサービスを管理し、認証情報を提供する立場を指す。 |
Service Provider | SP と略す。SAML 認証においてユーザーが実際に利用するサービスであり、IdP が提供する認証情報を利用して認証、サービスを提供する立場を指す。 |
管理機能 | freee 内における社内向けの機能の一つ。プロダクトによってあったりなかったりする。一番古いものでは創業当初から存在している。 |
共通管理基盤 | 増え続けている freee プロダクトに対する共通の管理機能の基盤となる社内向けマイクロサービス。「管理機能」からのマイクロサービス化・リプレイスを進めている。 |
認証基盤 | freee における認証処理を行うマイクロサービス。 |
元々はどういう作りであったか
元々はよくあるパスワード認証の作りとなっており、利用者である freee の従業員は管理機能の画面から ID とパスワードを入力することでプロダクト内で認証を行なっていました。 この認証の入り口は図でいうところのプロダクトA に閉じており、プロダクトB の管理機能にアクセスしたい場合はプロダクトA での認証を経てアクセスを行う必要があります。
認証後のセッション発行と管理は認証基盤が担当しています。*2
どのように作り変えたか
SAML 認証の機能提供を行うにあたって、以下のようなアーキテクチャとしました。
IdP にはフリー株式会社で既に利用している IDaaS を利用することにし、情報システム部門による入退職の運用フローに乗せてもらうことにしました。 そうすることで、SAML 認証利用に関するアカウント管理運用の分散を防ぐとともに、統制を高めることに寄与しています。 また、freee の従業員としても今まで利用している IDaaS 上にログインするアプリケーションの選択肢が増えるだけなので、利用に際しての学習コストがほぼ無いメリットがあります。
SP には共通管理基盤を利用することにしました。SAML Request の作成や SAML Response の検証は共通管理基盤に寄せています。 ReplayAttack のチェックに redis を利用しています。
認証基盤は SAML 認証後のユーザーチェックとセッション発行を行なっています。詳細は次のセクションに書きます。
最終的に認証が完了した後は、体験が変わらないようにパスワード認証後と同じ既存の管理機能の画面に遷移するようにしています。
今回の機能実装時の工夫
今回の SAML 認証導入のタイミングで取り入れた工夫として「認証基盤に既存の管理機能の利用ユーザー情報を移し替えた」ことを共有します。
認証基盤に管理機能の利用ユーザー情報を移し替えた
SAML 認証を実装することで、少なくとも freee の従業員であるという証明はされることになりました。 ですが、管理機能という性質上、限られたメンバーだけが利用できるようにしたいです。 これは元々、管理機能の利用ユーザー管理を他の社内システムとは独立させるに至った要件になっています。
限られたメンバーだけに管理機能は利用させたい、そして、(将来的な)横展開のために共通利用できるようにしたい、ということから認証基盤へのユーザー情報の移行を行うことにしました。 認証基盤を利用することで既存のプロダクト DB への依存を無くすことができると共に認証のロジックも集約できることになります。
そのため、共通管理基盤では SAML 認証のみで利用させることはせず、認証基盤を利用して ユーザーチェック およびに セッション管理 を行うようにしました。 例えば、IDaaS のみにアカウントが登録されている状態であるが、認証基盤側でユーザーの存在が確認できなければ認証基盤側で reject するようにしています。 これにより、「入退職による freee の従業員であるというアカウントの管理」と「管理機能を利用できるユーザーであるというアカウントの管理」の二段階のチェックを実現し、アカウント管理の統制を高めています。
認証基盤側の DB へ利用ユーザーの情報をどのように追加していくかについては、以下のように実現しています。 既存の管理機能を利用しているユーザーであれば意識せずに認証基盤が利用されるようになってほしいので、プロダクト DB の情報をマスターとして、プロダクト DB にレコードがあればそれを同期する仕組みにしました。
SAML 認証のタイミングで、認証に成功した場合、認証基盤に保存しているユーザーの情報と(主に利用されている)プロダクトに保存されているユーザーの情報の突合を行います(図に記載の 1 ~ 2 に相当します)。 認証基盤側にユーザーが未登録であるか、登録情報に差分が生じているかを確認し、必要に応じてプロダクト側に用意した同期機構に同期処理のリクエストを送信します(図に記載の 3 に相当します)。
管理機能の利用ユーザー情報管理自体はまだプロダクトにあるため、そちらを編集すると合わせて同期機構が動作し認証基盤に自動的に同期されるように二段構えの実装になっています。 これにより、IDaaS のユーザー管理に加え、システム側に元々存在していたユーザー情報を元に認証が行われることを実現しています。
将来的には認証基盤の情報がマスターになるようにし、プロダクト DB からはレコード削除を行うことを予定しています。
おわりに
社内向けの基盤に対して SAML 認証を提供するのはいささかリッチではないかという印象を当初持っていました。 ですが、退職時に IdP から削除される社内のアカウント管理フローに乗ることでアカウントの統制の文脈で大きいメリットがあったり、実際に利用するとボタン一つで認証が完了する利便性に勝るものはありませんでした。
管理基盤へのログイン方法のメインストリームを SAML 認証にすることに対して利用者へのハレーションもあるかと思いましたが、思ったよりもスッと受け入れられ活用されています。 認証フローを SP initiated と IdP initiated のどちらにも対応したことで、ログインオペレーションとして大きく変わらなかったことや操作として覚えることがほぼなかったことが良かったのかなと思います。
共通管理基盤として、まだまだ対応すること・したいことは盛りだくさんですが、これからもスピード感をもって社内に対して改善を届けていきたいですね。
明日は jaxx2104 さんによる tonari を活用したアプリ作成 に関するお話です!どういうのが作られるのでしょうね。お楽しみに!