Single Sign-On (SSO)

OIDC OAuth2 SSO

Single Sign-On (SSO) allows users to authenticate with multiple applications using a single set of credentials. This plugin supports OpenID Connect (OIDC) and OAuth2 providers.

SAML support is coming soon. Upvote the feature request on our GitHub

Installation

Add Plugin to the server

auth.ts
import { betterAuth } from "better-auth"
import { sso } from "better-auth/plugins/sso";
 
const auth = betterAuth({
    plugins: [ 
        sso() 
    ] 
})

Migrate the database

Run the migration or generate the schema to add the necessary fields and tables to the database.

npx @better-auth/cli migrate

See the Schema section to add the fields manually.

Add the client plugin

auth-client.ts
import { createAuthClient } from "better-auth/client"
import { ssoClient } from "better-auth/client/plugins"
 
const authClient = createAuthClient({
    plugins: [ 
        ssoClient() 
    ] 
})

Usage

Register an OIDC Provider

To register an OIDC provider, use the createOIDCProvider endpoint and provide the necessary configuration details for the provider.

A redirect URL will be automatically generated using the provider ID. For instance, if the provider ID is hydra, the redirect URL would be {baseURL}/api/auth/sso/hydra. Note that /api/auth may vary depending on your base path configuration.

register-provider.ts
import { authClient } from "@/lib/auth-client";
 
// only with issuer if the provider supports discovery
await authClient.sso.register({
    issuer: "https://idp.example.com",
    providerId: "example-provider",
});
 
// with all fields
await authClient.sso.register({
    issuer: "https://idp.example.com",
    domain: "example.com",
    clientId: "client-id",
    clientSecret: "client-secret",
    authorizationEndpoint: "https://idp.example.com/authorize",
    tokenEndpoint: "https://idp.example.com/token",
    jwksEndpoint: "https://idp.example.com/jwks",
    mapping: {
        id: "sub",
        email: "email",
        emailVerified: "email_verified",
        name: "name",
        image: "picture",
    },
    providerId: "example-provider",
});

Sign In with SSO

To sign in with an SSO provider, you can call signIn.sso

You can sign in using the email with domain matching:

sign-in.ts
const res = await authClient.signIn.sso({
    email: "user@example.com",
    callbackURL: "/dashboard",
});

or you can specify the domain:

sign-in-domain.ts
const res = await authClient.signIn.sso({
    domain: "example.com",
    callbackURL: "/dashboard",
});

You can also sign in using the organization slug if a provider is associated with an organization:

sign-in-org.ts
const res = await authClient.signIn.sso({
    organizationSlug: "example-org",
    callbackURL: "/dashboard",
});

Alternatively, you can sign in using the provider's ID:

sign-in-provider-id.ts
const res = await authClient.signIn.sso({
    providerId: "example-provider-id",
    callbackURL: "/dashboard",
});

To use the server api you can use signInSSO

sign-in-org.ts
const res = await auth.api.signInSSO({
    body: {
        organizationSlug: "example-org",
        callbackURL: "/dashboard",
    }
});

When a user is authenticated, if the user does not exist, the user will be provisioned using the provisionUser function. If the organization provisioning is enabled and a provider is associated with an organization, the user will be added to the organization.

auth.ts
const auth = betterAuth({
    plugins: [
        sso({
            provisionUser: async (user) => {
                // provision user
            },
            organizationProvisioning: {
                disabled: false,
                defaultRole: "member",
                getRole: async (user) => {
                    // get role if needed
                },
            },
        }),
    ],
});

Schema

The plugin requires additional fields in the ssoProvider table to store the provider's configuration.

Field NameTypeKeyDescription
idstringA database identifier
issuerstring-The issuer identifier
domainstring-The domain of the provider
oidcConfigstring-The OIDC configuration
userIdstring-The user id
providerIdstring-The provider id. Used to identify a provider and to generate a redirect url.
organizationIdstring-The organization Id. If provider is linked to an organization.

Options

Server

provisionUser: A custom function to provision a user when they sign in with an SSO provider.

organizationProvisioning: Options for provisioning users to an organization.

PropTypeDefault
provisionUser?
function
-
organizationProvisioning?
object
-

On this page