KeycloakへのContributionについて(2019年版)

日立製作所　中村雄一

筆者のチームでは、Keycloakへ様々なパッチを投稿していることもあり、本記事では、Keycloakへのパッチ投稿についての豆知識を紹介します。Keycloakは、Red Hat社によって元々開発されており、[メンテナ一覧] (https://github.com/keycloak/keycloak/blob/master/MAINTAINERS.md)を見ても、メンテナは全員Red Hat社の方々です(2019/12/20現在)。外部の人間が開発に携わるのはハードルが高そうですが、一定のルールを理解すれば門戸は広く開いています。ルールについてのおさらいと、また、実例からどうパッチがマージされていくのかを紹介します。これからKeycloakへパッチ投稿をしてみたい方の参考になればと思います。


#パッチ投稿の流れ
　[こちらのファイル](https://github.com/keycloak/keycloak/blob/master/GOVERNANCE.md)に記載されている通りです。
　小さな修正は、Issueを[JIRA](https://issues.redhat.com/projects/KEYCLOAK/issues)に登録し、[GitHubのリポジトリ](https://github.com/keycloak/keycloak/)にPull Requestを出します。
　大きな修正については、[Developerメーリングリスト](https://groups.google.com/forum/#!forum/keycloak-dev)で議論、その後Githubの[keycloak-communityリポジトリ](https://github.com/keycloak/keycloak-community/tree/master/design)にdesign proposalを出してさらに議論します。
　ですが、何が小さな修正で、何が大きな修正なのか、そして受け入れられやすい修正は何なのかは、グレーゾーンでケースバイケースです。実例を元にいくつか紹介します。
　筆者のチームでのパッチ投稿は、大きく分けると、「バグフィックス」「標準仕様への対応」「標準にない機能追加」の3種類です。それぞれ事例を紹介します。

#バグフィックス
　バグフィックスは、最も始めやすい領域です。メンテナの方も、Developerメーリングリストにて、初めての貢献としては[バグフィックスを推奨しています](https://groups.google.com/d/msg/keycloak-dev/twpmnu68e58/NS4kgYweCAAJ)。 筆者のチームの[@y-tabata](https://github.com/y-tabata)が出したパッチをベースに事例を紹介します。KeycloakはOAuth2.0に対応した認可サーバですが、例外系のレスポンスにて、いくつか標準での記載と異なることを発見し、Pull Requestを出しました（表）。

|Pull Request|概要|
|--:|--:|
|[KEYCLOAK-12019 Change error response from unsupported_response_type t…] (https://github.com/keycloak/keycloak/pull/6487)| RFC6749の4.1.2.1. Error Responseに厳密に従ったエラー返却する修正|
|[KEYCLOAK-12149 change error response from invalid_grant to unauthoriz…](https://github.com/keycloak/keycloak/pull/6506)|RFC6749の5.2. Error Responseに厳密に従ったエラー返却する修正|
|[KEYCLOAK-12150 change error response from invalid_request to unsuppor…](https://github.com/keycloak/keycloak/pull/6507)|RFC6749の5.2. Error Responseに厳密に従ったエラー返却する修正| 

　このような「標準に書いてあることとは違う」というのは、比較的簡単にバグとして認められ、すんなりとマージまで至ることが多いです。
 　一方で、一般的なバグ、については、バグとして認定されなかったり、議論になることがあります。ここで、メンテナ側が気にするポイントは、「既存の動作に影響を与えないか」につきます。ここはかなり細かくチェックされます。
　例えば、[KEYCLOAK-12094 Change to remove client sessions when the client deleted](https://github.com/keycloak/keycloak/pull/6554)というパッチは、クライアントが消された際にゴミが残っている問題を解決するパッチです。しかし、本パッチが入ることで、ネットワークに送出されるメッセージが増大する可能性を指摘されました。幸いに、解決方法をメンテナが示唆してくれたので、簡単に修正できましたが、案外苦労することがあります。

#標準仕様への対応
　過去の記事でも紹介しましたように、[Financial-Grade API](https://qiita.com/yuichi-nakamura/items/53b35a9cbaf663fab441)や[WebAuthn](https://qiita.com/tnorimat/items/6d5b055292f2d65427bd)への対応を進めています。これらのパッチは基本的には、機能追加とみなされ、developerメーリングリストでの議論が必要なことが多いです。ただし、design documentの提出まで求められたケースは1件のみです。

#標準にない機能追加
こちらが実は最も大変です。標準にない機能の追加ですので、機能を必要性が分かってもらえないと相手にしてもらえません。一つ事例を紹介します。
　Keycloakのリフレッシュトークンの有効期限については、同一レルム内では全て一つにしか設定できません(8.0.0現在)。つまり、クライアントが複数あって、クライアント毎に有効期限を変えようとすると、レルムを複数用意する必要があり煩雑です。これらの問題を解決するために、同一レルム内であっても、クライアント毎にリフレッシュトークンの有効期限を変えることができるパッチ投稿を[@y-tabata](https://github.com/y-tabata)が始めました。
　
##最初のパッチ投稿
2019年9月に「[KEYCLOAK-10907 Add configurable token settings per client](https://github.com/keycloak/keycloak/pull/6309)」という形でパッチ投稿しました。メーリングリストにも[投稿し](https://lists.jboss.org/pipermail/keycloak-dev/2019-September/012530.html)、ユースケースや利点を説明しました。しかしながら、ユースケースを理解して頂けず、必死の説得も空しく、Pull Requestはメンテナに却下されてしまいました。

##二度目のパッチ投稿
　しかし、11月になり突如Developerメーリングリストに、却下の判断を下したメンテナより、先日投稿したパッチを包含する機能をもつ機能が欲しいと[投稿がありました](https://lists.jboss.org/pipermail/keycloak-dev/2019-November/012824.html)。これはチャンスとばかりに、議論に参加しました。結果、どうやら作りたいという意思のみで、実際の開発がもう少し先になるということが分かりましたので、再度パッチ投稿にチャレンジすることにしました。
　12月になり「[KEYCLOAK-12406 Add "Client Session Max" and "Client Session Idle" for…](https://github.com/keycloak/keycloak/pull/6581)」という形で、メンテナの意図に沿うよう実装も見直しパッチを再投稿しました。今度は必要性は理解されている状態であったため、すぐにレビューも始まり、好意的な反応もあり、「prioritize」フラグがつき、2019/12/20現在、前向きにレビュー中となっています（下図、[Pull Request一覧](https://github.com/keycloak/keycloak/pulls)より抜粋）

　![prioritize.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267380/e018e49b-4409-2751-3a5a-4ebb9205abcc.png)
 
　ここで、「prioritize」フラグとは、メンテナ側が優先的にレビューすることを示すフラグです。昨今KeycloakへのPull Requestが増えており、なかなかレビューが進まないことがあります。そんな中、このフラグがつくと、どんどんレビューが進むことが多いことから、パッチ投稿側としては、非常に嬉しい状態です。記事執筆現在、パッチがマージされることを一同祈っている状態です。

　このように、標準外の機能追加は苦労することが多いです。しかしながら、標準外の部分をしっかりと作りこむことが、使い勝手や信頼性を左右することも多いと思いますので、チャレンジしていきたいものです。