The OIDC Provider plugin enables you to build and manage your own OpenID Connect (OIDC) provider using Better Auth. Other services can authenticate users through your OIDC provider instead of relying on third-party services like Okta or Azure AD. Key capabilities:Documentation Index
Fetch the complete documentation index at: https://mintlify.com/better-auth/better-auth/llms.txt
Use this file to discover all available pages before exploring further.
- 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 |