こんにちは。FLYWHEELでソフトウェアエンジニアをしてますsaoiです。我々のビジネスの中核はデータを活用したプラットフォーム事業ですが、この大切なデータを保護し安全にアクセスされるようにするため欠かせない技術が認証(Authentication:Wikipedia)と認可(Authorization:Wikipedia)です。
両者について詳しく記述するのはWebを検索していただければ沢山の解説記事があると思いますので割愛させていただいて、ざっくりとした解説のみすれば、
- 認証:あるユーザーが誰であるかを確認するためのステップ
- 認可:あるユーザーがあるリソース(たとえば情報など)に対してアクセス可能かを判定するステップ
というような理解になります。AWSやGCP、Microsoft Azureなど各種クラウドプラットフォームにおいてデータを保存したり、仮想マシンにアクセスしたりする際にも上記のステップを踏んでいることになりますし、わかりやすい例で言えば自社・個人でWebアプリを書かれて、そのユーザーの管理をしている場合なども当てはまります。
FLYWHEELにおいても事業の一翼である広告プラットフォームで、Webアプリケーションとして管理画面を提供しており、ここにもこの2つの技術が使われています。
本シリーズではこの2つの技術のうち、自社で開発して運用していた認証の部分を、外部の認証サービス(IDaaS, Identity as a service)に移行した際のお話をしていこうと思います。ちなみにタイトルにあるように、認証の引っ越しに次いで、FLYWHEELは渋谷に移転していたりします!
なぜこの話をBlogとして書こうかと思ったかというと、後にも触れますが、「認証」という大変地味ですがサービスのアキレス腱とも言うべき部分で、「自前で実装すべきかそうでないか」「すでにある自前実装を移行すべきか否か」「移行にかかわるコストとメリットの比較は?」などで悩んでいる同じエンジニアの方々に、少しでも判断材料として役に立てたらなぁ、と思って執筆をきめた次第です。
今回第1回の導入編は、移行に至った動機や背景、サービスの選定、どのような手順で入することによってどのようなメリットがあったのかなどについてお話をします。
認証は大事だけど面倒である
個人でアプリを開発し、ユーザー管理をされている場合などはクラウド各社が提供する認証サービスなどを組み込むのが標準になりつつありますが、企業においては、
- すでに実装済みで外部認証サービスへの移行が大変
- ユーザーの個人情報を管理するので、自社のクラウドアカウントorオンプレミス環境にとどめたい
ような理由で認証機構を自前で開発・運用しているケースがまだまだ多いかと思います。
どちらも企業の目線からすると頭の痛い問題です。しかし一方認証機構を自前実装・保守し続けることには様々なリスクも伴います。
- 使用しているセキュリティ技術(例:暗号化技術など)を最新に保ち続ける必要がある
- ソーシャルログイン(Facebookログイン、GitHubアカウントでのログイン)などSSO(Single Sign On)を用いたアクセスに対応するためのコスト
- メールアドレス確認、多要素認証などのセキュリティを高めるための追加技術実装コスト
これらのような認証機構に対する利便性の向上、堅牢性の向上への要求の高まりに追従し続けることは無視できないコストであり、本来アプリ・サービスで提供したい機能の実装を圧迫してしまうこともあり得ます。
FLYWHEELの広告プラットフォーム管理画面においても、認証機構を自前実装していました。しかし今後事業を拡大していくにあたって、認証まわりのセキュリティを担保しつつ、認証に関わる追加の開発コストや運用コストを最小化するためにIDaaSを導入することが決定されました。
どのIDaaSを使うか?
さて、IDaaSの導入にあたっては、数多あるクラウドサービスのなかから使うものを選定せねばなりません。これについてもWeb検索をすれば多くの比較記事やまとめ記事が出て来るかと思うので、ここではあくまで私が検討した際に判断材料とした項目にてついて書いていきます。
- ドキュメントが整備されている(サンプルコードなどを含む)
- 既存の認証機構から移行をするためのサポート機能がある
- APIによる各種制御がWebUIベースの管理コンソールと同等かそれ以上
- 設定をコードとして管理できる(Infrastructure as Code)
- 口コミ
1は導入検討ステージからプロトタイプに至るまで、チュートリアルやユースケース、機能説明やAPIの仕様について頻繁にドキュメントを参照することになります。また、導入後も頻繁にドキュメントをみることになるのは必至なので。ここのクオリティが低いと検討対象から自然と落ちていってしまいます。
2と3は既存実装からの移行という視点において重要でした。既存ユーザーのインポートや、移行中の中間状態をうまく乗り切るためには、移行が認証サービスの機能として提供されていることはもちろん、ユーザー登録や編集などの設定がプログラム上から行えることが必須です。
4は導入時にはあまり関係はありませんが、運用保守の観点から重要です。導入・設定にあたったエンジニアとその後保守・運用を行うエンジニアが同一ということは保証されていません。同じ環境を復元したりまたはクローンを作成する際にも設定がUIではなくコード(設定ファイルなど)としてダンプ可能、かつコードからの設定が可能であれば、その後の運用が驚くほど楽になります。
5はちょっと特殊ですが、やはりエンジニア界隈の口コミは信用に足るというところでしょうか。とくに「〇〇は使っててツライ」というのは、個人の好みという部分を差し引いても「自分も同様の問題にあたるかもしれない」というサインだったりすると思っています。
以上のような観点から(全てのサービスを比較する時間的余裕も根性もなかったので)、名前を知っている以下のサービスから検討することにしました。
大手クラウド3社+独立系1社という偏ったセレクションでしたが、大手はだいたい検討項目についてカバーしているのが予想できましたし、それ以外で社内エンジニアから聞いた1社を検討対象として入れてみた。という感じです。
検討した結果、Auth0を使ってみようという判断になりました。ドキュメントやプロトタイプを通して、どのサービスでも実装したい内容に不足はありませんでしたが、Auth0については以下の点が優れているという結論でした。
- ドキュメントの質が高い(知りたい情報についてWeb検索から公式ドキュメントへたどることが容易)
- 既存ユーザーのインポートについて多様な経路がサポートされている
- 「つかっててツライ」という話を聞かない
最後の点は消去法じみてはいますが、認証サービスのような狩野モデルにおける「当たり前品質」が求められる性質のものにおいて、「悪い話を聞かない」というのは大きな加点要素になるのではないかと思います。
認可機構はそのままに、認証のみをお引越し
さて、ここからがいよいよ移行に向かっての計画です。管理画面の構成は以下のようになっていました(説明を簡単にするため、実際の実装とは異なりますが、概念図として示しています)
管理画面はSPA(Sigle Page Application)として実装されており、広告配信に必要なデータ(広告内容、予算など)データベースに保存されています。このデータはSPAからAPI経由で操作され、APIの呼び出しの際の認証と認可がAPIサーバー上に実装されていました。
管理画面のAPIサーバーの実装では、認証(どのユーザーがリクエストしてきているか)と認可(リクエストしてきているユーザーは対象のデータを閲覧・編集する権限があるか)がうまく切り離されていたので、下図に示すように既存ユーザーのリストをAuth0側にエクスポートし、SPAはAuth0からアクセストークン取得、APIサーバーAuth0から発行されたトークンを検証してユーザー認証を行うようにする。という構成で実装することになりました。
すでに実装されている認証・認可機構がある場合、それが認可情報と密結合していることもあるかもしれません。そのような場合には今回のケースのようなシンプルな移行は難しいかもしれませんが、それらの結合を疎にするようなリファクタリングを行った上で同様のステップに持ち込むことは可能かと思います。
今回のまとめ
当初は1回で書き切ろうと考えていたのですが、冒頭で説明した「もしかしたら同じことで悩んでいるエンジニアも案外いるかも知れない」という思いのもと、認証がなぜ重要にも関わらず面倒な状態で全体システムの中に置かれてしまうのか?、移行する動機とは?、ではいざ移行するとなったらどんなことを検討したらいいのか?といった内容について、多分に個人的な見解ではありますが書かせて頂きました。次回「Part2-実践編」では具体的にAuth0のどのような機能を使って移行したのか、移行したことによってどんなメリットがあったのかについて書く予定です!