GNAP超入門 ~ OAuth 2.0との違いとは

こんばんは、ritouです。

この記事はDigital Identity技術勉強会 #iddance のアドベントカレンダー 初日の記事です。 今年も張り切っていきましょう。

qiita.com

さて先日、Internet Week 2021なるもののために GNAP についてお話する機会がございました。

speakerdeck.com

45分間で各自が話す持ち時間は10分のためさわりだけしかお話しできませんでしたが、資料を見てもなんのことやらって感じだと思うのでここでもう一回説明してみます。

f:id:ritou:20211201131746j:plain

f:id:ritou:20211130105239j:plain

Grant Negotiation and Authorization Protocol 通称GNAP(読み方はなっぷとかぐなっぷとかじーなっぷとか、人によって呼び方がフリーダムなID界隈の謎しぐさ)ですが、OAuth 2.0のこれまでの経験と知識を踏まえて新しい権限移譲のプロトコルを作っていこうという取り組みです。

現在策定中の仕様はコアプロトコルとリソースサーバーの2つです。

f:id:ritou:20211130105304j:plain

  • コアプロトコル : 権限委譲を行うところまで
  • リソースサーバー : リソースサーバーが認可サーバーとどうやりとりしてリソースアクセスを提供できるか

これだけ見るとRFC6749の仕様を分解したように見えますが、実際のコアプロトコルの仕様にはいろんなことがいっぱい書いてあります(雑)

www.ietf.org

今回は現時点のGNAP概要とOAuth 2.0との違いにフォーカスしつつ、概要を紹介します。

f:id:ritou:20211130105313j:plain

最初のIntroductionのあたりです。

f:id:ritou:20211130105324j:plain

最初に何が書いてあるかというと、このプロトコルはいわゆるClientインスタンス(OAuth 2.0でいうところのClientですね)がAuthorization Serverに対してアクセス要求をどう行い、必要な対話を行い、目的とする情報へのアクセス権限をえるところにフォーカスしていますということです。また、インターオペラビリティについても言及があります。

f:id:ritou:20211130105335j:plain

GNAPにおけるRole、いわゆる登場人物を紹介します。ほとんどOAuth 2.0と同じ用語になっていますが、最後のEndUserっていうのがClientを操作する人物のことです。

OAuth 2.0のAuthorization Code Grantのあたりでは、暗黙的にこのEndUserとROが同一人物である想定になっています。 GNAPでは色々なユースケースを想定している中で、これが別の人物になる可能性も考慮しています。 既存のものだと、CIBAとかを想像してみてください。CIBAのConsumption Deviceを操作する人物についてはあまり意識しないかもしれませんが、必ずしも人間ではない場合もありますし、OIDCにおけるEndUserと一致する必要もありません。

f:id:ritou:20211130105344j:plain

GNAPがさまざまなユースケースで使われていくにあたり、Role間のTrustrelationshipが重要になります。 先ほど言ったようにクライアントを操作する人物とアクセスしたいリソースのオーナーが異なる場合はいわゆるUser ManagedAccess、通称ウーマと呼ばれる仕組みのユースケースに近くなるでしょう。業務システムの承認フローみたいなのにも適用できそうです。

その他にもRole間の関係性がプロトコルのどの部分に関連するかが言及されていますので、興味のある方は仕様を読んでみてください。

f:id:ritou:20211130114915j:plain

シーケンスの説明のところで、いくつかフローがあります。

  • Redirect-based Interaction : ブラウザのリダイレクトを利用してROとインタラクションを行う、OAuth 2.0のAuthorization Code Grantのようなフロー
  • User-code Interaction : ユーザーコードを利用する、OAuth 2.0のDevice Authorization Grantのようなフロー
  • Asynchronous Authorization : EndUserとROが別で、処理が分かれて行われるOIDC CIBAのようなフロー
  • Software-only Authorization : ROとの対話が存在しない、OAuth 2.0のClient Credentials Grant のようなフロー
  • Refreshing an Expired Access Token : 期限切れのアクセストークンを更新する、OAuth 2.0の Refresh Token を用いた Access Token 再取得のようなフロー
  • Requesting User Information : RSへのアクセスを要求せず、ROの情報を要求する、OIDCのようなフロー

