Authentication

Two-Factor Verification

Require an email code or a passkey after primary sign-in.

Dashboard starters include email one-time codes (OTP) and passkey second factors. Users keep signing in with GitHub and choose their second factor in Settings → Security. CloudConfig enforces verification on the server before completing sign-in.

Enable Verification

For an existing app, enable the capability in cloud.config.ts:

auth: {
  providers: { github: true },
  twoFactor: true,
}

Install better-auth and @better-auth/passkey version 1.7.7 or newer, then run pnpm db:generate and pnpm db:migrate. CloudConfig owns the extra auth tables; do not run Better Auth's separate migration CLI.

Deliver Email Codes

OTP delivery uses @dashboardstack/email, the shared Cloudflare email service. Configure it with pnpm exec cloudconfig auth email. This stores EMAIL_SERVICE_URL and EMAIL_API_KEY in your ignored environment file. Use your project's service key; its registered sender supplies the from address. Deployment requires and syncs both values. During development, a missing sender prints codes to the local server console. Production requires delivery and never logs verification codes.

Let Users Manage Their Factors

Email enrollment requires verifying a code before enabling 2FA. Codes are hashed, expire in five minutes, and allow five attempts.

Passkeys require a device PIN or biometrics and must belong to the account used for primary sign-in. Users can switch factors, add passkeys, or turn off 2FA after a recent sign-in. They must switch factors or turn off 2FA before removing their last active passkey.

Build a Custom Interface

The Nuxt dashboard template includes settings/TwoFactor.vue and /two-factor. Custom interfaces use useCloudConfigTwoFactor() for email codes and passkey ceremonies, and useCloudConfigAccount().getTwoFactorStatus() to read the selected method and pending challenge. Set twoFactor: { passkey: false } for email only.

After changing auth settings, run cloudconfig auth status to check required secrets before deploying.

Copyright © 2026