Two-Factor Verification
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.