npm better-auth 1.7.0-beta.6
v1.7.0-beta.6

8 hours ago

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-in with 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 the jwt() plugin, update imports from better-auth/plugins to @better-auth/mcp, rename withMcpAuth to requireMcpAuth and createMcpAuthClient to createMcpResourceClient, then run npx auth migrate to apply schema changes (oauthApplication becomes oauthClient, with new oauthRefreshToken and oauthClientAssertion tables).

  • Introduced explicit OAuth protected resource modeling, replacing validAudiences with a resource-first configuration API (#9648)

Migration: Replace validAudiences with resources, link clients through oauthClientResource, then run npx @better-auth/cli generate and apply the migration to add oauthResource, oauthClientResource, and new jwks columns before deploying.

  • Changed dynamic baseURL resolution to ignore x-forwarded-host by default, preventing forwarded headers from selecting an unintended allowed host (#9134)

Migration: If your proxy exposes the public hostname only through x-forwarded-host, add advanced: { trustedProxyHeaders: true } to your betterAuth() config. Deployments where the proxy rewrites Host directly (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 set socialProviders.google.clientId in your Better Auth config.

  • Removed the deprecated oidcProvider plugin from better-auth/plugins (#10031)

Migration: Replace oidcProvider from better-auth/plugins with @better-auth/oauth-provider for 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-store on all OAuth credential responses to prevent proxies and browsers from caching tokens (#10065)
  • Added auth.api.consumePhoneNumberOTP for 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 sendVerificationEmail errors to propagate to callers instead of being silently swallowed (#8863)
  • Fixed stateless account cookies to resolve correctly across multiple server instances (#9979)
  • Fixed setUserPassword in the admin plugin to create a credential account when one does not already exist (#9482)
  • Fixed TypeScript inference in updateSession to 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-method cookie 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 additionalData returned 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 updateMemberRole to 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 the jwt() plugin, update imports from better-auth/plugins to @better-auth/mcp, rename withMcpAuth to requireMcpAuth and createMcpAuthClient to createMcpResourceClient, then run npx auth migrate to apply schema changes (oauthApplication becomes oauthClient, with new oauthRefreshToken and oauthClientAssertion tables).

  • Introduced explicit OAuth protected resource modeling, replacing validAudiences with a resource-first configuration API (#9648)

Migration: Replace validAudiences with resources, link clients through oauthClientResource, then run npx @better-auth/cli generate and apply the migration to add oauthResource, oauthClientResource, and new jwks columns 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 clientAuthentication strategies to return { clientId } instead of { clientId, client }, and remove the grantType argument from provider.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-store on 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/userinfo to return a WWW-Authenticate challenge 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 the jwt() plugin, update imports from better-auth/plugins to @better-auth/mcp, rename withMcpAuth to requireMcpAuth and createMcpAuthClient to createMcpResourceClient, then run npx auth migrate to apply schema changes (oauthApplication becomes oauthClient, with new oauthRefreshToken and oauthClientAssertion tables).

  • Introduced explicit OAuth protected resource modeling, replacing validAudiences with a resource-first configuration API (#9648)

Migration: Add a resource option to your mcp({ ... }) configuration (for example, resource: "https://api.example.com/mcp"), replace validAudiences with resources, then run npx @better-auth/cli generate and 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 incrementOne primitive natively. Custom BetterAuthRateLimitStorage implementations must replace the separate get/set pattern with a single atomic consume method.

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 generate command 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 defaultValue for additionalField definitions (#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 additionalFields support to ssoProvider for 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-store on 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 linkSocial flow 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

Don't miss a new better-auth release

NewReleases is sending notifications on new releases.