Authorization Server Auth: DPoP Token Binding (SEP-1932)
メンテナーはふだん 7 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 45/100
- issue の種類
- 機能追加
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 技術スタック
- typescript
- 領域
- api, authentication, security
調査の方向性
まず既存の helpers/ と src/scenarios/authorization-server/ 配下の Authorization-Server シナリオを読み、次に標準 CLI を通じてシナリオがどのように登録・実行されるかを確認します。ここで説明されている DPoP ヘルパー、thumbprint とメタデータのチェック、proof の失敗ケース、nonce の動作、および受け入れテストを実装します。npm test で成功するケースと意図的に失敗するケースがカバーされ、シナリオが登録され、文書化された実装が検証されれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Overview
SEP-1932
adopts OAuth 2.0 Demonstrating Proof of Possession
(RFC 9449) as an optional MCP
authorization extension. For sender-constrained tokens to work, the OAuth
authorization server must accept a DPoP proof at the token endpoint, bind the
issued access token to the client's public key, and advertise its DPoP support.
This issue covers authorization server conformance only. It validates that an
authorization server advertises dpop_signing_alg_values_supported, validates the
token-endpoint DPoP proof, issues a DPoP-bound token (token_type=DPoP with a
cnf.jkt confirmation), honours the optional nonce mechanism, and enforces
dpop_bound_access_tokens client registration.
Key properties of the authorization-server role:
- The framework drives the authorization server as a DPoP client at the token
endpoint, presenting valid and invalid proofs. - DPoP is adopted as defined in RFC 9449 — no MCP-specific extensions to the
token-endpoint exchange. - This is distinct from client and resource-server conformance even though all
three involve OAuth; the authorization server is tested in isolation.
Specification References
- SEP-1932 PR: https://github.com/modelcontextprotocol/modelcontextprotocol/pull/1932
- Detailed proposal: https://github.com/modelcontextprotocol/ext-auth/blob/pieterkas-dpop-extension/specification/draft/dpop-extension.mdx
- RFC 9449 — OAuth 2.0 Demonstrating Proof of Possession (DPoP): https://www.rfc-editor.org/rfc/rfc9449.html
- §4.3 Checking DPoP Proofs (token-endpoint validation), §5 DPoP Access Token Request
- §6 Public Key Confirmation (
cnf/jkt) - §5.1
dpop_signing_alg_values_supported, §5.2dpop_bound_access_tokens - §8 Authorization Server-Provided Nonce
- RFC 8414 — OAuth 2.0 Authorization Server Metadata: https://datatracker.ietf.org/doc/html/rfc8414
- Baseline MCP Authorization specification: https://modelcontextprotocol.io/specification/draft/basic/authorization
Scope
In scope — what the authorization server does:
- Advertising
dpop_signing_alg_values_supported(asymmetric algorithms only; no
none) in its authorization server metadata. - Validating the DPoP proof presented on the token request (§4.3 as applicable to
the token endpoint:typ,alg, signature,jwkwithout private key,
htm=POST,htu=token endpoint,jti,iatwindow,noncewhen required). - Issuing a DPoP-bound access token:
token_typeofDPoPand acnf.jkt
confirmation equal to the base64url JWK SHA-256 thumbprint of the proof key. - Token-endpoint nonce mechanism:
400 use_dpop_nonce+DPoP-Nonce, then
accepting the retried request. - Honouring
dpop_bound_access_tokens=trueclient registration by rejecting token
requests that lack a DPoP proof. (Excluded — requires dynamic client registration, out of scope for these DPoP scenarios; see #396.) - Binding refresh tokens to the same key for public clients. (Deferred — not testable until the shared conformance test AS supports refresh tokens; tracked as a follow-up. See #396.)
Not in scope (covered elsewhere or by another role):
- Resource-server proof validation and
ath/cnfagreement at resource access —
covered by the server conformance issue. - Client proof construction and nonce-retry behaviour — covered by the client
conformance issue.
Changes Required
Conformance harness (framework acting as a DPoP client at the token endpoint)
- The framework, acting as a DPoP client, performs a token request with a
DPoP proof against the authorization server under test, then inspects the
metadata, the token response (token_type), and the issued token'scnf.jkt. - Fixture generation for a valid proof keyed to a generated key pair, plus crafted
invalid proofs (one per token-endpoint failure mode).
Helpers (helpers/)
- DPoP proof builder with per-field overrides (reused from / shared with the
server scenario helpers where practical). - JWK SHA-256 thumbprint helper to assert
cnf.jktequals the proof key
thumbprint. - Metadata fetch/parse helper for
dpop_signing_alg_values_supported.
Scenario (src/scenarios/authorization-server/)
- A single scenario file implementing all checks below, registered in the
authorization-server scenario list.
Acceptance test suite
- Helper unit tests and scenario acceptance tests asserting each check passes for
a conformant authorization server and fails for a deliberately non-conformant
one.
Components that do not change
- The resource-server (MCP server) path — the grant/token type does not change how
a resource server validates an access token's audience. - OIDC discovery infrastructure beyond surfacing the new metadata field.
Checks to Cover
Positive
- Metadata advertises
dpop_signing_alg_values_supportedas a JSON array of
asymmetric JWSalgvalues;noneis not present. - Token endpoint accepts a valid DPoP proof (
typ=dpop+jwt, asymmetricalg,
embedded publicjwk,htm=POST,htu=token endpoint,jti,iatin
window) and issues a token. - Issued token response sets
token_typetoDPoP. - Issued token carries a
cnf.jktequal to the base64url JWK SHA-256
thumbprint of the proof's public key. (Verified for JWT access tokens; opaque/reference tokens are out of scope —cnf.jktisn't observable without introspection; see #396.) - For a public client, an issued refresh token is bound to the same key. (Deferred to a follow-up. The shared test AS does not yet support refresh tokens; see #396.)
Negative (token-endpoint proof failures → 400 invalid_dpop_proof unless noted)
- Proof signature does not verify against the embedded
jwk. -
typis notdpop+jwt. -
algisnoneor a symmetric algorithm. -
jwkcontains a private key. -
htm/htudo not match the token endpoint request. -
iatis outside the acceptable window. - A required claim is missing (
jti,htm,htu,iat).
Nonce behaviour (if the authorization server requires nonces)
- Returns
400 use_dpop_nonce+DPoP-Noncewhen a nonce is required and
absent. - Accepts the retried token request carrying the matching
nonceclaim. - Rejects a proof whose
noncedoes not match a recently supplied value.
Client registration enforcement
- With
dpop_bound_access_tokens=true, the authorization server rejects a
token request that does not include a DPoP proof. (Excluded — depends on dynamic client registration; see #396.)
Acceptance Criteria
- A single scenario file in
src/scenarios/authorization-server/implements
all checks above (one scenario, many checks). - Each check has both a passing case (conformant authorization server) and a
deliberate failing case (crafted invalid proof / missing field) proven by the
automated acceptance test suite — no check is vacuously passing. - Helper unit tests cover the proof builder, thumbprint, and metadata helpers.
- The acceptance test suite runs as part of
npm test. - Scenario runs through the standard CLI runner; no parallel entry point is
introduced. - Validated against at least one real authorization server implementation
before the PR is submitted; SDK/AS baseline YAMLs updated where existing
implementations do not yet support DPoP.
Out of Scope
- Nonce cryptographic construction (e.g. AEAD-encrypted timestamps) — an
implementation choice; only the observableuse_dpop_nonceprotocol is tested. - Full OAuth 2.1 / token-endpoint conformance unrelated to DPoP (PKCE, resource
indicators, etc.) — covered by existing baseline authorization conformance. - Resource-server and client behaviour — covered by the separate server and
client conformance issues.
Notes
Prepared with the help of Claude (Opus 4.8)
- 主要言語
- TypeScript
- スター
- 130
- フォーク
- 107
- 平均マージ
- 8日 19時間
- マージ済み PR(30日)
- 2
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
modelcontextprotocol/conformance のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
modelcontextprotocol/conformance#531 · コメント 1 件 ·
メンテナーはふだん 7 日以内に返信
-
server-stateless: 500 ms whole-request deadline in no-log-without-loglevel reports slow servers as failures対応中かも @birbprophet が 8 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
modelcontextprotocol/conformance#530 ·
メンテナーはふだん 7 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
modelcontextprotocol/conformance#519 ·
メンテナーはふだん 7 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
modelcontextprotocol/conformance#315 · コメント 1 件 ·
メンテナーはふだん 7 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
modelcontextprotocol/conformance#312 · コメント 1 件 ·
メンテナーはふだん 7 日以内に返信
modelcontextprotocol/conformance の issue をすべて見る
似ている issue
-
Link Checker Reportオープンautomated issue report
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
databendlabs/databend-docs#3511 ·
-
area/dashboard kind/bug QA/dev-automation
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
rancher/dashboard#19379 · コメント 2 件 ·
メンテナーはふだん 5 日以内に返信
-
perf(core): getComments() runs the approved count and the comment list as two sequential queriesオープンarea/core bot:bug bot:working
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
emdash-cms/emdash#3905 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
難易度 1/5 1時間未満 初心者へのやさしさ 90/100
lingdojo/kana-dojo#31728 · コメント 1 件 · リアクション 5 件 ·
メンテナーはふだん 1 日以内に返信
-
selective-claw: freshTailTurns=0 keeps ALL turns verbatim and summarizes none (slice(-0) === slice(0))対応中かも @zjncs が今日担当しました。 オープンcomponent:tokenless
難易度 2/5 1〜3時間 初心者へのやさしさ 80/100
agentic-os-org/ANOLISA#6112 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信