1. 金融サービスセッション

金融サービスセッション (Road to Be FAPI Certified)

この文字起こしは、2022 年 12 月 7 日に開催された Authlete Customer and Partner Meetup 2022 のプレゼンテーションのひとつです。 ゼロバンク・デザインファクトリー株式会社 シニアマネージャー 豊島慎志氏に、Authlete を用いて構築したシステムに関する FAPI 認定取得の事例をお話しいただきました。

はじめに

こんにちは。 工藤さんから紹介がありましたように、FAPI 認定までの道のりについて話します。

まずざっくりとぼく自身の自己紹介をした上で、みんなの銀行についてと、今回の API 開発の目的となった BaaS 事業について紹介させていただいた後に、本題の Authlete を活用したBaaS API 基盤開発についてお話しさせていただきます。最後は今後の FAPI についてしめくくります。

自己紹介

自己紹介です。

2016 年に ERP ベンダーに入社して、サプライチェーンマネジメントのERP パッケージの開発をしていました。それからもうちょっとクラウドネイティブ指向な開発をしたいっていう個人的な意向があって、2018 年に Microsoft Azure 専業の SI 会社に行って、クラウドバンキングの開発をやっていました。

その後 2020 年 3 月、みんなの銀行が開業する 1 年ちょっと前のタイミングだったのですが、そこでゼロバンク・デザインファクトリーに参画して、みんなの銀行アプリの API および勘定系システムの開発に従事しています。

現在は既存サービスの保守をしつつ、主に BaaS API の開発を担当しています。この BaaS API と我々が呼んでいるのが、今回 FAPI 認定を取ったAPI プラットフォームになります。

みんなの銀行について

まず、みんなの銀行についてです。

国内初のデジタルバンク

みんなの銀行は、ふくおかフィナンシャルグループの傘下にあります。そして、みんなの銀行のシステムそのものの開発・運用・保守を担っているのが、ゼロバンク・デザインファクトリーになります。

図の通り、エリア・ターゲット・チャネルが、従来の銀行とは違ったものになっています。銀行そのもののあり方としても、これまでと異なり、従来のかたちにとらわれず、 現代の社会に必要とされている機能を、フレキシブルに作っていこうというマインドセットで、事業を展開しています。

お金のあれこれ、スマホで完結

何事もミニマルにというのが、みんなの銀行の世界観です。デジタルバンクなのでブランチは無く、すべてのアクションを、アプリの中で、 シンプルに完結させるところを、常に念頭に置いています。

銀行をもっとシンプルに

ターゲットはデジタルネイティブ世代です。

デザインはこんな感じです。ちょっとユニークなかたちになっています。たとえば、貯蓄預金のところをドラッグ & ドロップすればお金を移動できるといった、軽快な UX にもこだわっています。もしよかったらダウンロードよろしくお願いします。

3 つのビジネスを展開

みんなの銀行の事業ドメインです。 主に 3 つのビジネスを展開しています。

1 番目はB2C 事業そのものです。みんなの銀行アプリを運営しています。

2番目、これが今日の本題になる B2B2X です。いわゆる Embedded Finance、事業者が銀行の機能を借りてビジネス展開していく事業になります。

3番目は勘定系システムの外販やホワイトレーベルアプリ開発などのビジネスです。

BaaS 事業

今回話すのは、2番目の BaaS API です。

パートナー企業に API を提供

その詳細です。API 提供モデルというビジネスの、多くのユースケースでは、事業者側もライセンスが必要になることが多いです。 相互に協力し合って連携していくかたちです。ここで、FAPI に準拠した認可フローで、事業者に接続してもらうことになります。

銀行口座から銀行口座に直接支払う「A2A 決済」

実際のところ、BaaS API とは何か。

まず、A2A 決済というのが日本でも世界的にも流行っています。これは Bank to Bank、銀行口座から銀行口座に直接支払うしくみです。アプリ的には「Pay with みんなの銀行」みたいな感じで支払うだけですが、リテイラーにとっては、仲介業者が挟まらず実質的にコストがかなり安くなるため、とてもニーズがあります。

我々は勘定系システムを自前で持っているので、いろいろな機能をロールアウトしていくことができます。最初にリリースする更新系が、A2A 決済です。

Walmart の事例

