OAuth Identity and Authorization Chaining Across Domains のドラフトを読んでみた
OAuth 2.0 のドラフト「OAuth Identity and Authorization Chaining Across Domains」をざっと読んでみました。
- draft-ietf-oauth-identity-chaining-06
“Identity and Authorization Chaining” と目に入って「なんだなんだ?」と思ったのですが。やりたいことはシンプルで、「ドメインまたいでもコンテキストをなるべく保ったままアクセストークンを(Token Exchangeで)取得したい」という話でした。
読み進めると、最近よく話題に上がる ID-JAG のベースになるドラフトだと分かりました。まだ Cross-App Access (XAA) 自体は読めていませんが、こちらにも関わる仕様のようです。XAA を理解したかったので、ここでは勉強した内容をメモ的に残しておきます。いまのところ、XAA を実現する仕様が ID-JAG という理解です。
このドラフトが解きたい課題
アプリケーションは、複数の信頼ドメインに分散したリソースへアクセスすることがよくあります。各信頼ドメインはそれぞれ Authorization Server を持ち、1つのリクエストが完了するまでに、異なるドメインに属する複数の Resource Server を経由することもあります。
このとき、リクエストに関わる保護リソース側は少なくとも次を知る必要があります。
- そのリクエストは元々「誰の代理で」開始されたのか(つまりユーザー)
- どのような認可が与えられていたのか
- (必要なら)認可判断を行う前に、他にどの Resource Server が呼ばれていたのか
問題は、リクエストが1つ以上の信頼ドメイン境界を越えると、この手の情報が引き継がれにくいことです。このドラフトは、こうした情報をドメイン間でも保つ仕組みを “chaining” と呼び、共通パターンとして定義しようとしています。Token Exchange(RFC 8693)と JWT 認可グラント(RFC 7523)を組み合わせ、複数の信頼ドメインを横断しても、元のユーザーと認可の文脈をなるべく失わずにリソースへアクセスできるようにします。
どういう仕組みで chaining するのか
Token Exchange(RFC 8693)と JWT 認可グラント(RFC 7523)を組み合わせるアプローチです。
全体はこんな感じ:
- ドメインAのクライアントが、まずドメインBのASを発見する
- ドメインAのASに対して Token Exchange をして、ドメインB向けのJWT認可グラントをもらう
- そのJWT認可グラントを、ドメインBのASに assertion として提示し、ドメインBのATをもらう
- そのATで、ドメインBのRSを呼ぶ
ざっくり言い換えちゃうと以下みたいな感じかと。
- Aで「B向けに通用する紹介状(JWT認可グラント)」を発行してもらい
- Bで「その紹介状を検証してATを出す」
Claims transcription
Claims transcription は、信頼境界をまたいで「ユーザーやクライアントの識別子」「認可コンテキスト」「その他の関連情報」を伝えるための仕組みです。これにより、関係する各主体は少なくとも次を判断できるようになります。
- そのリクエストが誰の代理で行われているのか
- どのような認可が与えられているのか
- (場合によっては)以前にどのRSが関与していたのか
AS は、次のどちらのタイミングでも claims を transcription してよいとされています。
- Token Exchange フローで JWT認可グラント を生成するとき
- assertion フローで AT を生成するとき
原文では、claims transcription が必要になり得る理由として、次の4つが挙げられています。
- subject 識別子の転記(ドメイン間でID表現が違うので載せ替えが必要)
- データ最小化(プライバシーや信頼度の都合で不要なclaimを落とす/隠す)
- scope の制御(downscoping用途。要求scopeが
subject_tokenより強くならないよう検証する) - JWT認可グラントのclaimの利用(ドメインBのASが提示されたclaimをATに反映してよいが、インジェクション対策として名前空間化や検証が必要)
ユースケース
このドラフト、本文だけ読むと「なるほどパターンは分かった」で終わりがちなんですが、Appendixが手厚く、読み応えがありました。具体的にどこで嬉しくなるのかがわかりやすかったです。
ユースケースが網羅的ではないと言いつつ、結構しっかり書いてある印象です。読んだ内容はまさにID-JAGって感じでした。
- A.1 マルチクラウド/マルチハイブリッド環境でユーザー文脈を保持
- オンプレ+クラウド、さらに複数の信頼境界で分断されている状況で、ワークロード同士が別ドメインのサービスを呼び出す
- そのときも「元ユーザー」や「中継サービス」の文脈を維持して、認可判断に使いたい
- A.2 CIが外部リソースへアクセス
- artifactアップロードやテスト実行などで外部リソースにアクセスする
- 「ビルドのアイデンティティ情報(コミットやリポジトリ等)」も越境させたい
- A.3 API Security(Camera APIの例)
- パートナー連携でカメラ映像をダッシュボードに統合する、みたいな場合
- 提供側が「このリクエストは正当なユーザーにより認可された」と独立に検証したい
- A.4 SSOをAPIアクセスまで拡張
- 企業IdPにログイン済みなら、対話的なOAuthフローを毎回やらずにAPIアクセスもしたい
- IdPから得た identity assertion(ID Token / SAML Assertion)を材料に、JWT認可グラントへ交換してSaaS側(ドメインB側)のATを得る
- A.5 クロスドメインのAPI認可(メール+カレンダーの例)
- メールクライアントがIdPから identity assertion を取り、別ドメインのカレンダーAPIにアクセスする。
- 信頼関係があるなら追加のユーザー操作なしにtokenを取得する
読んだ感想
- ドメインを跨ぐ時に必要なATをどう取得するのかベースの仕様が提示されたドキュメント
- 内容はシンプルで読みやすかったです。
- そして Token Exchage とはとても汎用的な仕組みだなと感心してます。
- これが Cross-App Access (XAA) に繋がっていると思うと、昨今の「IdP でぜんぶ管理したい」という OAuth とか OIDC の潮流のようなものを感じました
- IPSIE とか完全にそっちの流れという理解です
- https://zenn.dev/ksakiyama/articles/6c3f7dc3c5ef71
Discussion