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:
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, },});adapter
Section titled “adapter”Type:
Adapter, Required: Yes
The adapter is responsible for connecting gau to your database and handling db operations.
See the adapters guide.
providers
Section titled “providers”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.
profiles
Section titled “profiles”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
scopesused 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,promptfor 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:
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
redirectUrifor desktop/mobile flows, set it in the profile and configuretrustHostsappropriately 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
- profile override (typed) > query parameter (e.g.
Extra params
Section titled “Extra params”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.
basePath
Section titled “basePath”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.
session
Section titled “session”Type:
object, Default:{}
This object allows you to configure session management.
session.strategy
Section titled “session.strategy”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.
jwt.secret
Section titled “jwt.secret”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:
npx gau secretpnpm dlx gau secretyarn dlx gau secretbunx gau secretnlx gau secretjwt.algorithm
Section titled “jwt.algorithm”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.
jwt.privateKey
Section titled “jwt.privateKey”Type:
CryptoKey, Required: No
The private key to use for signing JWTs, only with ES256.
By default, this is derived from jwt.secret.
jwt.ttl
Section titled “jwt.ttl”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.
jwt.iss, jwt.aud, and jwt.sub
Section titled “jwt.iss, jwt.aud, and jwt.sub”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.
cookies
Section titled “cookies”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',},trustHosts
Section titled “trustHosts”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.
- CSRF Protection: Only origins in this list can make
POSTrequests (like signing out). - Redirect Validation: The
redirectToparameter 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. WhenallowCredentials: false, the response usesAccess-Control-Allow-Origin: *. When credentials are enabled, the requesting origin is echoed.allowedOrigins: 'trust': Reuses yourtrustHostslist. IftrustHosts: '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 theAccess-Control-Allow-Credentialsheader. IffalseandallowedOrigins === '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 (setsAccess-Control-Expose-Headers).maxAge: Seconds browsers may cache the preflight response.
autoLink
Section titled “autoLink”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,gauchecks 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.
allowDifferentEmails
Section titled “allowDifferentEmails”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.
updateUserInfoOnLink
Section titled “updateUserInfoOnLink”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.
roles.defaultRole
Section titled “roles.defaultRole”Type:
string, Default:'user'
The default role assigned to newly created users.
roles.resolveOnCreate
Section titled “roles.resolveOnCreate”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.
roles.adminRoles
Section titled “roles.adminRoles”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.
roles.adminUserIds
Section titled “roles.adminUserIds”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.
linkOnly
Section titled “linkOnly”Type:
booleanDefault: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: trueto the provider config. - Profile level: set
linkOnly: trueon 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.