Selective Disclosure for JWTs (SD-JWT)

issuer が claim を salt 付きハッシュに置き換えた JWT に署名し、holder は後で verifier が必要とする claim だけを開示する。任意で、束縛された鍵を持っていることも証明できる。

現在地
RFC として公開済み
公式本文
RFC 9901
公式に文書化された対応
0
動き
6 件の動き (90 日)

RFC を英日対訳で読む解説の元ファイル (GitHub)

どういうときに使うか

  • credential を一度発行して何度も提示する: 多くの claim を持つ JWT が holder に渡り、各 verifier は求めた disclosure だけを受け取る。issuer の署名はそのまま検証できる (Section 1、3.1、3.2)。
  • 提示者が正当な holder であることを verifier が確かめたい: issuer が holder の公開鍵を cnf に入れ、holder は nonce と verifier を指す aud を含む Key Binding JWT で提示に署名する (Section 3.3、4.1.2、4.3)。
  • credential が隠している claim の数を verifier に知られたくない: decoy digest で _sd 配列を水増しし、本物の claim の数を見えなくする (Section 4.2.5、10.4)。
  • credential が verifier をまたぐ追跡トークンになってはいけない: unlinkability は credential ごとの新しい salt と Key Binding 鍵にかかっており、batch issuance で holder は verifier ごとに別の credential を使える (Section 10.1)。
図
flowchart LR
    A["issuer がユーザーの全 claim を含む JWT に署名して holder に渡す"] -->|"普通の JWT を verifier に提示"| B["全 claim が見える。一部を削ると署名が壊れる"]
    A -->|"SD-JWT: claim を salt 付き digest に置き換え、disclosure は別に運ぶ"| C["holder は issuer 署名付き JWT と verifier が必要とする disclosure だけ、任意で KB-JWT を送る"]

解決する問題

JWT は全体に署名されるので、名前と住所も入った credential から生年月日だけを verifier に見せたい holder には、悪い選択肢が 2 つしかない。全部見せるか、issuer に新しいトークンをもらいに戻るかだ。SD-JWT は salted hash の上に作られている。issuer は選択的に開示できる各 claim の digest を署名付きペイロードに入れ、claim の実際の salt・名前・値は別の Disclosure で運ぶ (Section 1、3.1)。Disclosure は署名を壊さずに省略でき、改変は検出できる (Section 3.1)。

仕様は 2 つの形式を定める。SD-JWT は Issuer-signed JWT と 0 個以上の Disclosure。SD-JWT+KB はそれに Key Binding JWT を足したもので、verifier は提示者が issuer が credential に束縛した鍵を制御していることを確かめられる (Section 1.1)。

仕組み

図
flowchart TB
    SD["SD-JWT+KB = Issuer-signed JWT ~ Disclosure 1 ~ ... ~ Disclosure N ~ KB-JWT"]
    SD --> I["Issuer-signed JWT: digest の _sd 配列、_sd_alg、holder 鍵を持つ cnf、常に見える claim"]
    SD --> D["Disclosure: salt、claim 名、claim 値 の base64url"]
    SD --> K["KB-JWT: typ kb+jwt、iat、aud、nonce、sd_hash、holder 鍵で署名"]
    D -->|"Disclosure の US-ASCII バイト列のハッシュ"| I
    K -->|"Issuer-signed JWT ~ 選んだ Disclosure ~ に対する sd_hash"| SD