OAuth 2.0では RFC6749 でいくつかのGrantTypeが定義され、Authorization Code Grantは認可エンドポイントへのリダイレクトによりROとのインタラクションが行われます。それ以外にROとのインタラクションを要求するDevice AuthZ Grant や OIDC CIBA などは新規のエンドポイントへのリクエスト/レスポンスが定義されたりします。ClientはASが提供するフローのうち、自分の使いたいものを選択して実装する必要があります。

GNAPのシーケンスでは、様々なユースケースに対応されている中で、最初にClientからASにアクセス要求を行う部分は共通になっています。 その時に、Clientは自分が対応しているインタラクションを提示します。ASはアクセス要求の内容を検証し、必要なインタラクションをClientに応答することでその後のROとのインタラクションに誘導します。 ブラウザのリダイレクトが行われるのか、デバイスフローのような遷移が行われるか、CIBAのようなpush経由の同意が行われるのか、ROとのrインタラクションなしで処理が続けられるのかが分岐していくわけです。

f:id:ritou:20211130114926j:plain

最後にOAuth 2.0との関係を紹介します。プロトコルレベルでの互換性はありませんが、先ほど紹介した通り、OAuth 2.0/OIDCで提案されているユースケースは想定されていますし、OAuth 2.0では解決できない、複雑になってしまうようなところも拾っていくような感じです。

仕様内でも付録にOAuth 2.0との違いが記載されております。Appendix B. Compared to OAuth 2.0" です。

f:id:ritou:20211130114937j:plain

ここでは6つの観点から整理されています。

  • Consent and authorization flexibility: OAuth 2.0(RFC6749)はブラウザでのインタラクションが定義されていますが、GNAPではDevice AuthZ GrantやOIDC CIBAのようなインタラクションまでサポートしています。
  • Intent registration and inline negotiation: これはシーケンスのところでも説明したように共通のアクセス要求から始まって、そこでネゴシエーションが行われるよってところです。
  • Client instances: OAuth 2.0において、ClientにはClientIDが割り当てられますが、GNAPはClientからASに提示された鍵の情報をうまく使います。
  • Expanded delegation: OAuth 2.0のscopeがresourceやRARという概念で拡張されていますが、GNAPは最初からRARのような柔軟な表現が使われています。
  • Cryptography-based security: OAuth 2.0ではClientSecretというBearer Secretがいろんなところで使われていますがFAPIなどでは別の方法が必要になります。GNAPではClientが保持する鍵を用いた暗号ベースの保護を利用します。
  • Privacy and usable security: OAuth 2.0はAS-RSの強力な紐付けが前提となっていますが、GNAPでは色々なパターンでAS/RSがやり取りできるように考えられています。

ざっとこんな違いが書かれています。

f:id:ritou:20211130114947j:plain

GNAPの最新情報はIETFのWG、ML、Githubを参照指定いただければと思います。

今回は超入門として、OAuth 2.0とGNAPの設計思想の違いを紹介しました。 この辺りを先に意識した上でGNAPのプロトコルの詳細を見ていくことで今までよりも読んでいくハードルを下げられるのかなと思ったりします。 今回な具体的なリクエスト/レスポンスには触れませんでしたが、続きの形でOAuth2.0と比べながら細かく見ていく記事も書こうと思っています。

また、まだまだ使われ続けるOAuth 2.0の各種フローをそのまま覚えるのでなくROとのインタラクション、トークン発行、クライアントとの紐付けやクライアント認証といった部分を細かいパーツに分けて理解し、GNAPはそれを組み替え直したようなものだと捉えられるようになったらもうこの辺の新しい仕様も怖くなくなります。これからも頑張りましょう。

明日のアドカレはAuthleteのあの人が記事を書いてくれそうです。楽しみですね! 私は今のところ、最終日に何かを書く予定です。 ではまた。