3. Financial-grade API

このビデオについて

このビデオは、2020 年 1 月 31 日に開催した弊社勉強会プレゼンテーション録画のパート 3 です。 Financial-grade API (FAPI) について、Request Object / Hybrid Flow / JARM を中心に、 Authlete の工藤達雄が紹介します。

文字起こし(ログを元に再構成)

Financial-grade API (FAPI) の概要

工藤: そうか、もう 4 年近く経つんですね。 (FAPI は)金融系でけっこう API で OAuth が使われてきたので、ちゃんと標準化しましょうというところで出てきたものです。

去年か一昨年くらいから、イギリスとか、あとは最近オーストラリアの Consumer Data Right という動きとかで、 FAPI を使ってセキュリティプロファイルを作る、あるいは英国なんかだと、そもそも自分で作っていたセキュリティプロファイルを捨てて FAPI ベースでやる、 という動きになってきています。

そのセキュリティプロファイルとはなんぞやというところなんですが、 これは非公式な、ぼくが、こういうことなのかなと描いて出しているやつなんですけど、 パート 1、パート 2 ってのがあってですね。 パート 1 は、変わるかもしれないけどいまの名前は Read Only、 パート 2 っていうのは Read and Write。 いわゆる参照系と更新系みたいな分けかたです。

パート 1 のほうは、基本的には OAuth2 の世界でできることが書いてある。 さっきのセキュリティ BCP に入っている内容、プラス、OAuth の拡張仕様でできる部分、っていうのがパート 1。

パート 2 はもうちょっと OpenID Connect を使ってできる部分を入れていったもので、 かつ、OpenID Connect だけではまだできなかった点についても、 OpenID Connect として拡張仕様を定義して使っていく、というものになっています。

いくつかポイントはあるんですけど、この黄色くなっていない部分は、さっきあった Security BCP で大体できているんですね。 黄色い部分、このリダイレクトの部分でリクエスト / レスポンスをどうやって保護するかっていうのは、 さっきの OAuth 2.0 BCP の中には入ってないんですよ。

ここどうするかで、たとえば Request Object っていうものとか、あるいは Hybrid Flow もしくは JARM を使う、と書いてあります。

Request Object

それぞれお話ししていくと、まず Request Object のところですね。

これは何をするかというと、 認可リクエスト、OpenID Connect の世界だと認証リクエストですけど、 認可リクエストって言っちゃいますけど、この部分をどうやって保護するか、 いろいろ、scope だとか state だとか response_type だとか、そういったものをですね、Key / Value にして JSON にして、 これを Signed JWT にするなり、JWE で暗号化して、リダイレクトに載せる、認可リクエストに載せる、っていうものになります。

その載せかたとして、これを単純に値、request=eyJ なんたらかんたら、っていうように送ることもできますし、 これをどこかに POST してですね、ロケーションをもらって、そのロケーションを request_uri というかたちでセットしてやりとりする、という方法もあります。

Hybrid Flow

次に、戻り(認可レスポンス)なんですけど、ここで出てくるのは 2 つあって、ひとつは Hybrid Flow です。

これは何をするかっていうと、 認可リクエストの部分はあまり重要ではなくて、 こういう response_type が入っていたら Hybrid Flow のフラグが立って、そのあとそういう処理をするものです。

このあとまず認可レスポンスを作る前に、認可サーバーが、これから送る内容については認可レスポンスのところに ID トークンというものをつけて送る、 というかたちになります。

その ID トークンと一緒に認可コードを送って、(クライアントが)Detached Signature の検証を行なって、 そのあとクライアントのほうで、その検証が通った場合には初めてこの認可コードを、改ざんされていない すり替わっていないと(判断します)。

あるいは state が入っていたら、その state(の値)は確かだということを判断して、トークンリクエストにその認可コードを使う、という流れになっていきます。

Detached Signature って何かというと、 ちょっとややこしいんですけど、 はじめに受け取った認可リクエストに沿った値の中に、まず state が入っているはずなんですね。 FAPIだと、(stateを)入れなさいってなってるので、入っていると。 そして(認可リクエスト処理の結果としての)code があると。

それをもとにハッシュを作って、(その)一部をとって、それを Key / Value にして、ID トークンに埋め込む。 埋め込んで、認可サーバーとして署名をかける。 それを、認可レスポンスで返す、と

受け取ったクライアントは、 まずこの JWT についている署名を検証して、認可サーバーのものだということがわかれば、 その中に入っている「state のハッシュの一部 (s_hash)」「code のハッシュの一部 (c_hash)」を取り出して、 その値と、いまパラメーターとしてついてきた codestate というものを照合して、 一致すれば、つまりこのやりとりにおいて、これがすり替わっていない、そして ID トークンがおかしくないということがわかれば、この値を初めて使って、とくに code のほうを使って トークンリクエストを行うと。ひいてはアクセストークンがもらえる、というようになっていきます。

JARM

(Hybrid Flow は)けっこう難しいというか、とくにこのへん(認可レスポンス処理)が、ちょっとややこしいですよね。

かつ、これができるのが、ID トークンを使ったときだけなんですよね。 オープンバンキングとかの世界だと、アイデンティティは要らない、ユーザー識別子は別に送ってくれるな、 逆に送られるとプライバシー的に嫌なんだということがあって、 それを使わない方法がほしいということで出てきたのが JARM です。

これはもっとすっきりしていて、ここで送る認可レスポンスも、認可リクエストと同じように、 署名付きの JWT を使って、そのまま送ってやると。

その値 (JWT) をクライアントが検証して、問題がなければこの中から code を取り出して、トークンリクエストに回す、ていうかたちになります。

いまはこういうことをやりたい場合に、Hybrid Flow でやるべきか、JARM でやるべきか、どっちですかって言われたら、 JARM でいいんじゃないですか、と言うかなという気がします。

FAPI の策定状況

FAPI のほうなんですけど、大まかにいうともっと細かいのがいろいろあると思うんですけど、こういうところ(状態)で、 これが決まっているのが、いま Implementer’s Draft、実装者向けドラフトの、Second Draft、第 2 版というものなんですね

実は第 2 版が一昨年に出て、それからちょっと変わってきていてですね、意外と知られていないので、 このあたりは興味のある方向けというご参考情報なんですけど。

たとえば Token Binding が、仕様がアップデートされる見込みが無いので、drop したとか。

code id_tokencode id_token token っていう response_typeが OK だったんですけど、 これはもう使わないよねということでNG、使うな、になったと。

LoA 3、この(第 2 版の)FAPI のパート 2 だと LoA3 は必須と書いてあったんですけど、 そこはデプロイメントに任せようやみたいな空気が出てきて、そういう縛りがなくなって。

4 点目、public client のサポートも、Request Object への署名が必須なところ、それができない、 キーペアを作るのができないので、外されたということになります。 あとたぶん、英国で Open Banking を進めていて、その要件が前からそうだったんですけどけっこう入ってきていて、 その UK のほうでは public client は初めから禁止なんですよね。 なので、それを逆に FAPI のほうに押し込んだのはあるかな、という気はします。

この仕様で一緒になっていた、Pushed Request Object を(仕様として)分けたりとか、 あと JARM がちょっとおまけみたいな感じでかかれていたのが、 Hybrid Flow と並列で書かれるようになったりとか。

あとは追加された内容としては、 exp、expireっていう値が Request Object にあって、 いままで決まってなかったんですけど、これは 60 分って決まっている感じです。

以上が FAPI になります。

4. Lodging Intent Pattern に続きます