Issuer-signed JWT は issuer の秘密鍵で署名しなければならない (Section 4.1)。選択的に開示できる object property ごとに issuer は Disclosure を作る。salt・claim 名・claim 値の JSON 配列を base64url にしたもので、配列要素の場合は salt と値の 2 要素配列になる (Section 4.2.1、4.2.2)。digest は base64url 化した Disclosure の US-ASCII バイト列に対して計算し (Section 4.2.3)、_sd 配列に入れる。issuer はその順序を隠さなければならない (Section 4.2.4.1)。_sd_alg は Named Information Hash Algorithm Registry のハッシュアルゴリズム名で、既定は sha-256 (Section 4.1.1)。holder の公開鍵かその参照は cnf に入る (Section 4.1.2)。compact 形式はすべてを ~ で連結し、素の SD-JWT は末尾の ~ で終わる。これで 2 つの形式を見分ける (Section 4)。KB-JWT は typ に kb+jwt を持ち、必須 claim は iat、aud、nonce、sd_hash。sd_hash は Disclosure と同じアルゴリズムで、Issuer-signed JWT と選んだ Disclosure に対して計算した digest だ (Section 4.3、4.3.1)。

仕様が求めること

  • salt は選択的に開示する claim ごとに一意でなければならず (MUST)、claim 名は _sd、...、または同じ object に常時開示の claim として既にある名前であってはならない (MUST NOT) (Section 4.2.1)。
  • トップレベルに _sd_alg がなければ sha-256 を使わなければならない (MUST) (Section 4.1.1)。
  • SD-JWT を処理する holder と verifier は、同じ digest 値が 2 回以上現れたら、あるいは digest から参照されない Disclosure があったら、拒否しなければならない (MUST)。対応する Disclosure のない digest は無視しなければならない (MUST)。処理後のペイロードで nbf、exp、aud を確認する (Section 7.1)。
  • holder は SD-JWT+KB を受け取ったら拒否しなければならない (MUST) (Section 7.2)。
  • verifier は検証の前に Key Binding が必要かを決めなければならず (MUST)、その判断は holder が KB-JWT を出したかどうかに依存してはならない (MUST NOT)。必要なのに無ければ提示を拒否しなければならない (MUST)。KB-JWT は holder の鍵で検証し、none は受け付けてはならず (MUST NOT)、typ が kb+jwt、iat が許容範囲内、nonce と aud が妥当、sd_hash を再計算して一致することを確認する (Section 7.3、9.5)。
  • JWS JSON Serialization 形式のサポートは任意 (OPTIONAL) (Section 8)。

注意点

  • JWT は issuer が署名しなければならず (MUST)、verifier は Disclosure を検査して claim の値が正しいことを確かめなければならない (MUST) (Section 9.1、9.2)。
  • 各 salt は暗号学的に乱数で十分長くなければならない (MUST)。推奨される最小値は乱数部分 128 bit で、ハッシュ関数は第二原像計算困難でなければならない (MUST) (Section 9.3、9.4)。
  • issuer は、credential の有効性評価に不可欠な内容を選択的開示の対象にしてはならない (MUST NOT) (Section 9.7)。
  • Key Binding がなければ、SD-JWT を持つ誰でも Key Binding を強制しない第三者に転送でき、Disclosure の追加や削除で SD-JWT を改変しても有効なままになる (Section 9.9、9.10)。
  • application profile は、Issuer-signed JWT に application/example+sd-jwt 形式の media type で明示的な typ を設定することが推奨される (RECOMMENDED) (Section 9.11)。
  • 仕様は機密性を提供しない。ユーザーデータのプライバシーや受動的な観測者による相関が懸念されるなら、実装者はトランスポートが機密性を提供することを保証しなければならない (MUST)。batch の各 credential には新しい Key Binding 鍵と salt を使わなければならない (MUST) (Section 10.1、10.3)。

出典

他の仕様との関係

関係図
flowchart LR
  s_sd_jwt["Selective Disclosure for JWTs"]
  s_jwt["JSON Web Token"]
  s_sd_jwt_vc["SD-JWT-based Verifiable Credentials"]
  s_delegate_sd_jwt["Delegate SD-JWT"]
  style s_sd_jwt stroke-width:3px
  s_sd_jwt -->|土台とする仕様| s_jwt
  s_sd_jwt_vc -->|プロファイル対象| s_sd_jwt
  s_delegate_sd_jwt -->|拡張対象| s_sd_jwt

