Skip to content

Configuration

The core of gau is the createAuth function, which you use to configure your auth setup. This guide covers all the available options in detail.

Here’s a quick overview of a typical configuration:

auth.ts
import { DrizzleAdapter } from '@rttnd/gau/adapters/drizzle'
import { createAuth } from '@rttnd/gau/core'
import { GitHub } from '@rttnd/gau/oauth'
import { db } from './db'
import { Accounts, Users } from './db/schema'
export const auth = createAuth({
adapter: DrizzleAdapter(db, Users, Accounts),
providers: [
GitHub({
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
}),
],
jwt: {
secret: process.env.AUTH_SECRET,
},
});

Type: Adapter, Required: Yes

The adapter is responsible for connecting gau to your database and handling db operations.

See the adapters guide.

Type: OAuthProvider[], Required: Yes

This option takes an array of configured OAuth providers that your application will support.

Each provider typically needs a clientId and clientSecret.

import { GitHub, Google } from '@rttnd/gau/oauth'
// ...
providers: [
GitHub({
clientId: process.env.GITHUB_CLIENT_ID!,
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
}),
Google({
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
}),
],

You can pass additional provider-specific options using params.

Check out the OAuth Providers section for a list of available providers and their specific configuration.

Type: { [providerId: string]: { [profileName: string]: { scopes?: string[], redirectUri?: string, params?: Record<string,string> } & ProviderSpecificOverrides } }
Default: {}

Define server-controlled, per-provider profiles to group auth provider configs. A profile can:

  • Override scopes used when building the provider authorization URL
  • Override the provider redirectUri (useful for desktop/mobile custom schemes)
  • Include provider-specific, strongly typed overrides (e.g. tenant, prompt for Microsoft)
  • Add arbitrary authorization params (appended to the provider auth URL)

Profiles are selected by name at login/link time, either via the client helpers or a ?profile= query parameter. If an unknown profile is requested, gau returns 400.

Example configuration:

auth.ts
import { createAuth } from '@rttnd/gau/core'
import { GitHub } from '@rttnd/gau/oauth'
export const auth = createAuth({
providers: [
GitHub({ clientId: process.env.GITHUB_CLIENT_ID!, clientSecret: process.env.GITHUB_CLIENT_SECRET! }),
],
profiles: {
github: {
// Minimal sign-in with user identity
basic: { scopes: ['read:user', 'user:email'] },
// Elevated permissions for repo automation
maintainer: { scopes: ['read:user', 'user:email', 'repo', 'read:org'] },
},
},
})

Select a profile when starting a flow:

  • Client: auth.signIn('github', { profile: 'maintainer' })
  • URL: GET /api/auth/login/github?profile=maintainer

Security notes:

  • Profiles are defined on the server; the client can only choose by name. Unknown names are rejected.
  • Use profiles to constrain allowed scope sets, this avoids exposing arbitrary scopes to the client.
  • If you use a custom redirectUri for desktop/mobile flows, set it in the profile and configure trustHosts appropriately for your return hosts.
  • Avoid putting secrets into params — they become part of the URL.
  • Precedence for settings (when supported by a provider like Microsoft):
    • profile override (typed) > query parameter (e.g. ?prompt=...) > provider default

Some providers accept extra authorization parameters via the provider config:

GitHub({
clientId: process.env.GITHUB_CLIENT_ID!,
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
params: { allow_signup: 'false' },
})

Profile params are merged on top of provider params for the selected profile.

Type: string, Default: '/api/auth'

Defines the relative path for all authentication API endpoints. You typically don’t need to change this.

The resulting URL is {baseURL}/{basePath}/{provider}.

If your frontend and backend are on different hosts, look for the baseURL config in the framework specific guides.

Type: object, Default: {}

This object allows you to configure session management.

Type: 'auto' | 'cookie' | 'token', Default: 'auto'

Determines how sessions are handled. See the Session Management guide for a detailed explanation of the different strategies.

These hooks let you customize the OAuth callback lifecycle, see Hooks.

Type: object, Default: {}

This object allows you to configure JSON Web Token settings for session management.

Type: string, Required: Yes

The secret used for signing and verifying JWTs.

For HS256, this can be a simple string. For the default and recommended ES256, this must be a base64url-encoded PKCS#8 private key. You can generate a valid secret using the CLI:

Terminal window
npx gau secret

Type: 'ES256' | 'HS256', Default: 'ES256'

The signing algorithm to use.

ES256 is the default and recommended. It uses a private/public key pair, which is more secure: only your server can sign tokens, but anyone with the public key can verify them. HS256 uses a single shared secret and is slightly faster, but both the signer and verifier need the same key.

Type: CryptoKey, Required: No

The private key to use for signing JWTs, only with ES256.

By default, this is derived from jwt.secret.

Type: number, Default: 3600 * 24 * 7 (7 days)

