Summary
Add OAuth/social login provider support as a plugin, allowing users to sign in via Google, GitHub, Discord, and other OAuth2 providers alongside the existing email/password auth.
Motivation
Community interest in replacing the built-in auth with Better Auth (#620) was primarily driven by wanting OAuth providers. Rather than a full auth rewrite (which would be a breaking change), we can add OAuth as a plugin on top of the existing hardened auth system.
The current auth stack is solid after the v2.8.3–v2.9.x security hardening:
Proposed Approach
Plugin: oauth-providers
Phase 1 — Core OAuth2 Flow
- Generic OAuth2/OIDC authorization code flow
- Provider-agnostic token exchange and user info fetching
- Account linking (connect OAuth to existing email account)
- New user creation from OAuth profile
- Session management (reuse existing JWT system)
- Admin settings UI for configuring provider credentials
Phase 2 — Built-in Providers
- Google (
accounts.google.com)
- GitHub (
github.com/login/oauth)
- Discord (
discord.com/oauth2)
- Microsoft/Azure AD
- Generic OIDC (for self-hosted identity providers)
Phase 3 — Advanced Features
- TOTP/2FA support
- Account linking management UI
- Provider-specific scopes and permissions
- JWT claims enrichment from OAuth profile
Auth Routes Added
GET /auth/oauth/:provider → Redirect to provider
GET /auth/oauth/:provider/callback → Handle callback, create/link account
POST /auth/oauth/link → Link OAuth to existing account
POST /auth/oauth/unlink → Unlink OAuth provider
Database Changes
New oauth_accounts table:
CREATE TABLE oauth_accounts (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL REFERENCES users(id),
provider TEXT NOT NULL,
provider_account_id TEXT NOT NULL,
access_token TEXT,
refresh_token TEXT,
token_expires_at INTEGER,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE(provider, provider_account_id)
);
Admin UI
- Settings page: configure client ID/secret per provider
- User profile: show linked OAuth accounts
- Login page: "Sign in with Google/GitHub/Discord" buttons
Design Principles
- Plugin, not core — OAuth is optional, doesn't affect users who don't need it
- No breaking changes — existing email/password auth unchanged
- Cloudflare Workers compatible — no Node.js-specific dependencies
- Minimal dependencies — use native
fetch for OAuth flows, no heavy auth libraries
Prior Art / Inspiration
Related
Summary
Add OAuth/social login provider support as a plugin, allowing users to sign in via Google, GitHub, Discord, and other OAuth2 providers alongside the existing email/password auth.
Motivation
Community interest in replacing the built-in auth with Better Auth (#620) was primarily driven by wanting OAuth providers. Rather than a full auth rewrite (which would be a breaking change), we can add OAuth as a plugin on top of the existing hardened auth system.
The current auth stack is solid after the v2.8.3–v2.9.x security hardening:
Proposed Approach
Plugin:
oauth-providersPhase 1 — Core OAuth2 Flow
Phase 2 — Built-in Providers
accounts.google.com)github.com/login/oauth)discord.com/oauth2)Phase 3 — Advanced Features
Auth Routes Added
Database Changes
New
oauth_accountstable:Admin UI
Design Principles
fetchfor OAuth flows, no heavy auth librariesPrior Art / Inspiration
Related