公式に文書化された対応

利用状況には、公式のドキュメント(ベンダーやプロジェクト自身のもの、または標準化団体がその名前を挙げているページ)に対応が明記されているものだけを載せている。引用した文言がそのページにまだあるかは毎週確認している。実験的・アルファ・ベータの対応は「プレビュー」として別に数える。

出典付きの対応情報はまだ集めていない。普及していないという意味ではない。

動き

Datatracker の revision 履歴、このサイトの日次 run が書いた解説、draft 名を挙げた ML の件名。

このサイトの解説

  • 実質的な変更OAuth WG

    oauth-delegate-sd-jwt で、cnf、exp、nbf などのセキュリティクレームが delegate_payload からベースの KB-SD-JWT ペイロードへ移り、意味も定義される。

    oauth-wg/oauth-delegate-sd-jwt#15: Move security claims to base KB-SD-JWT payload and define claim semantics

    解説を読む

    #3 と #10 を修正する PR #15 は、セキュリティおよび有効性に関するクレーム (cnf、exp、nbf など) を delegate_payload からベースの KB-SD-JWT ペイロードへ移す。これにより標準的な JWT / SD-JWT ライブラリは、delegate payload を先に展開せずにそれらを評価できる。複数の delegate_payload エントリがある場合は、ベース KB-SD-JWT のセキュリティクレームを共有する。また、cnf、iat、exp、nbf、aud、nonce、sd_hash、issuer_jwt_hash が、新しい Delegate Holder への委任時にどう解釈されるか、およびその後の Delegate Holder や検証者にどう解釈されるかを定める節を追加し、Verification の節も更新する。入手できたのは PR の説明のみで、差分は確認できていない。

    • 委任されたプレゼンテーションの cnf や有効期限を、委任固有の展開処理なしに既存の SD-JWT KB 検証で確認したいライブラリ実装者。
    • クレデンシャルを別のホルダーへ再委任するエージェントが、audience と nonce の意味を明確にする必要がある場合。
  • 実質的な変更OAuth WG

    この PR は SD-JWT VC の型を発行者が vct と aka_vcts で表明したものに限定し、extends に基づく照合を削除する。

    oauth-wg/oauth-sd-jwt-vc#457: Clarify that the types of an SD-JWT VC are those asserted in vct and aka_vcts

    解説を読む

    -25 以降、第 2.2.2.2 節は、クレデンシャルの型は vct の値であるか aka_vcts に列挙されたものであると定めている。この PR は第 5.4 節に残っていた二点を削除する。一つは、Consumer が Type Metadata の extends プロパティでも型を照合してよいとする MAY、もう一つは vct の型が aka_vcts の各型を extends すべきとする SHOULD で、型は他の一つの型しか extends できないため、無関係な型が並ぶ場合には満たせない。extends は継承する Type Metadata を決めるだけになる。第 5.4 節は、拡張した型を aka_vcts に列挙するという第 2.2.2.2 節の推奨を参照し、第 7.7 節は aka_vcts の型を vct の型と同様に発行者が表明したものと記述する。後続の MUST NOT は変更されない。PR は、新しい要件はないこと、OpenID4VP 1.1 は既に vct と aka_vcts で vct_values を照合していること、ISO/IEC 18013-5 が 11 月末に日付付きドラフトを引用する予定であることを述べている。

    • vct_values を照合する検証者は、Type Metadata の extends から追加の型を推定してはならず、どちら側がメタデータを取得したかで結果が変わらなくなる。
    • 検証者が要求する親の型を extends している型の発行者は、その親の型を aka_vcts に列挙すべきである。
    • 型の照合を本文書に委ねている ISO/IEC 18013-5 の mdoc プロファイル。
    • 関連: OpenID: openid/OpenID4VP. PR は、OpenID4VP 1.1 が既に vct と aka_vcts で vct_values を照合し、型の拡張は帯域外の知識として扱うと述べている。
  • 実質的な変更OpenID

    openid/dchp で23コミットの仕様編集があり、フィールド名の変更、credential_types の配列化、mdoc と SD-JWT VC の文言修正が行われた。

    openid/dchp: 23 new commits on the default branch

    解説を読む

    利用できるのはコミットタイトルのみで、23件中8件は一覧に含まれないため、全体像は部分的である。タイトルからは、CredentialItem.format を credential_format に改名したこと、フォーマット附属書を credential_types の配列化に合わせたことが読み取れる。また、mdoc ではなくウォレットが issuer 署名か device 署名かを選ぶと明記したこと、定義が認める場合に代替のデータ要素を返せるようにしたこと、support_no_cryptographic_binding の DocRequestInfo へのマッピングを削除したことも読み取れる。SD-JWT VC のパス意味論は issue #52 に委ねられ、KB-JWT の提案が反映された。ISO 18013-5 の Document 型をバイト列として再定義するのをやめ、authority key identifier には RFC 5280 の名称を用い、RFC 7515 を規範的参照に追加した。残りはレビュー対応と整備のコミットである。ワイヤ形式への正確な影響は、タイトルだけでは確認できない。

    • dchp を追跡するウォレット開発者は、credential_format への名称変更と、配列となった credential_types に対応する必要がある。
    • mdoc レスポンスの実装者は、issuer 署名か device 署名かをウォレットが選ぶことを把握する必要がある。
  • 編集上の変更OAuth WG

    -25 版は型照合の BCP 14 の SHOULD を外し、ステータス確認のリスク記述を加え、例を再生成した

    draft-ietf-oauth-sd-jwt-vc-25: SD-JWT-based Verifiable Digital Credentials (SD-JWT VC)

    解説を読む

    型照合の記述から SHOULD が除かれ、Holder または Verifier は、型が vct の値または aka_vcts に含まれる場合にその型として「扱う」と記述された。ステータス確認は SHOULD のままだが、確認しない Verifier は失効や停止を検知できず、そのリスクをポリシーに従って受け入れることになる、という説明が加わった。例も書き換えられ、ヘッダーの typ は vc+sd-jwt から dc+sd-jwt に変わり、PID の例は架空の「Ændgard」発行者、vct の urn:example:eudi:pid:aendgard:1、追加クレーム(sex、age_in_years、portrait など)を使い、署名とハッシュも再計算された。残りは目次のページ番号と空白の変更のみで、資料は途中で切れている。

  • 編集上の変更OAuth WG

    SD-JWT VC の -26 は、RFC 6890 の参照を IANA レジストリに置き換え、重複文を削除しただけの改訂である。

    draft-ietf-oauth-sd-jwt-vc-26: SD-JWT-based Verifiable Digital Credentials (SD-JWT VC)

    解説を読む

    変更は Éric Vyncke 氏のレビューに関連する二点である。SSRF に関する考慮事項は RFC 6890 に代えて IANA の IPv4 および IPv6 特殊用途アドレスレジストリを参照するようになり、RFC 6890 の参照項目は削除された。2.2.2.2 節では、Holder と Verifier が SD-JWT VC を vct および aka_vcts の型のクレデンシャルとして扱えるとする文が削除された。その他の差分部分は日付、有効期限、文書履歴の空白の変更のみである。履歴には要件の変更は記載されていない。

  • 編集上の変更OAuth WG

    このプルリクエストは、2.2.2.2 節で直前の文と重複していた文を削除する。

    oauth-wg/oauth-sd-jwt-vc#456: Remove a duplicate sentence in Section 2.2.2.2

    解説を読む

    #454 で型の照合規則が追加された後、Holder と Verifier が SD-JWT VC をこれらの型のクレデンシャルとして扱えるとする古い文は、直前の文の繰り返しになっていた。本プルリクエストはその文を削除し、意味は変わらないとしている。#455 の上に積まれており、履歴項目は同じ -26 の見出しにまとめられる。