LogoLaunchSaaS

Authentication

Set up Better Auth in LaunchSaaS with social login (Google, GitHub), magic links, role-based access control, and secure session management.

LaunchSaaS uses Better Auth for authentication, providing a flexible and secure system with multiple authentication methods, session management, and role-based access control.

The boundary is:

  • apps/launchsaas/src/lib/auth/auth.ts owns Better Auth server construction
  • apps/launchsaas/src/lib/auth/auth-client.ts owns Better Auth client construction
  • apps/launchsaas/src/components/layout/better-auth-ui-provider.tsx bridges the auth client with router, i18n, and client-safe auth UI settings
  • apps/launchsaas/src/components/{auth,settings} contains the source-vendored Better Auth UI components consumed by the app

Setup

1. Generate Better Auth Secret

The BETTER_AUTH_SECRET is a random string used for encryption and generating hashes. Generate one using VictoryHub or run:

openssl rand -base64 32

Add it to your .env file:

BETTER_AUTH_SECRET="your-generated-secret-key"

2. Configure Email/Password (Optional)

Email/password authentication is enabled by default via features.auth.emailPasswordEnabled in src/configuration/features.ts. Login works without an email provider — the email capability is only needed for verification and password reset emails.

To disable it (e.g. for an OAuth-only app), set the flag to false:

// apps/your-app/src/configuration/features.ts
auth: {
  emailPasswordEnabled: false,
  ...
},

To require email verification on sign-up, set requireEmailVerification: true (also requires an email provider to be configured):

auth: {
  emailPasswordEnabled: true,
  requireEmailVerification: true,  // default is false
  ...
},

Login always works without an email provider. Verification and password reset emails are silently skipped when no email provider is configured — wire one with /launchsaas add-capability email to activate them.

Magic link is disabled by default. To enable it:

  1. Make sure an email provider is configured (required for sending the link)
  2. Open src/configuration/features.ts and set magicLinkEnabled to true:
auth: {
  ...
  magicLinkEnabled: true,
},

Once enabled, Better Auth will send a one-time sign-in link to the user's email. The sign-in UI automatically shows the magic link option.

Magic link requires an email provider. If capabilities.email is null, the magic link plugin will not be registered and requests will silently fail.

4. Configure GitHub OAuth (Optional)

  1. Go to GitHub Developer Settings
  2. Click on "OAuth Apps" → "New OAuth App"
  3. Fill in the registration form:
    • Application name: Your app name
    • Homepage URL: http://localhost:3000 (or your production URL)
    • Authorization callback URL: http://localhost:3000/api/auth/callback/github
  4. Click "Register application"
  5. Generate a client secret
  6. Add to your .env file:
NEXT_PUBLIC_GITHUB_CLIENT_ID="your-client-id"
GITHUB_CLIENT_SECRET="your-client-secret"

Create separate OAuth apps for development and production environments. They require different callback URLs.

5. Configure Google OAuth (Optional)

  1. Go to Google Cloud Console
  2. Create a new project or select an existing one
  3. Go to CredentialsCreate CredentialsOAuth client ID
  4. Configure OAuth consent screen if prompted
  5. Create OAuth Client ID:
    • Application type: Web application
    • Authorized JavaScript origins: http://localhost:3000
    • Authorized redirect URIs: http://localhost:3000/api/auth/callback/google
  6. Add to your .env file:
NEXT_PUBLIC_GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
GOOGLE_CLIENT_SECRET="your-client-secret"

5. Configure CAPTCHA (Optional)

CAPTCHA activates automatically when CAPTCHA_SECRET_KEY is set. No code change needed.

See the Captcha guide for provider options and setup instructions.

Features

LaunchSaaS authentication includes:

  • Email/Password - Sign up, sign in, and password reset (enabled by default; set emailPasswordEnabled: false in src/configuration/features.ts to disable; set requireEmailVerification: true to require address confirmation on sign-up)
  • Magic Links - Passwordless authentication (disabled by default; set magicLinkEnabled: true in src/configuration/features.ts to enable — requires email provider)
  • Social Login - Google and GitHub OAuth (enabled by adding client ID env vars)
  • CAPTCHA - Bot protection via Cloudflare Turnstile, Google reCAPTCHA, hCaptcha, or CaptchaFox (enabled by adding CAPTCHA_SECRET_KEY; see Captcha guide)
  • Session Management - Server-side session handling
  • Role-Based Access - User and admin roles
  • App-Owned Auth Wiring - Server, client, and auth UI stay in your app

User Roles

User Role

Default role for all registered users. Has access to:

  • Billing page (/billing)
  • Settings (/settings/profile, /settings/security, /settings/preferences)
  • Subscription management

Admin Role

Elevated privileges for administrators. Has access to:

  • Admin panel (/admin/users, /admin/orders, /admin/entitlements)
  • User management
  • All user features

Production Checklist

Before going to production, ensure:

  • BETTER_AUTH_SECRET is a strong, unique secret
  • NEXT_PUBLIC_APP_URL is set to your production domain
  • Social OAuth apps are configured with production callback URLs
  • Email service is configured and domain verified

References

Next Steps