[GH-ISSUE #8288] oauth-provider: pairwise subject identifiers documented in types but not implemented #11048

Closed
opened 2026-04-13 07:25:33 -05:00 by GiteaMirror · 0 comments
Owner

Originally created by @gustavovalverde on GitHub (Mar 2, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/8288

To Reproduce

  1. Register a client via DCR with subject_type: "pairwise" in the request body
  2. Complete an authorization code flow for two different clients with the same user
  3. Compare the sub claim in the id_tokens

Current vs. Expected behavior

Current: The sub claim is always user.id regardless of client. Both clients receive the same sub, making the user linkable across RPs. The subject_type field from DCR is silently stored in client metadata (via the [key: string]: unknown index signature) but never read by the runtime.

The types acknowledge pairwise as a concept (types/oauth.ts:206-213):

/**
 * pairwise: the subject identifier is unique to the client
 * public: the subject identifier is unique to the server
 *
 * only `public` is supported.
 */
subject_types_supported: "public"[];

And sub: user.id is hardcoded after the custom claims spread in token.ts, so customIdTokenClaims can't override it either:

// token.ts:154-166 — createIdToken
const payload: JWTPayload = {
  ...customClaims,   // hook output
  ...userClaims,     // has sub: user.id
  sub: user.id,      // hardcoded last → overwrites
};

Expected: When a client registers with subject_type: "pairwise", the sub should be a per-client pseudonymous identifier as defined in OIDC Core Section 8.1, so different RPs cannot correlate users. This is supported by all major OIDC providers and required for OIDC conformance when advertising pairwise support.

What version of Better Auth are you using?

1.5.0-beta.18

(@better-auth/oauth-provider source checked at latest main)

System info

{
  "system": { "platform": "darwin", "arch": "arm64" },
  "node": { "version": "v24.12.0" },
  "frameworks": [{ "name": "next", "version": "16.1.6" }],
  "databases": [{ "name": "@libsql/client", "version": "0.17.0" }, { "name": "drizzle", "version": "0.45.1" }],
  "betterAuth": { "version": "1.5.0-beta.18" }
}
Originally created by @gustavovalverde on GitHub (Mar 2, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/8288 ## To Reproduce 1. Register a client via DCR with `subject_type: "pairwise"` in the request body 2. Complete an authorization code flow for two different clients with the same user 3. Compare the `sub` claim in the id_tokens ## Current vs. Expected behavior **Current:** The `sub` claim is always `user.id` regardless of client. Both clients receive the same `sub`, making the user linkable across RPs. The `subject_type` field from DCR is silently stored in client `metadata` (via the `[key: string]: unknown` index signature) but never read by the runtime. The types acknowledge pairwise as a concept (`types/oauth.ts:206-213`): ```typescript /** * pairwise: the subject identifier is unique to the client * public: the subject identifier is unique to the server * * only `public` is supported. */ subject_types_supported: "public"[]; ``` And `sub: user.id` is hardcoded after the custom claims spread in `token.ts`, so `customIdTokenClaims` can't override it either: ```typescript // token.ts:154-166 — createIdToken const payload: JWTPayload = { ...customClaims, // hook output ...userClaims, // has sub: user.id sub: user.id, // hardcoded last → overwrites }; ``` **Expected:** When a client registers with `subject_type: "pairwise"`, the `sub` should be a per-client pseudonymous identifier as defined in [OIDC Core Section 8.1](https://openid.net/specs/openid-connect-core-1_0.html#PairwiseAlg), so different RPs cannot correlate users. This is supported by all major OIDC providers and required for OIDC conformance when advertising pairwise support. ## What version of Better Auth are you using? 1.5.0-beta.18 (`@better-auth/oauth-provider` source checked at latest `main`) ## System info ```json { "system": { "platform": "darwin", "arch": "arm64" }, "node": { "version": "v24.12.0" }, "frameworks": [{ "name": "next", "version": "16.1.6" }], "databases": [{ "name": "@libsql/client", "version": "0.17.0" }, { "name": "drizzle", "version": "0.45.1" }], "betterAuth": { "version": "1.5.0-beta.18" } } ```
GiteaMirror added the lockedenhancement labels 2026-04-13 07:25:33 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#11048