Better Auth Changelog - February 21-28, 2026

February 28, 2026

This changelog is generated by Notra for demonstration purposes. Notra is not affiliated with Better Auth.

Highlights

Critical: OTP race condition allows reuse across concurrent requests

Concurrent POST requests could verify the same OTP multiple times before deletion, bypassing single-use constraints and enabling account takeover. Fixed using atomic delete-before-verify across all OTP endpoints (email-otp, sign-in, password reset). #8067 (Author: @Oluwatobi-Mustapha)

API Keys now scoped to organizations with multi-config support

The api-key plugin now lives at @better-auth/api-key and supports multiple configurations per instance. Keys can be owned by organizations instead of just users. Schema changes: userId becomes referenceId, plus new configId and references fields. #4210 (Author: @ping-maxwell)

User enumeration prevention during signup

When email verification or manual signup is enabled, duplicate email attempts now return success without creating a session. Eliminates timing attacks that leak registered accounts. Optional onExistingUserSignUp callback for notifying account owners. #8091 (Author: @bytaesu)

ID token persistence in getAccessToken auto-refresh

getAccessToken was returning a new idToken from token refresh but not persisting it, leaving identity claims stale in storage. Now saved alongside access and refresh tokens. #8211 (Author: @GautamBytes)

Built-in Cloudflare D1 database support

Added Kysely dialect for Cloudflare D1. BetterAuth now runs natively on Workers without custom adapters. Auto-detection via batch/exec/prepare method checks. #7519 (Author: @bytaesu)

More Updates

Security

  • Keep auth_time stable across ID token refresh #8134 - Per OpenID Connect Core 1.0, auth_time must not change when tokens refresh. Captures original login time and carries it through token rotation. Requires migration: add nullable authTime column to oauthRefreshToken. (Author: @grant0417)

Features & Enhancements

  • POST /update-session endpoint #8084 - Update custom session fields and refresh the session cookie. (Author: @himself65)
  • CLI upgrade command #8204 - npx auth upgrade scans package.json for better-auth deps, fetches latest versions, shows a table, and installs pinned versions. (Author: @himself65)

Bug Fixes

  • Session changes broadcast to other tabs #8177 - Sign-out and user updates now post to other open tabs so useSession stays in sync. Fixes dead-code broadcast function. (Author: @Abhinav-kodes)
  • Drizzle adapter date handling crash #8105 - Removed input transformation that stringified dates before insert. Dates now convert only on read. (Author: @ping-maxwell)
  • Drizzle camelCase key mapping #8176 - Schema introspection now handles camelCase column names on PostgreSQL. (Author: @jonathan-teamstatus)

Infrastructure

  • Prisma v7 migration #8166 - Updated prisma-adapter and CLI. Changed: datasourceUrl now passed to PrismaClient constructor; call prisma generate explicitly after db push. (Author: @himself65)

Documentation

  • New documentation and landing page #8195 - Moved landing site into main repository. (Author: @ping-maxwell)