better-auth
❗ Breaking Changes
- Added wildcard endpoint matching to the captcha plugin, requiring full auth path matches instead of partial prefix matching (#10004)
Migration: Replace partial endpoint paths like
/sign-inwith explicit wildcards such as/sign-in/*or/sign-in/**in your captcha plugin configuration.
- Moved the MCP plugin into its own package,
@better-auth/mcp, built on@better-auth/oauth-provider(#9992)
Migration: Install
@better-auth/mcp, add thejwt()plugin, update imports frombetter-auth/pluginsto@better-auth/mcp, renamewithMcpAuthtorequireMcpAuthandcreateMcpAuthClienttocreateMcpResourceClient, then runnpx auth migrateto apply schema changes (oauthApplicationbecomesoauthClient, with newoauthRefreshTokenandoauthClientAssertiontables).
- Introduced explicit OAuth protected resource modeling, replacing
validAudienceswith a resource-first configuration API (#9648)
Migration: Replace
validAudienceswithresources, link clients throughoauthClientResource, then runnpx @better-auth/cli generateand apply the migration to addoauthResource,oauthClientResource, and newjwkscolumns before deploying.
- Changed dynamic
baseURLresolution to ignorex-forwarded-hostby default, preventing forwarded headers from selecting an unintended allowed host (#9134)
Migration: If your proxy exposes the public hostname only through
x-forwarded-host, addadvanced: { trustedProxyHeaders: true }to yourbetterAuth()config. Deployments where the proxy rewritesHostdirectly (nginx default, Vercel, Cloudflare, Netlify) are unaffected.
- Required a Google client ID to be configured for One Tap ID token audience validation (#10036)
Migration: Configure
oneTap({ clientId: "your-google-client-id" })or setsocialProviders.google.clientIdin your Better Auth config.
- Removed the deprecated
oidcProviderplugin frombetter-auth/plugins(#10031)
Migration: Replace
oidcProviderfrombetter-auth/pluginswith@better-auth/oauth-providerfor OIDC authorization-server integrations.
Features
- Added support for pre-binding device codes to a specific user during the device authorization flow (#9995)
- Added a popup-based OAuth sign-in flow as an alternative to full-page redirects (#9890)
- Added DPoP (RFC 9449) sender-constrained access token support to the OAuth provider (#10039)
- Enforced
Cache-Control: no-storeon all OAuth credential responses to prevent proxies and browsers from caching tokens (#10065) - Added
auth.api.consumePhoneNumberOTPfor verifying and consuming phone OTP codes server-side without modifying users or sessions (#9766) - Added opt-in JWKS-backed asymmetric JWT support for session cookie cache tokens, allowing public-key verification instead of shared secrets (#8931)
Bug Fixes
- Fixed session checks to work without HTTP headers for server-side use cases (#10053)
- Fixed the cookie cache fallback to correctly retrieve sessions on a cache miss (#9348)
- Fixed
sendVerificationEmailerrors to propagate to callers instead of being silently swallowed (#8863) - Fixed stateless account cookies to resolve correctly across multiple server instances (#9979)
- Fixed
setUserPasswordin the admin plugin to create a credential account when one does not already exist (#9482) - Fixed TypeScript inference in
updateSessionto include plugin-defined session fields (#9777) - Fixed auth client return types to use named types instead of anonymous inline shapes (#10071)
- Fixed plugin type inference to work correctly in composite TypeScript monorepo setups (#9583)
- Fixed large session and account cookies to be chunked near the browser size limit, preventing truncation (#10088)
- Fixed the database layer to reuse active transactions instead of opening nested ones (#10070)
- Fixed
last-login-methodcookie clearing to include the domain attribute, ensuring cross-subdomain cookies are removed correctly (#9319) - Fixed the OAuth popup flow to filter internal state keys from the
additionalDatareturned to the caller (#10067) - Fixed OpenAPI schema generation to mark model ID fields as required (#9704)
- Fixed OpenAPI serialization of Zod request schemas to accurately reflect all validation constraints (#9315)
- Fixed
updateMemberRoleto reject unknown or empty role values with a proper error (#9962) - Refactored role authorization logic to reduce nesting and improve extensibility (#9677)
- Reverted the headerless session check fix (#10053) pending further investigation (#10074)
For detailed changes, see CHANGELOG
@better-auth/oauth-provider
❗ Breaking Changes
- Moved the MCP plugin into its own package,
@better-auth/mcp, built on@better-auth/oauth-provider(#9992)
Migration: Install
@better-auth/mcp, add thejwt()plugin, update imports frombetter-auth/pluginsto@better-auth/mcp, renamewithMcpAuthtorequireMcpAuthandcreateMcpAuthClienttocreateMcpResourceClient, then runnpx auth migrateto apply schema changes (oauthApplicationbecomesoauthClient, with newoauthRefreshTokenandoauthClientAssertiontables).
- Introduced explicit OAuth protected resource modeling, replacing
validAudienceswith a resource-first configuration API (#9648)
Migration: Replace
validAudienceswithresources, link clients throughoauthClientResource, then runnpx @better-auth/cli generateand apply the migration to addoauthResource,oauthClientResource, and newjwkscolumns before deploying.
- Changed client authentication strategies to return only the proven client ID, with the provider resolving and authorizing the client record itself (#10063)
Migration: Update custom
clientAuthenticationstrategies to return{ clientId }instead of{ clientId, client }, and remove thegrantTypeargument fromprovider.authenticateClient()calls in custom grant handlers.
Features
- Added DPoP (RFC 9449) sender-constrained access token support to the OAuth provider (#10039)
- Added an extension surface for registering custom token grants, client authentication methods, discovery metadata, and claim contributors in companion plugins (#10030)
- Improved token introspection to return consistent claims for both opaque and JWT access tokens, and to support resource-server-scoped introspection (#10045)
- Added protected dynamic client registration (RFC 7591) with initial access token support, allowing machine clients to register without a user session (#10037)
- Enforced
Cache-Control: no-storeon all OAuth credential responses to prevent proxies and browsers from caching tokens (#10065)
Bug Fixes
- Fixed multiple bugs: JWKS caching, OAuth ID mapping, team invitations, account cookie handling, and SCIM deprovisioning (#9987)
- Fixed OAuth query parameter canonicalization for signed requests to prevent signature verification failures (#9941)
- Fixed
/oauth2/userinfoto return aWWW-Authenticatechallenge when the access token is invalid, expired, or revoked (#10068)
For detailed changes, see CHANGELOG
@better-auth/mcp ✨
❗ Breaking Changes
- Moved the MCP plugin into its own package,
@better-auth/mcp, built on@better-auth/oauth-provider(#9992)
Migration: Install
@better-auth/mcp, add thejwt()plugin, update imports frombetter-auth/pluginsto@better-auth/mcp, renamewithMcpAuthtorequireMcpAuthandcreateMcpAuthClienttocreateMcpResourceClient, then runnpx auth migrateto apply schema changes (oauthApplicationbecomesoauthClient, with newoauthRefreshTokenandoauthClientAssertiontables).
- Introduced explicit OAuth protected resource modeling, replacing
validAudienceswith a resource-first configuration API (#9648)
Migration: Add a
resourceoption to yourmcp({ ... })configuration (for example,resource: "https://api.example.com/mcp"), replacevalidAudienceswithresources, then runnpx @better-auth/cli generateand apply the migration before deploying.
Features
- Added DPoP (RFC 9449) sender-constrained access token support to the OAuth provider (#10039)
For detailed changes, see CHANGELOG
@better-auth/api-key
❗ Breaking Changes
- Hardened state transitions with atomic adapter primitives, enforcing API key quotas and rate limits without race conditions (#10000)
Migration: Custom adapters must implement the new
incrementOneprimitive natively. CustomBetterAuthRateLimitStorageimplementations must replace the separateget/setpattern with a single atomicconsumemethod.
Bug Fixes
- Hardened session authority checks to reject stale cookie cache entries and unverified session selectors (#9991)
- Refactored server-only endpoints to prevent them from being accidentally exposed over HTTP (#9835)
For detailed changes, see CHANGELOG
auth
Bug Fixes
- Fixed the
generatecommand to correctly handle a directory path passed to--output(#9564) - Fixed CLI import resolution for SvelteKit, Vite asset, and Cloudflare virtual-module imports (#9834)
- Fixed the Drizzle schema generator to correctly serialize array
defaultValueforadditionalFielddefinitions (#10048) - Fixed the Prisma schema regenerator to skip
Unsupported()field types without failing (#10011) - Fixed the Prisma generator to update existing field types when regenerating the schema (#9729)
For detailed changes, see CHANGELOG
@better-auth/sso
Features
- Added
additionalFieldssupport tossoProviderfor storing and returning custom SSO provider data (#9445)
Bug Fixes
- Hardened identity token validation for One Tap, Microsoft, SSO, WeChat, and Reddit providers (#10003)
- Fixed OIDC endpoint redirect rejection to work portably, including on Cloudflare Workers, with a clear error when a discovery or token endpoint redirects (#10072)
For detailed changes, see CHANGELOG
@better-auth/core
Features
- Added DPoP (RFC 9449) sender-constrained access token support to the OAuth provider (#10039)
- Enforced
Cache-Control: no-storeon all OAuth credential responses to prevent proxies and browsers from caching tokens (#10065)
For detailed changes, see CHANGELOG
@better-auth/expo
Bug Fixes
- Hardened trusted request context handling to prevent spoofed request contexts in Expo apps (#9990)
- Fixed the Expo
linkSocialflow to send the session cookie when linking an account via an ID token (#9953)
For detailed changes, see CHANGELOG
@better-auth/scim
Features
- Added durable SCIM Group resources with organization-scoped membership, role projection, and Group lifecycle endpoints (#10018)
Bug Fixes
- Fixed team capacity enforcement, made SCIM token comparison constant-time, and fixed org-admin SSO domain verification (#10002)
For detailed changes, see CHANGELOG
@better-auth/drizzle-adapter
Bug Fixes
- Fixed the Drizzle MySQL adapter to return rows consumed by update and delete operations (#10081)
For detailed changes, see CHANGELOG
@better-auth/electron
Bug Fixes
- Restructured the session fetch architecture in the Electron client to improve reliability (#8760)
For detailed changes, see CHANGELOG
@better-auth/kysely-adapter
Bug Fixes
- Made single-use credential, counter, and replay marker operations atomic to prevent race conditions (#9993)
For detailed changes, see CHANGELOG
@better-auth/mongo-adapter
Bug Fixes
- Fixed guarded state transitions to be portable across Prisma-backed adapter configurations (#10086)
For detailed changes, see CHANGELOG
@better-auth/passkey
Bug Fixes
- Fixed passkey OpenAPI schema generation to produce valid schemas compatible with client code generators (#9555)
For detailed changes, see CHANGELOG
@better-auth/stripe
Bug Fixes
- Fixed Stripe subscription handling and customer linking to correctly associate subscriptions with users (#9971)
For detailed changes, see CHANGELOG
Contributors
Thanks to everyone who contributed to this release:
@arnnvv, @Bekacru, @brentmitchell25, @brone1323, @bytaesu, @ChrisMGeo, @ElGauchooooo, @GautamBytes, @gustavovalverde, @ping-maxwell, @SferaDev, @tsushanth, @Tushar-Khandelwal-2004
Full changelog: v1.7.0-beta.5...v1.7.0-beta.6