アメリカの事例を紹介します。有名なグローサリーストアのウォルマートです。同社の課題として、給与日前に生活費が枯渇して購入意欲が無くなることによる機会損失がありました。 そこで、ウォルマート自身のアプリの中で、小口融資を給与日前に出すサービスを展開して、顧客の購買意欲を促進しています。 ひとつのわかりやすい事例ですね。

みんなの銀行でも、こういったサービスは提供可能です。BaaS API、 FAPIに則ったセキュアなかたちで、こういった機能をどんどんロールアウトしていこう、という計画です。

Authlete を活用した BaaS API 基盤開発

そしてようやく、Authlete を活用した BaaS API 基盤開発の本題に入ります。

本格開発からリリースまで約 1 年

開発の流れです。数ヶ月間 PoC を行った後、去年の 9 月頃から本格的に開発しました。そこから始めて、 約 1 年で開発しました。開発はゼロバンク・デザインファクトリーと、LiNKXと、ミクセファイというパートナーの、3 つの会社で肩を組んでやっていました。

本格開発

本格開発は全般的で、インフラ構築もそうですし、認証認可基盤からリソースサーバー系のマイクロサービス、そしてモバイルアプリや勘定系接続も含みます。

Authlete を統合し FAPI 対応

開発が進み、認可サーバーとかの構築が完了した時点で、さっき工藤さんからもコンポーネント的に使えるっていう話がありましたが、事前に構築した認可サーバーを Authlete と入れ替えるかたちで統合しました。既存の認可サーバーでは FAPIの要件を満たしておらず、そこをカバーするのを目的に、Authlete と統合しました。Authlete の API はすごくつなぎやすく、クイックに対応できました。

テストスイート実行から FAPI 認定へ

ある程度 FAPI 対応ができたぞと自信を持った段階で、FAPI のテストスイートを実行しました。FAPI のテストスイートは、OpenID Foundation が提供する自動テストツールです。自らの手でテストスイートを実行し、自らコードを修正するのは、個人的にもすごく貴重な経験でした。 何個か見落としていたケースがありましたが、そこをテストスイートが拾ってくれました。それらを修正して、全部のテストを通過して、ようやく OpenID Foundation にテスト結果を提出しました。最終的にマニュアルレビューを OIDF から受けて、やっと FAPI 認定を受けました。

App2App 連携デモ(マネーフォワード ME)

その 2 ヶ月後に参照系の本番リリースをしました。更新系 API は Coming Soon となっています。

マネーフォワードさんが、最初にうちとつないでくれたクライアントさまです。マネーフォワード ME から、みんなの銀行アプリに連携するデモをお見せします。

直でディープリンクに行って、 リダイレクトでマネーフォワードに戻って、この時点でもうアクセストークンが発行されています。 非常に見た目はシンプルですが、中ではとてもセキュアなことをやっています。それが FAPI です。FAPI について次のスライドで話していきます。

FAPI 採用が日本の金融システムにおける最適解である理由

技術的な話をする前に、日本の金融システムが FAPI 認定を取得する意義について、個人的に考えてみました。

「具体的な標準仕様が存在しない日本」における最適解

世界を見てみると、UKをはじめ、EU、ブラジル、オーストラリア等、Financial Grade な API 仕様が公開されています。対して日本には具体的な仕様がまだありません。全銀協のワーキンググループや FISC などは存在しますが、具体的な仕様は無いと思います。

標準仕様があった方がいいと、個人的に思っています。優秀な人たちが考えてきた知の恩恵を受けられるだけではなく、軸がはっきりしているので開発も効率的になります。

利点は開発側だけではなくクライアント側にもあります。接続する方式が統一化されると、一般公開される SDK などが充実します。安心できるセキュリティ強度が証明できるのも利点です。

日本では標準が揃っていないので、標準仕様として認定プログラムのプロファイルである “Plain FAPI” を採用するのが最適解だと考えています。

様々なセキュリティテクニックの取り込み

標準仕様はある意味、制約の側面もあるかもしれません。しかし、アーキテクチャ設計段階において、一般的に言われている様々なセキュリティのテクニックを取り込むには、たんに “Plain FAPI” に則るだけでは不十分です。

我々は、セキュアなものはどんどん取り込んでいくつもりで開発を進めており、もう少し具体的な標準仕様があると、もしかしたらもっと効率化できるのかもな、と思っています。

