Skip to content

fix(oauth-provider): customIdTokenClaims should override standard claims#7865

Merged
himself65 merged 3 commits intobetter-auth:canaryfrom
gustavovalverde:fix/id-token-custom-claims-overwrite
Mar 3, 2026
Merged

fix(oauth-provider): customIdTokenClaims should override standard claims#7865
himself65 merged 3 commits intobetter-auth:canaryfrom
gustavovalverde:fix/id-token-custom-claims-overwrite

Conversation

@gustavovalverde
Copy link
Copy Markdown
Contributor

@gustavovalverde gustavovalverde commented Feb 8, 2026

Summary

customIdTokenClaims values are overwritten by standard userNormalClaims in the id_token payload due to incorrect spread order in createIdToken().

The userInfoEndpoint already has the correct order ({ ...baseUserClaims, ...additionalInfoUserClaims }), but createIdToken() had them reversed ({ ...customClaims, ...userClaims }), making custom claims ineffective when they overlap with standard profile claims like given_name or family_name.

Fix

Swap the spread order in createIdToken() so custom claims take precedence over auto-derived standard claims, matching the existing userInfoEndpoint behavior.

Test

Added a test that configures customIdTokenClaims returning custom given_name, family_name, and custom_field, then verifies the id_token contains the custom values rather than the auto-derived ones.

Fixes #7864


Summary by cubic

Fixes id_token claim precedence so customIdTokenClaims override standard profile claims. Matches userInfo endpoint behavior.

  • Bug Fixes
    • Build id_token payload as {...userClaims, ...customClaims} so custom claims win (e.g., given_name, family_name).
    • Expanded tests: verify override and keep name/sub intact; add assertions for client_secret, redirect_uris, redirect URL, and auth code.

Written for commit 3f64dce. Summary will update on new commits.

Copilot AI review requested due to automatic review settings February 8, 2026 21:24
@vercel
Copy link
Copy Markdown

vercel bot commented Feb 8, 2026

@gustavovalverde is attempting to deploy a commit to the better-auth Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes id_token claim merging so customIdTokenClaims correctly overrides overlapping standard OIDC profile claims, aligning createIdToken() behavior with the existing userinfo endpoint.

Changes:

  • Swap spread order in createIdToken() so customIdTokenClaims takes precedence over userNormalClaims.
  • Add a regression test asserting custom given_name/family_name values are preserved in id_token when profile scope is requested.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
packages/oauth-provider/src/token.ts Adjusts id_token payload merge order so custom claims override standard derived claims.
packages/oauth-provider/src/token.test.ts Adds a regression test covering custom-claim precedence for overlapping profile claims in id_token.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Feb 8, 2026

Open in StackBlitz

@better-auth/api-key

npm i https://pkg.pr.new/@better-auth/api-key@7865

better-auth

npm i https://pkg.pr.new/better-auth@7865

auth

npm i https://pkg.pr.new/auth@7865

@better-auth/core

npm i https://pkg.pr.new/@better-auth/core@7865

@better-auth/drizzle-adapter

npm i https://pkg.pr.new/@better-auth/drizzle-adapter@7865

@better-auth/electron

npm i https://pkg.pr.new/@better-auth/electron@7865

@better-auth/expo

npm i https://pkg.pr.new/@better-auth/expo@7865

@better-auth/i18n

npm i https://pkg.pr.new/@better-auth/i18n@7865

@better-auth/kysely-adapter

npm i https://pkg.pr.new/@better-auth/kysely-adapter@7865

@better-auth/memory-adapter

npm i https://pkg.pr.new/@better-auth/memory-adapter@7865

@better-auth/mongo-adapter

npm i https://pkg.pr.new/@better-auth/mongo-adapter@7865

@better-auth/oauth-provider

npm i https://pkg.pr.new/@better-auth/oauth-provider@7865

@better-auth/passkey

npm i https://pkg.pr.new/@better-auth/passkey@7865

@better-auth/prisma-adapter

npm i https://pkg.pr.new/@better-auth/prisma-adapter@7865

@better-auth/redis-storage

npm i https://pkg.pr.new/@better-auth/redis-storage@7865

@better-auth/scim

npm i https://pkg.pr.new/@better-auth/scim@7865

@better-auth/sso

npm i https://pkg.pr.new/@better-auth/sso@7865

@better-auth/stripe

npm i https://pkg.pr.new/@better-auth/stripe@7865

@better-auth/telemetry

npm i https://pkg.pr.new/@better-auth/telemetry@7865

@better-auth/test-utils

npm i https://pkg.pr.new/@better-auth/test-utils@7865

commit: 8155f85

@dvanmali
Copy link
Copy Markdown
Contributor

dvanmali commented Feb 9, 2026

LGTM

In createIdToken, the payload was built as { ...customClaims, ...userClaims },
causing userNormalClaims to overwrite values returned by customIdTokenClaims.
This is incorrect because custom claims should take precedence over auto-derived
standard claims (e.g., given_name/family_name derived from user.name).

Swap the spread order to { ...userClaims, ...customClaims } so that
customIdTokenClaims values win. The userinfo endpoint already had the correct
order ({ ...baseUserClaims, ...additionalInfoUserClaims }).

Adds a test verifying custom claims override profile-derived claims in id_token.
Add setup assertions for client_secret and redirect_uris in beforeAll.
Add redirect URL and authorization code assertions before token exchange.
@gustavovalverde gustavovalverde force-pushed the fix/id-token-custom-claims-overwrite branch from 3b59fad to a6e52e4 Compare February 24, 2026 11:19
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Feb 24, 2026

CLA assistant check
All committers have signed the CLA.

@gustavovalverde
Copy link
Copy Markdown
Contributor Author

cc: @himself65 this one should be pretty straightforward

@gustavovalverde
Copy link
Copy Markdown
Contributor Author

@himself65 just in case, this is marking the PR as CLA pending, but it's signed.

Also, this is technically a one liner, it's just a bigger PR because of the test

@himself65
Copy link
Copy Markdown
Contributor

Closing: CLA has not been signed. Please sign the CLA and reopen or submit a new PR if you'd like to continue. Thanks!

@himself65 himself65 closed this Mar 3, 2026
@gustavovalverde
Copy link
Copy Markdown
Contributor Author

I did sign the CLA @himself65
image

Why close the PR?

@himself65
Copy link
Copy Markdown
Contributor

Sorry, badge didn't update

@himself65 himself65 enabled auto-merge March 3, 2026 04:55
@himself65 himself65 added this pull request to the merge queue Mar 3, 2026
Merged via the queue into better-auth:canary with commit c598335 Mar 3, 2026
29 of 31 checks passed
gustavovalverde added a commit to gustavovalverde/better-auth that referenced this pull request Mar 16, 2026
Move auth_time and acr assignments before the customClaims spread in
createIdToken, so that customIdTokenClaims can override these values.
Follow-up to better-auth#7865 which fixed userClaims vs customClaims order but
left acr/auth_time after the spread.
@gustavovalverde gustavovalverde deleted the fix/id-token-custom-claims-overwrite branch March 19, 2026 07:34
@better-auth better-auth locked as resolved and limited conversation to collaborators Mar 31, 2026
@bytaesu bytaesu added the locked Locked conversations after being closed for 7 days label Mar 31, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

locked Locked conversations after being closed for 7 days

Projects

None yet

Development

Successfully merging this pull request may close these issues.

customIdTokenClaims values are overwritten by standard profile claims in id_token

6 participants