KeycloakのFAPI(Financial-grade API)対応について

日立製作所　中村雄一

OpenID Foundationで策定が進むプロファイルである「[Financial-grade API(FAPI)](https://openid.net/wg/fapi/)」へのKeycloakの対応のための開発を筆者のチームで進めています。現在のKeycloakのFAPI対応状況を紹介します。

# FAPIとは
　まずは、FAPIが登場した背景を説明します（図）。APIの認可・認証にOAuth 2.0 (RFC6749)が使われています。しかし、OAuth 2.0そのものは、「アクセストークン」をどのようにやり取りするかの枠組みが定められているだけであり、多くが実装者の自由に委ねられていました。その結果、セキュリティホールも作り込まれやすく、多くの問題が指摘されてきました。これに対して、OAuth2.0の中で各自勝手に「認証情報」をやり取りしていたものを標準化し、安全に認証情報をやり取りできるようにし、さらにOAuth 2.0の危険な使い方を縛った規格が「OpenID Connect (OIDC)」です。OIDCはOpenID Foundationにより標準化されています。加えて、OAuth 2.0/OIDCが金融分野のような高いセキュリティが求められるＡＰＩ向けに適用されるようになってきたことに伴い、周辺仕様含め金融分野を強く意識した安全な使い方を規定している仕様が「FAPI」となります。
<img width="470" alt="figure.png" src="https://qiita-image-store.s3.amazonaws.com/0/267380/57469935-e667-17e8-970c-215967300df8.png">


 FAPIもOIDCと同様にOpenID Foundationによって策定されています。2018/11/30時点では、Implementer’s draftであり、まだ正式な仕様ではありません。しかし、イギリスのOpenBankingで採用されたり、[全銀協のレポート](https://www.zenginkyo.or.jp/news/detail/nid/8261/)にも言及されるなど、金融分野では大きく注目されている仕様です。
 記事執筆現在、FAPIは、Part1(読み出し用APIのセキュリティ)、Part2(読み書きするAPIのセキュリティなど４つのパートから成り立っていますが、本記事では、Part1とPart2のみを対象とします。

# KeycloakのFAPI対応状況
 Keycloakは、OAuth2.0/OIDCに対応したOSSの認可サーバです。FAPIへの対応状況を紹介します。このような仕様への準拠状況を図る場合は、テストツールを利用するのが本来ですが、FAPIでは、テストツールがまだ整備されていないため、机上でのFIT&GAPを行い、筆者らのチームでコミュニティに非対応項目の報告を行いました。そして、日立の[@tnorimat](https://qiita.com/tnorimat)さんが中心となって対応のための開発が行われています。Part1, Part2のFIT&GAPを行った結果(2017年3月時点のKeycloak 3.0.0)と、現在(2018年11/22時点のKeycloak 4.7.0ソースツリー)の対応状況をまとめたものを下表に記します。

|非対応項目のJIRA|概要|Pull Request|対応バージョン|
|--:|--:|--:|--:|
|[KEYCLOAK-2604](https://issues.jboss.org/browse/KEYCLOAK-2604)|RFC7636(PKCE)サポート|[3831](https://github.com/keycloak/keycloak/pull/3831)|3.1.0|
|[KEYCLOAK-5661](https://issues.jboss.org/browse/KEYCLOAK-5661)|アクセストークンと一緒にscopeを返却|[4527](https://github.com/keycloak/keycloak/pull/4527)|3.4.0|
|[KEYCLOAK-5811](https://issues.jboss.org/browse/KEYCLOAK-5811)|client_secret_jwtでのクライアント認証対応|[4835](https://github.com/keycloak/keycloak/pull/4835)|4.0.0|
|[KEYCLOAK-6700](https://issues.jboss.org/browse/KEYCLOAK-6700)|stateパラメタ保護のためのs_hash|[5022](https://github.com/keycloak/keycloak/pull/5022)|4.0.0|
|[KEYCLOAK-6770](https://issues.jboss.org/browse/KEYCLOAK-6770),[KEYCLOAK-8460](https://issues.jboss.org/browse/KEYCLOAK-8460)|PS256またはES256署名アルゴリズム対応|[5533](https://github.com/keycloak/keycloak/pull/5533), [5603](https://github.com/keycloak/keycloak/pull/5603)|4.5.0,4.7.0|
|[KEYCLOAK-6771](https://issues.jboss.org/browse/KEYCLOAK-6771)|トークン所持者証明対応|[5083](https://github.com/keycloak/keycloak/pull/5083)|4.0.0|
|[KEYCLOAK-6768](https://issues.jboss.org/browse/KEYCLOAK-6768)|IDトークン暗号化対応|未|未|

## 主な機能の紹介
これらの中でも、FAPI対応以外にも役に立つ主な機能を少し紹介します。

### RFC7636(PKCE)対応
　Authorization code grantにおける、認可コード横取り攻撃の対策となる機能です。Keycloakでも3.1.0から採用されました。IETFにて検討が進んでいるOAuth 2.0の[ベストプラクティス](https://tools.ietf.org/id/draft-ietf-oauth-security-topics-09.html)でもPKCEの利用が推奨されるようになってきており、本機能の利用がますます増えていくことかと思います。KeycloakでのPKCEの詳細は、[@tnorimatさんの記事](https://qiita.com/tnorimat/items/e2dd3ecd36f192fca5ba
)に詳しいです。

### トークン所持者証明対応
　OAuth 2.0のアクセストークンは、基本的には「ベアラトークン」という考え方です。つまり「アクセストークンを持っている人を信じる」考え方ですので、アクセストークンの第三者により利用されてしまう可能性を捨てきれません。これに対して、クライアントのみが保有する秘密の情報とアクセストークンを結びつけることで、第三者による更新を困難化するための技術が「トークン所持者証明」です。Keycloakの4.0.0から、「OAuth 2 Certificate Bound Access Tokens」という名称の機能として採用されました。こちらの詳細は、下記記事に詳しいです。
[OAuth 2.0でのHolder-of-Key TokenとKeycloakについて]
(https://qiita.com/tnorimat/items/ee45d2cb08d799a7d4a6)

### PS256またはES256署名対応
　Keycloakでは、トークン類に署名をしていますが、その署名アルゴリズムが「RS256」というアルゴリズムにしか対応していませんでした。RS256は、暗号専門家の間では脆弱だと言われており、FAPIでは、PS256またはES256のようなより強固なアルゴリズムの利用が求められています。しかし、Keycloakでは、「RS256の利用」がハードコードされてしまっており、他のアルゴリズムへの対応は容易ではありませんでした。そこで、ハードコードを取り除くためのリファクタリングが行われ、署名アルゴリズム・鍵管理方式をプラグイン形式で実装できるようになりました(Token Signature SPI)。その結果、Keycloak 4.7.0では、ES256等の署名アルゴリズムに対応できるようになっています。

# 今後について
 主な項目として、IDトークンの暗号化対応が残されていますが、順次整備が進んでいくと思われます。また、FAPIのテストツールが開発された暁には、テストツールをパスする動きも必要になってくるでしょう。FAPIのテストツールは[こちら](https://gitlab.com/fintechlabs/fapi-conformance-suite)で開発が進んでいるようで、要ウォッチです。