Configure authentication
Configure site sign-in, social providers, passkeys, and admin portal access.
Configure authentication
The project uses Better Auth for email and password sign-in, organizations, two-factor authentication, passkeys, and the OAuth/OIDC provider used by MCP clients.
Required values
Set these in .env.local and in your deployment environment:
| Variable | Purpose |
|---|---|
BETTER_AUTH_SECRET | Signs sessions on every site. Generate with openssl rand -base64 32. |
NEXT_PUBLIC_APP_URL | Public base URL of the site, for example http://localhost:8801; also the auth base URL. Per site: set it in the site's .env.development locally and in its Vercel project. |
Rotating BETTER_AUTH_SECRET signs every user out.
Social sign-in (optional)
Google and GitHub sign-in turn on when both values of a pair are set:
- Google:
NEXT_PUBLIC_GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET. Redirect URI:<site-url>/api/auth/callback/google(add one per site). - GitHub:
NEXT_PUBLIC_GITHUB_CLIENT_ID,GITHUB_CLIENT_SECRET. Redirect URI:<site-url>/api/auth/callback/github(add one per site).
Passkeys
Set PASSKEY_RP_ID to the domain users sign in on (for example
app.example.com). It must match the deployed domain or passkey registration
fails.
Admin portal access
The admin portal (apps/backend) has its own sign-in, separate from the
sites:
| Variable | Purpose |
|---|---|
BACKEND_ADMIN_EMAILS | Comma-separated emails allowed to sign in. Removing an email revokes access immediately. |
BACKEND_SESSION_SECRET | Protects emailed sign-in codes. Generate with openssl rand -base64 32. |
Admins sign in at /login with a 6-digit code sent by email (zsend). In
production, configure ZSEND_API_KEY. Without it, the code is written to the
admin portal's server log (for example Vercel → Logs), so sign-in still works
before email is set up.
Site admins
ADMIN_EMAIL_DOMAINS: comma-separated domains whose users become site admins.ADMIN_NAME,ADMIN_EMAIL,ADMIN_PASSWORD: the initial admin created bybun run db:seed.