- Client registration (static trusted clients and dynamic registration)
- Authorization Code Flow
- Refresh token support
- OAuth consent screens (with bypass support for trusted apps)
- UserInfo endpoint
- JWKS endpoint integration via the JWT plugin
- Custom claims
Installation
Add the plugin to your auth config
auth.ts
Migrate the database
Add the client plugin
auth-client.ts
Registering clients
Dynamic registration
Clients can register via the/oauth2/register endpoint (RFC 7591):
Trusted clients (static configuration)
For first-party applications, configure trusted clients directly. They bypass database lookups and can skip the consent screen:auth.ts
OIDC endpoints
The plugin exposes these standard OIDC endpoints:| Endpoint | Description |
|---|---|
GET /api/auth/oauth2/authorize | Authorization endpoint |
POST /api/auth/oauth2/token | Token endpoint |
GET /api/auth/oauth2/userinfo | UserInfo endpoint |
POST /api/auth/oauth2/consent | Consent submission |
POST /api/auth/oauth2/register | Dynamic client registration |
GET /api/auth/.well-known/openid-configuration | OIDC discovery document |
UserInfo endpoint
The UserInfo endpoint returns claims based on the granted scopes:| Scope | Claims returned |
|---|---|
openid | sub (user ID) |
profile | name, picture, given_name, family_name |
email | email, email_verified |
Custom claims
auth.ts
Consent screen
By default, Better Auth shows a built-in consent screen. Customize it with aconsentPage path:
auth.ts
consent_code, client_id, and scope query parameters. After the user consents, call:
Trusted clients with
skipConsent: true bypass the consent screen entirely.Handling login
When users are not signed in and reach the authorization endpoint, they are redirected tologinPage. After a new session is created, the plugin automatically continues the authorization flow.
auth.ts
JWKS integration
Combine with the JWT plugin for asymmetric ID token signing:auth.ts
When
useJWTPlugin is false (default), ID tokens are signed with HMAC-SHA256 using the application secret.Customize OIDC metadata
auth.ts
Schema
oauthApplication
| Field | Type | Description |
|---|---|---|
id | string | Primary key |
clientId | string | Unique OAuth client identifier |
clientSecret | string | Client secret (optional for public clients) |
name | string | Application name |
redirectUrls | string | Comma-separated redirect URLs |
type | string | Client type (web, native, etc.) |
disabled | boolean | Whether the client is disabled |
userId | string | Owner user ID (optional) |
icon | string | Application icon URL |
metadata | string | Additional metadata (JSON) |
createdAt | Date | Creation timestamp |
updatedAt | Date | Last update timestamp |
oauthAccessToken
| Field | Type | Description |
|---|---|---|
accessToken | string | The access token |
refreshToken | string | The refresh token |
accessTokenExpiresAt | Date | Access token expiration |
refreshTokenExpiresAt | Date | Refresh token expiration |
clientId | string | Associated OAuth client |
userId | string | Associated user |
scopes | string | Granted scopes (comma-separated) |
oauthConsent
| Field | Type | Description |
|---|---|---|
userId | string | User who gave consent |
clientId | string | OAuth client |
scopes | string | Consented scopes (comma-separated) |
consentGiven | boolean | Whether consent was granted |