OAuth2 活用におけるバッドプラクティスの回避

次に「認可フレームワークは OAuth2 を推奨」だけでは自由度が高すぎるため、バッドプラクティスを採りかねません。金融システムの認可機能を構築する上で、FAPI は OAuth2 活用のたんなるベストプラクティスではなく、「高度な」ベストプラクティスだと思っています。

認定プログラムによる仕様準拠検証の自動化

認定プログラムは、自動テストによって仕様に則っているかを検証するので、すごく細かい問題に関しても検知できます。リリース前に細かなこと、すごく細かな RFC の読み落としとかも、拾えるところが良かったです。

進化し続ける FAPI

あと FAPI2 の動向も追っています。FAPI はこのまま進化し続ける見込みが高いです。

FAPI1 Advanced プロファイル

より技術的なところになります。FAPI プロファイルにはいくつかあります。今回認定を取ったのは、FAPI Advanced OpenID Provider with mTLS, JARM というプロファイルです。FAPI1 Advanced で要求されている必須項目を網羅するのが、このプロファイルになります。

4 つの必須要件

FAPI Advanced プロファイルの必須要件は、以下の 4 つです。

  • 署名された認可リクエスト
  • クライアント証明書にひもづいたアクセストークン
  • クライアント認証として mTLS の採用
  • 署名された認可レスポンス

他にも細かい要件はたくさんありますが、この 4 つが代表的なものだと思っています。

PAR

オプショナルな仕様として、Pushed Authorization Requests (PAR) があります。 PAR は認可リクエストを事前にクライアントから認可サーバーへ直接送信した上で、Authorization Code Grantを行うしくみです。

PAR の利点として、まず、ユーザーエージェントに認可リクエストのペイロードが露出されません。また、認可リクエスト URL が短くなります。 トラディショナルな認可リクエストで、リクエスト URL に Base64 エンコードされたストリングが入ると、かなり長い URLになってしまい、エラーを引き起こしやすいという懸念があります。

正直に言えば、PAR を導入すればよかったと思っています。FAPI1 Advanced では PAR は必須ではありません。その「必須かどうか」にこだわりすぎたところもあって、PAR を標準フローとして取り込みませんでした。ただ、もしいまから FAPI 認定を取るとなったら、PAR はすごくおすすめです。

FAPI2 の動向として、PAR が必須化される見込みです。まだドラフトですし、ぼくは OIDF のメンバーでもないので強いことは言えませんが、動向を追っている限りではそうなると思います。

PKCE

あとは PKCE です。エンジニアのみなさんはけっこうご存知かもしれないですけど、 OAuth2 における認可コードの横取り対策のベストプラクティスです。

FAPI Advanced ではなぜか、PAR を使わないのであれば PKCE は必須ではない、となっていると認識していますが、とはいえ PKCE を強制しない理由はとくにないかなと思います。

ただ、テストスイートには No PKCE と PKCE のどちらのテストもありました。よって、いずれにせよどちらのフローにも対応する必要があります。Authlete はフラグを持っているだけなので、そこは柔軟に対応できます。

FAPI テストスイートは早めに実行すべき

次は FAPI テストスイートです。認定を取った後に振り返ると、本当に、早めにテストスイートを実行すればよかったなと思っています。

正解を最初に見たほうが効率的にできる

利点はいろいろありますが、まず考えられるのは、 誰でも気軽に実行できるところです。思ったよりかんたんに実行できるので、最初に動かしてみる価値があります。あとはテストドリブンでやった方が、全体も見えるし、正解を最初に見るほうが効率的だなと思います。

仕様の見落としを防止できる

FAPI 認定を受ける上では OAuth2 に対する深い理解が必要です。その上で膨大な量の RFC を読むことになりますが、人間なのでどこかを見落とすものと思った方がいいです。なので、正解のパスから逆算してやっていっても良かったのかなと思っています。

世界の FAPI 関連プロファイルが参考になる

あと、“Plain FAPI” だけではなく、Brazil FAPI とか Open Banking UK とか、そういった世界の FAPI 関連のプロファイルを探索できて、アーキテクチャとして参考にできる点をいろいろ発見できて、それも良かったです。

繰り返しになりますが、FAPI テストスイートは気軽に実行できるので、触ってみるのはとてもおすすめです。

