DocumentsLobeHub
Authentication System
Authentication System
Type
Topic
Status
Published
Created
Jul 7, 2026
Updated
Jul 7, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

Authentication System#

LobeHub's self-hosted authentication is built on Better Auth. The central configuration lives in src/libs/better-auth/define-config.ts, which assembles the full Better Auth instance from environment-driven options, database adapters, plugins, and SSO providers.

Authentication strategies are entirely controlled through environment variables — no code changes are needed to switch between modes. All auth env vars are declared and validated (via Zod + @t3-oss/env-core) in packages/env/src/auth.ts.


Authentication Modes#

Email/Password (default)#

Email/password login is enabled by default . The Better Auth config exposes it via the emailAndPassword block:

  • Passwords are 8–64 characters
  • Bcrypt hashes from Clerk migrations are supported alongside Better Auth's default scrypt
  • Email verification is opt-in via AUTH_EMAIL_VERIFICATION=1
  • Magic link (passwordless) login is opt-in via AUTH_ENABLE_MAGIC_LINK=1 ; expires in 15 minutes
  • Password-reset and verification emails require SMTP configuration

SSO-Only Mode#

Setting AUTH_DISABLE_EMAIL_PASSWORD=1 disables email/password login entirely . When active :

  • The email field is hidden on the login page
  • The signup page redirects to login
  • Users must authenticate through a configured SSO provider

⚠️ Ensure at least one SSO provider is configured via AUTH_SSO_PROVIDERS before enabling SSO-only mode, or users will have no login path .


SSO Provider Configuration#

Providers are enabled by setting AUTH_SSO_PROVIDERS to a comma-separated list of provider IDs . The order determines display order on the login page.

Supported providers (each requires a corresponding AUTH_<PROVIDER>_ID / AUTH_<PROVIDER>_SECRET, and OIDC providers also need AUTH_<PROVIDER>_ISSUER) :

CategoryProviders
Social / OAuthGoogle, GitHub, Apple, Microsoft, WeChat, Feishu
OIDC / EnterpriseAuth0, Authelia, Authentik, Casdoor, Cloudflare Zero Trust, Cognito, Keycloak, Logto, Okta, Zitadel
Generic OIDCgeneric_oidc (via AUTH_GENERIC_OIDC_*)

Internally, initBetterAuthSSOProviders() resolves each provider name against a registry, validates required env vars, and routes them to either socialProviders (built-in) or genericOAuthProviders (OIDC). The parsed provider list is also used as the trustedProviders for account linking, allowing accounts with different emails to be merged .


Key Environment Variables#

VariableRequiredDefaultPurpose
AUTH_SECRETSession token encryption key
JWKS_KEYRS256 RSA key pair for OIDC JWT signing and internal service auth
AUTH_SSO_PROVIDERSOptional""Comma-separated list of enabled providers
AUTH_DISABLE_EMAIL_PASSWORDOptional01 = SSO-only mode
AUTH_EMAIL_VERIFICATIONOptional01 = require email verification on signup
AUTH_ENABLE_MAGIC_LINKOptional01 = enable passwordless magic link login
AUTH_ALLOWED_EMAILSOptionalComma-separated emails/domains allowed to register
AUTH_TRUSTED_ORIGINSOptionalAdditional trusted origins for CSRF/CORS
INTERNAL_JWT_EXPIRATIONOptional30sExpiry for internal lambda→async JWT tokens

Full variable reference: docs/self-hosting/environment-variables/auth.mdx


Additional Features#

Passkeys — enabled unconditionally via the @better-auth/passkey plugin; rpID and origin are derived from APP_URL .

Email OTP (mobile) — the emailOTP plugin issues 6-digit codes expiring in 5 minutes for Expo/React Native clients; OTP is not auto-sent on signup .

Email whitelist — the custom emailWhitelist() plugin enforces AUTH_ALLOWED_EMAILS at user-creation time for both email signup and SSO flows, blocking registration with an EMAIL_NOT_ALLOWED error for unauthorized emails .

Session storage — sessions are stored both in PostgreSQL (via Drizzle) and a Redis secondary storage for performance; cookie-level cache has a 2-minute TTL .

User bootstrap — a databaseHooks.user.create.after hook calls UserService.initUser() for every new account regardless of sign-up method .

Rate limiting — password-reset and email-verification endpoints are capped at 3 requests per 60 seconds .


Key Source Files#

FilePurpose
src/libs/better-auth/define-config.tsMain Better Auth config factory
packages/env/src/auth.tsAll auth env var declarations & Zod schemas
docs/self-hosting/environment-variables/auth.mdxOperator-facing env var reference
docs/self-hosting/auth/providers/password.mdxEmail/password & SSO-only mode guide
Authentication System | Dosu