The time-to-live for session JWTs, in seconds. This determines how long a user stays logged in before needing to re-authenticate.

Type: string | string[]

Standard JWT claims for “issuer” (iss) and “audience” (aud). These are useful in multi-tenant applications or when your API needs to serve different clients. gau allows you to set default values for them here, and will automatically validate these claims when verifying a token.

Type: cookie.SerializeOptions, Default: { path: '/', sameSite: 'lax', secure: true, httpOnly: true }

Allows you to customize the options for the session cookie.

You can override the defaults. For example:

cookies: {
sameSite: 'strict',
},

Type: 'all' | string[], Default: []

This controls which domains are allowed to make requests to your auth endpoints and where users can be redirected after login.

  1. CSRF Protection: Only origins in this list can make POST requests (like signing out).
  2. Redirect Validation: The redirectTo parameter is only honored if it points to a trusted host.

The Origin header of incoming requests and the host of redirect URLs are checked against this list.

  • [] (Default): Only requests and redirects from/to the same origin as the app are allowed.

  • ['app.example.com', 'tauri.localhost']: For multi-domain setups or Tauri apps, you must add the allowed hostnames.

  • 'all': This is a convenient shortcut for development that disables these checks, but it is not recommended for production.

See the Security guide for more details.

Type: boolean | CORSOptions, Default: true

Configures Cross-Origin Resource Sharing (CORS) for all auth endpoints.

  • true (default): Enables CORS, defaults:
    • allowedOrigins: 'all' (all origins allowed)
    • allowCredentials: true (credentials reflected, origin echoed — never *)
    • allowedHeaders: ['Content-Type', 'Authorization', 'Cookie']
    • allowedMethods: ['GET', 'POST', 'OPTIONS']
  • false: Disables CORS completely (no CORS headers are added).
  • CORSOptions: Manually configure CORS headers.

Options:

  • allowedOrigins: 'all': Allow any origin. When allowCredentials: false, the response uses Access-Control-Allow-Origin: *. When credentials are enabled, the requesting origin is echoed.
  • allowedOrigins: 'trust': Reuses your trustHosts list. If trustHosts: 'all', every origin is allowed (origin echoed).
  • allowedOrigins: string[]: Provide an explicit allow-list. Items can be full origins (https://app.example.com), bare hostnames (app.example.com), host:port, or * (which allows any origin but still echoes the caller instead of using *).
  • allowCredentials: Toggles the Access-Control-Allow-Credentials header. If false and allowedOrigins === 'all', wildcard * is used; otherwise origin is echoed without the credentials header.
  • allowedHeaders: Array of request headers you want to allow (sent as a comma‑separated list).
  • allowedMethods: HTTP methods allowed for preflight / actual requests.
  • exposeHeaders: Extra response headers accessible to the browser (sets Access-Control-Expose-Headers).
  • maxAge: Seconds browsers may cache the preflight response.

Type: 'verifiedEmail' | 'always' | false, Default: 'verifiedEmail'

Controls how gau does automatic account linking.

Read the Account Linking guide for a full explanation.

  • 'verifiedEmail' (Default): On sign-in with a new provider, gau checks if the email is verified. If a user with that email already exists, the new account is linked to them. Otherwise, a new user is created.
  • 'always': Same as above, but links even if the provider doesn’t mark the email as verified.
  • false: Never auto-link. Every new provider sign-in creates a new user.

Type: boolean, Default: true

Controls whether a user can manually link a provider whose primary email differs from the user’s current primary email.

  • true (default): Allow linking even if the emails differ.
  • false: Reject manual linking with a 400 error when the emails differ.

This is only enforced during manual linking; it does not affect the auto-link checks above.

Type: boolean, Default: false

When enabled, during manual linking gau will update the user’s profile fields from the new provider (e.g. name, image). If the provider’s email matches the user’s current email and is verified, gau will also set emailVerified: true.

Type: object, Default: {}

This object allows you to configure role-based access control.

When configured, gau derives session.user.isAdmin for every validated session using the rules below.

Type: string, Default: 'user'

The default role assigned to newly created users.

Type: (context: { providerId: string, profile: any, request: Request }) => string | undefined, Required: No

A function to dynamically resolve the role for a new user at creation time. Return undefined to fall back to defaultRole.

Type: string[], Default: ['admin']

An array of role names that are considered admin roles for helper predicates and for the derived session.user.isAdmin flag.

Type: string[], Default: []

An array of user IDs that are always treated as admin for helper predicates and session.user.isAdmin.

For a full guide, see Role-Based Access Control.

Type: boolean Default: false

When enabled the provider or the profile can only be used for linking to an existing user account, not for signing in or signing up.

  • Provider level: pass linkOnly: true to the provider config.
  • Profile level: set linkOnly: true on a specific profile.

When a user completes an OAuth callback without an existing session for a link-only provider/profile, gau returns a 400 with a friendly message.