BaaS API プラットフォームの構成

アーキテクチャ

こちらがアーキテクチャーの概要、簡略版になります。

左の青いボックスがクライアント API です。上に Authlete があります。右にみんなの銀行アプリがあって、紫で囲んでいる部分が BaaS API プラットフォームです。もちろんその奥に勘定系とかいろいろありますが、そこは割愛します。

「署名された認可リクエスト」の処理

フローです。Authorization Code Flow with PKCE, Request Object, JARM, mTLS, Certificate-bound Access Token です。さっき言った、FAPI での主な必須要件です。PKCE は、PAR ではない場合には必須ではありませんが、基本として、本番の認可フローでは強制化しています。

フローを追っていきます。最初にクライアント API は認可リクエストを生成する必要があります。ここで重要なのが、認可リクエストは「署名された認可リクエスト」でなければなりません。FAPI ではその署名アルゴリズムも具体的に指定されています。

署名された認可リクエスト URL を、 エンドユーザーのシステムが開きます。次に認証ページにリダイレクトするのですが、 その前に認可リクエストそのものの署名検証とか、リダイレクト処理とかセッション管理とか、もろもろやります。

ここで Authlete がやるのが、認可リクエストの署名検証です。あとその他の詳細な、リクエストオブジェクトのパラメーターのバリデーションとかも Authlete にやってもらいます。

Authlete から結果が返ってきます。弊社の使っている Apigee X には OAuth ポリシーという機能があり、これを使って認可サーバーを実装できます。Apigee X の ExternalAuthorization のポリシーを使って、 Authlete からの結果を Apigee X に同期させるようにしています。

Authlete には “ticket” という、 Authlete のセッション ID みたいなものがあります。この “ticket” はクライアントに公開すべきではないと明記されています。よって、認証のセッション管理とは別に、内部のマイクロサービスで管理しています。内部的にはそのまま “ticket” とひもづいていますが、外部に公開してブラウザで使われるのは、うちが発行したセッション ID になります。

「みんなの銀行アプリ」によるユーザー認証強化

認可リクエストに問題が無かったら、そのまま認証ページにリダイレクトします。我々は、認証のリダイレクトで、 App2App フローと、App2Web もしくは Web2Web フローの、どちらもサポートしています。

App2App は、ディープリンクで直接クライアントのアプリからみんなの銀行アプリにリダイレクトするフローです。

一方、みんなの銀行アプリが連携しようとしている端末にインストールされていなかった場合は、ブラウザの認証ページにリダイレクトします。ブラウザの認証ページでは E メールとパスワードを入力してもらいます。みんなの銀行アプリのクレデンシャルです。 それを送信しただけでは、まだ認証はされません。その後、確実に本人であることを確認するために、 みんなの銀行アプリがいわゆる Two Factor Authentication (2FA) アプリとして機能します。みんなの銀行アプリによって承認されて、はじめて認証がされたとみなします。そこが、独自の認証の扱いかたのポイントです。

JARM を用いた認可レスポンス

認証が問題なく成功したら、その後、認可コードを発行するフローに移ります。 認可コードの発行も、Authlete に、 “ticket” を使ってリクエストします。署名された認可レスポンスを Authlete からもらって、それをクライアント API のコールバック URL に、リダイレクトで渡します。リダイレクトとかは Apigee でハンドリングしています。

クライアント API は、署名された認可レスポンスである JARM の署名検証を行います。パブリックキーを JWKS エンドポイントで公開しているので、クライアント API にはそこを見てもらって、パブリックキーを用いた署名検証をしてもらいます。

mTLS モードでのトークンリクエスト

署名の検証が終わったら、ようやく認可コードをトークンと交換するステップに進みます。もちろん細かいことを言えば、 クライアント API は、state をチェックし、認可コードだけでなく code_verifier を一緒にトークンリクエストで送信します。

ここでもうひとつ重要なのは、トークンリクエストのときは、mTLS モードであるということです。 クライアントの認証そのものを TLSで 認証した上で、トークンリクエストを許可します。我々の認可サーバーは、クライアント認証が終わった後に、code_verifier の検証をします。

