はじめまして、2019年10月に入社しました開発・インフラ本部の丸山と申します。
弊社テックリード(@yukung)がついに短パン*1で出社したという観測情報に触れ、いよいよ日本にも夏が到来したことを実感しているところであります。
さて、私が担当させていただいているInnovation Captital Pathfinder(以下、ICP)におきまして、このほど認証機能をKeycloakに移行したので、機能移行までに検討したことを振り返ってみたいと思います。
前置き
私たち開発しているICPは、弊社が抱える膨大な数の特許情報や科研費情報などをもとに、お客様の新規事業の創出を支援するサービスです。公式には2020年1月にリリースしていますが、実はPoCも含めると2018年から開発が続いている弊社では比較的息の長いサービスです。
弊社が抱える膨大な量のデータを、いかにユーザーが利用しやすい形で提供するかを試行錯誤しながら開発してきた経緯があり、その規模の割にはとても複雑なアプリケーション構想になっていたため、機能追加が非常にしにくい状態になっていました。
しかしながら、ICPへの投資は継続して行われること、それに合わせてメンバーの採用を強化することが決まっていたことから、今後よりコア機能の開発に集中できるようにアーキテクチャの組み換えを行うことを決め、その取り組みの一つとして認証・認可機能の分離を進めてきました。
移行にあたって検討してきたこと
まず、Keycloakを採用した背景ですが、採用理由は至ってシンプルで、
- 我々の事業のコアとなる機能により多くの開発リソースを割きたいので、自分たちでは作らず何らかのプロダクトを使う
- 既存のコードベースに入る変更を極力少なくしたいので、クライアントプロキシ型のプロダクトが理想
- とはいえ非コアな機能にあまりお金もかけられないので、いざとなったら自分たちで面倒をみる覚悟でOSSを使う
という我々のニーズに対して、応えられそうだったのがKeycloakだけだった、という身も蓋もない理由です。
実際調べてみるとわかることですが、認証/認可に機能特化したプロダクトで、クライアントプロキシ型に対応し、かつOSSとなると、実はそんなに選択肢はありませんでした😅
また、利用するプロダクトの選定と並行で、ICPの認証・認可と絡む機能をどこまで切り出し、どこまでを既存のアプリケーションに残すかということも同時に検討していきました。検討の切り口としては以下の3点になります。
- 認証機能
- 認可機能
- アカウント管理
認証
ユーザーはどのようにログインし、システム側ではどのようにログインしていることをチェックするかという観点です。 我々のニーズとしては前述の通りクライアントプロキシ型が理想でしたが、Keycloakはそれに対応していることがわかりました。この辺りの詳細については、以前弊社の植木が執筆していますので、ご興味がある方はご一読ください。
また、上記に合わせて、既存のアプリケーションには以下の改修が必要なことがわかりました。
- アプリケーションで独自に実装していたログイン画面を廃止
- ログイン用のIDとパスワードもアプリケーション側では持たないように変更
- 既存の認証チェック用のフィルターを廃止
- Keycloakのクライアントプロキシを通過した前提の認証情報を受け取る認証チェックフィルターの実装
これらについては、クライアントプロキシ型の認証機能を所望していた時点でどこに改修が必要になるかはある程度の当たりはついていましたので、そこまで苦労することなく対応することが出来たと思います。
認可
ユーザーに与えられた権限に応じて利用可能な機能を制御するという観点です。 こちらについては、Keycloak自身が提供する認可機能には頼らず、引き続きICPのアプリケーション内で実現するという判断をしました。
はじめは認可機能もKeycloakに切り出す方向で検討していたのですが、ICPでこれを利用しようとすると、
- ロールの設定をするためにはKeycloakの管理コンソールを直接操作させるか、あるいは設定変更が必要な機能だけをラップした何らかの管理機能を別途提供する必要がある(管理者の誤操作による障害発生のリスク)
- ICPとして期待するような複雑な権限設定は出来ない(機能不足)
- ロールの設定変更のたびに、それに合わせたgatekeeperの設定変更、及び設定反映のためのデプロイ作業が必要になる(リードタイムの遅延リスク)
といった点をクリアする必要がありました。
また、ユーザーが利用可能な機能(ロール)を販売プランと紐付けるといった設定・調整を自分たちで速やかに行えるようにしたいというビジネスサイドからの要請もあり、今ある機能をわざわざ捨ててまでKeycloakに移行するメリットを見出せなかったことが最終的な決め手となりました。
アカウント管理
ログインための認証情報(ID、パスワード)、及びユーザー自身の情報(氏名、連絡先など)をどのように管理するかという観点です。 こちらについてはエレガントな方法はなく、ICPにおける既存のアカウント管理のユースケースを地道に再整理し、どれをICPに残し、どれをKeycloakに移行するかでチーム内で議論しました。そして、最終的には以下の対応方針を固めました。
- アカウント情報の管理は引き続き既存のアプリケーション内に残し、認証に関わるものだけKeycloakで管理する
- ICPとして管理したいアカウント情報のうち、一部の情報はKeycloakに格納場所がなかった
- 管理対象の情報ごとに画面が分かれているとUXを著しく損ねることから、アカウント管理画面は既存のアプリケーションにに一本化することにした
- 一方で少なくとも認証に関わる情報だけはKeycloakで管理する必要があるため、管理APIを利用してバックエンドでKeycloakに対して更新をかける方式で実装することにした
- ログインパスワードを忘れたときの再設定機能は、Keycloakに全面移行する
- 現行機能と同等のことをKeycloakで実現でき、かつ自分たちの実装箇所を減らすことができるため即決
- そもそも利用頻度の低い機能はこれを機に廃止する
ユースケースの整理の様子(一部抜粋)
やってきたことの振り返り
実はまだKeycloakへの移行が完了して1ヶ月ほどのため、移行したことによる効果を総括をするにはもう少し時間が欲しいところですが、とりいそぎ実際に移行するまでの検証/開発過程で感じたことをまとめたいと思います。
良かったこと
- アプリケーションの実装においてはよりコア機能をどう実現するかに頭を使えるようになった
- 認証済み前提のAPIを実装すればよいので、よりコアとなる機能をどう作るかに集中できるようになった
- OpenID Connectという標準化された仕組みを利用することで自分たちのシステムの認証の仕組みをより説明しやすくなった
- 認証に関連する便利な機能をKeycloakがすでに提供しているため、すぐに利用できる
- これまでやりたくても対応優先順の関係で実現しなかったことが大抵実装されていたので、開発工数が大幅に下がった
- ログイン後に元の画面にリダイレクトする
- 監査ログを取得する
- アクセスクライアントを追加/削除する
- 代理ログイン機能が超絶便利
- 特定のユーザーでしか発生しない事象があった場合に、エンジニアがそのユーザーになりかわってログインするといったことができるので、事象の再現がしやすくなることが期待できる (ちなみに、本番環境でこれをやるときは当然ながら事前にユーザーの許可を得てから行います!)
- これまでやりたくても対応優先順の関係で実現しなかったことが大抵実装されていたので、開発工数が大幅に下がった
- Openstandiaに日本語のリソース情報があるのは大変心強かった
- 本家の更新頻度に頑張って追従していたので大変有り難い
- 英語のニュアンスが分かりづらいときは日本語で行間を補完し、逆に日本語で何を意図しているかわからないところは原文に立ち返って理解するという使い方が出来たので、ある意味英語の勉強にもなった
ちょっと困っていること
- Keycloak/OpenID Connectそのものへの理解はある程度要求される
- 少数で対応したこともあり、詳細を突き詰めていくとメンバー間で理解度に差が生じているため、知識共有がこれからの課題
- Keycloak自身の開発ロードマップがイマイチ不明瞭なので、今後のアップグレード計画が立てづらい印象
- ほぼ毎月メジャーバージョンアップしているようだが、変更点の大半がバグ改修のようなので、常に最新に追随していないと辛そう
- Github上に定義されているマイルストーンに合致するリリース物が存在しないことがある
- gatekeeperのプロジェクト名がある日突然変わった...だと…?
- 管理画面で意図しない設定変更をしてしまっても気づきにくい
- 管理コンソールでほぼすべての設定をカジュアルに変更できてしまうので、意図せず設定を変更してしまう懸念がある
- そんなわけで現時点ではエンジニア職以外への開放は検討しづらい
- 管理コンソールでほぼすべての設定をカジュアルに変更できてしまうので、意図せず設定を変更してしまう懸念がある
というわけで
Keycloakの導入にあたって検討したことをあれこれ振り返ってみました。 これから導入する、または導入を予定されている方にとって検討の一助となれば幸いです。
なお、コロナもなんのその、現在アスタミューゼではエンジニア・デザイナーを絶賛募集中です。 ご興味のある方は下記バナーの採用サイトからご応募いただくか、カジュアルにランチなどでお話させていただくことも可能です。皆様のご応募をお待ちしております。
*1:弊社では夏の季語として認識されております