Skip to main content
Vertz ships factory functions for OAuth providers. Configure your credentials, add the provider to createAuth(), and the framework handles the full flow: authorization redirect, callback handling, PKCE, token exchange, and account linking.

Setup

This generates two routes per provider:

Provider configuration

All providers share the same config interface:

Default scopes

ProviderDefault scopesEmail trust
Googleopenid, email, profileTrusted (verified by OIDC)
GitHubread:user, user:emailUntrusted
Discordidentify, emailUntrusted

Account linking

When a user signs in via OAuth, the system follows a three-path resolution:
  1. Existing link found — The provider account is already linked to a user. Sign them in.
  2. Trusted email match — The provider verifies the email (Google OIDC). If a user with that email exists, auto-link the provider account and sign in.
  3. No match — Create a new user account and link the provider account.
GitHub and Discord don’t verify email ownership at the OAuth level, so they never auto-link to existing accounts. Each GitHub/Discord sign-in creates a new account unless a link already exists in the OAuthAccountStore.

Required configuration

Encryption key

OAuth state is stored in an encrypted cookie (AES-256-GCM). You must provide an encryption key:
Generate one:

OAuthAccountStore

The account store tracks which provider accounts are linked to which users:
For development, use the built-in in-memory store:
For production, implement the interface backed by your database.

Redirect configuration

Control where users land after OAuth:

Security

ProtectionHow
PKCES256 code challenge for Google and Discord (GitHub doesn’t support PKCE)
State cookieAES-256-GCM encrypted, prevents CSRF on the callback
OIDC nonceValidated in Google ID tokens to prevent replay attacks
Rate limiting10 OAuth initiations per 5 minutes per IP
Email validationEmpty emails rejected before user creation

Environment variables

Use createEnv() to validate OAuth credentials at startup:

OAuth-only users

Users created via OAuth have a null password hash. If they attempt email/password sign-in, the auth system runs a timing-safe dummy bcrypt comparison — same response time, always fails. This prevents user enumeration via the sign-in endpoint.