ここで、トークンリクエストの検証も Authlete にお願いします。 Authlete に渡すのは、すでに認証済みのクライアント証明書と、トークンリクエストのセットです。それを Authlete にリレーして、問題が無ければ、トークンレスポンスを Authlete からもらって、そのトークンレスポンスを Apigee X の Cassandra に同期します。ここで重要なのは、トークン検証は証明書とひもづいて行わなければなりません。よって、クライアント証明書もセットで保存しています。それが終わったらようやく、アクセストークンとリフレッシュトークンをクライアント API に返却します。

証明書付きのリソースリクエスト

そのアクセストークンを使って、クライアント API は証明書付きのリソースリクエストを行います。証明書とアクセストークンのひもづけが問題無いか、つまりアクセストークンのチェックのみならず証明書とのひもづけも問題無いか、チェックされるのがポイントです。

その後に書いてある “ファントムトークン” とか “Pairwise Pseudonymous Identifier” とかは、”Plain FAPI” の話ではありません。FAPI のテクニックではありますが、この場では割愛します。

アクセストークンとクライアント証明書に問題が無ければ、 クライアント API は正常にリソースにアクセスできる、というフローになります。

Authlete 採用の 5 つの理由

Authlete 採用の主な理由を列挙しました。

自行での Authlete 利用実績

まず前提として、BaaS API で採用する前から、みんなの銀行アプリ自体が認可基盤として Authlete を活用していました。その実績があったのが、まず一番大きいです。

「みんなの銀行アプリ」の高度認証機能の活用

次に、認証ソリューションは必要としておらず、 みんなの銀行アプリによる独自の認証を活用したかったということがあります。みんなの銀行アプリは、先に述べた 2FA もありますが、内部的に challenge-response authentication というしくみでデバイス認証もやっています。生体認証に加えて、そういった強めの認証を独自で持っており、それを活用したかったということもあります。

API を通してコンポーネント的に利用可能

また認可サーバーそのものではなく、OAuth2 に関するコア機能を、API を通してコンポーネント的に活用できるので、 使用可能なアーキテクチャの自由度が高い、ということがありました。我々は認可サーバーを、最終的には Apigee X でほぼほぼ構築しましたが、その中の OAuth2 のコアな機能は Authlete に委任しています。

マルチリージョンに対応

あとはマルチリージョンが、我々にとっては重要です。我々のシステムは、 東京・大阪の active-active redundancy で動いており、東京が死んでも大阪が動いていれば死なないようになっています。そこで、システムが依存しているサービスはマルチリージョンに対応している必要があります。

サポートの充実・クイックな対応

そして、いいなと思うのが、サポートの充実です。OAuth2 でも、そのいろいろな解釈によって実装が分かれるところが、たまにあります。あるとき、Authlete ではこう解釈しているので対応していません、ということがありました。その際は、我々から機能追加要求をしたところ、かなりクイックに対応してくれました。そういうのがすごくありがたいなと思っています。

今後の FAPI について

今後の FAPI について、最後に締めくくります。

Authlete API を活用して FAPI2 に対応したい

ZDF は FAPI2 の動向に注目しています。まだ FAPI2 はドラフトですが、ファイナライズされたら、Authlete API を活用して、最短で認定を取りに行きたいなと思っています。

FAPI2 の特徴

見ている中での主な動向としては、 PAR の必須化とか、クライアント認証について mTLS のみから DPoP も選択肢として追加されることとかがあります。DPoP については、おそらく接続するクライアントの範囲を広げる傾向にあるのかな、と思っています。その意味では Dynamic Registration とかの動きにもすごく興味を持っています。

そして、Grant Management です。我々は Open Banking UK を参考にしてコンセントマネージメントを実装していて、その進化版と言っていいのか、似て非なるものですが、 Grant Management が導入されるところにも、いま興味を持っています。

あとは認可リクエストに詳細情報を埋め込む、Rich Authorization Requests です。ここもコンセントマネージメントと親戚みたいなところがあります。そこらへんも、我々が BaaS API をバージョン 1 からバージョン 2 とし、同時に FAPI2 に対応するときに、どうマイグレートしていこうかな、アップデートしていこうかな、というところに興味を持っています。

全体として、FAPI2 の大きな傾向、FAPI1 との大きな違いは、 クライアントフレンドリーな方向にある、という印象です。進化し続けているなと思います。

わたしからの発表は以上になります。ありがとうございました。