⚠️ There may be overlap with #1527 and #1548 — check before implementing.
Stack: SDK V2 + New Spec — 2 of 10 (after card 1; independent of transport work).
Re-key the persisted OAuth store and add the SEP-837/2350/2352 auth UX. This applies to both eras — the SDK v2 betas already enforce the flows, but they expect our provider to round-trip issuer-stamped state.
Scope
- Re-key storage from per-server-URL to
(server, issuer) (core/auth/store.ts, OAuthMemoryStore/ServerOAuthState). Stamp issuer on stored clientInformation/tokens; on every flow, detect issuer change vs. freshly fetched PRM/AS metadata → invalidate + re-register (DCR) / error (static) / continue (CIMD). (SEP-2352)
- DCR sends
application_type: "native" (localhost Inspector). Render registration rejections meaningfully in ClientSettingsForm. Reflect DCR's deprecated-in-favor-of-CIMD status. (SEP-837)
- Scope step-up union: persist the requested-scope set per
(server, issuer); on a 403 challenge, re-authorize with the union of prior + challenged scopes. Surface onInsufficientScope (reauthorize | throw) as a setting and visualize the union in the auth flow. (SEP-2350)
- 401 under negotiation: unwrap
SdkError(EraNegotiationFailed) → UnauthorizedError (at error.data.cause) in oauthManager.ts; switch to finishAuth(URLSearchParams) whole-params form (RFC 9207 iss validation inside → new IssuerMismatchError state to display).
- Extend
OAuthStep and the Network-tab auth capture with the new steps/errors (issuer comparison, step-up union, CIMD fetch).
Key files
core/auth/store.ts, core/auth/oauth-storage.ts, core/auth/scopes.ts, core/auth/challenge.ts, core/mcp/oauthManager.ts, core/auth/types.ts (OAuthStep), clients/web/src/components/groups/ClientSettingsForm/*, NetworkEntry.
Acceptance
- OAuth state keyed by
(server, issuer); AS change triggers correct re-register/error/continue.
- Step-up 403 loop resolves with unioned scopes and is visible in the UI.
npm run ci green.
Ref: specification/v2_new_spec_impact.md §5, §8.2(auth), §9.4, §9.5(2).
Stack: SDK V2 + New Spec — 2 of 10 (after card 1; independent of transport work).
Re-key the persisted OAuth store and add the SEP-837/2350/2352 auth UX. This applies to both eras — the SDK v2 betas already enforce the flows, but they expect our provider to round-trip issuer-stamped state.
Scope
(server, issuer)(core/auth/store.ts,OAuthMemoryStore/ServerOAuthState). Stampissueron storedclientInformation/tokens; on every flow, detect issuer change vs. freshly fetched PRM/AS metadata → invalidate + re-register (DCR) / error (static) / continue (CIMD). (SEP-2352)application_type: "native"(localhost Inspector). Render registration rejections meaningfully inClientSettingsForm. Reflect DCR's deprecated-in-favor-of-CIMD status. (SEP-837)(server, issuer); on a 403 challenge, re-authorize with the union of prior + challenged scopes. SurfaceonInsufficientScope(reauthorize | throw) as a setting and visualize the union in the auth flow. (SEP-2350)SdkError(EraNegotiationFailed)→UnauthorizedError(aterror.data.cause) inoauthManager.ts; switch tofinishAuth(URLSearchParams)whole-params form (RFC 9207issvalidation inside → newIssuerMismatchErrorstate to display).OAuthStepand the Network-tab auth capture with the new steps/errors (issuer comparison, step-up union, CIMD fetch).Key files
core/auth/store.ts,core/auth/oauth-storage.ts,core/auth/scopes.ts,core/auth/challenge.ts,core/mcp/oauthManager.ts,core/auth/types.ts(OAuthStep),clients/web/src/components/groups/ClientSettingsForm/*,NetworkEntry.Acceptance
(server, issuer); AS change triggers correct re-register/error/continue.npm run cigreen.Ref:
specification/v2_new_spec_impact.md§5, §8.2(auth), §9.4, §9.5(2).