docs/content/docs/guides/saml-sso-with-okta.mdx
This guide walks you through setting up SAML Single Sign-On (SSO) with your Identity Provider (IdP), using Okta as an example. For advanced configuration details and the full API reference, check out the SSO Plugin Documentation.
SAML (Security Assertion Markup Language) is an XML-based standard for exchanging authentication and authorization data between an Identity Provider (IdP) (e.g., Okta, Azure AD, OneLogin) and a Service Provider (SP) (in this case, Better Auth).
In this setup:
Log in to your Okta Admin Console
Navigate to Applications > Applications
Click "Create App Integration"
Select "SAML 2.0" as the Sign-in method
Configure the following settings:
http://localhost:3000/api/auth/sso/saml2/callback/sso). Note: sso is your providerIdhttp://localhost:3000/api/auth/sso/saml2/sp/metadata)Download the IdP metadata XML file and certificate
Here’s an example configuration for Okta in a dev environment:
const ssoConfig = {
defaultSSO: [{
domain: "localhost:3000", // Your domain
providerId: "sso",
samlConfig: {
// SP Configuration
issuer: "http://localhost:3000/api/auth/sso/saml2/sp/metadata",
entryPoint: "https://trial-1076874.okta.com/app/trial-1076874_samltest_1/exktofb0a62hqLAUL697/sso/saml",
callbackUrl: "http://localhost:3000/api/auth/sso/saml2/sp/acs/sso",
// IdP Configuration
idpMetadata: {
entityID: "https://trial-1076874.okta.com/app/exktofb0a62hqLAUL697/sso/saml/metadata",
singleSignOnService: [{
Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect",
Location: "https://trial-1076874.okta.com/app/trial-1076874_samltest_1/exktofb0a62hqLAUL697/sso/saml"
}],
},
cert: `-----BEGIN CERTIFICATE-----
MIIDqjCCApKgAwIBAgIGAZhVGMeUMA0GCSqGSIb3DQEBCwUAMIGVMQswCQYDVQQGEwJVUzETMBEG
...
[Your Okta Certificate]
...
-----END CERTIFICATE-----`,
// SP Metadata
spMetadata: {
metadata: `<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
entityID="http://localhost:3000/api/sso/saml2/sp/metadata">
...
[Your SP Metadata XML]
...
</md:EntityDescriptor>`
}
}
}]
}
You can configure multiple SAML providers for different domains:
const ssoConfig = {
defaultSSO: [
{
domain: "company.com",
providerId: "company-okta",
samlConfig: {
// Okta SAML configuration for company.com
}
},
{
domain: "partner.com",
providerId: "partner-adfs",
samlConfig: {
// ADFS SAML configuration for partner.com
}
},
{
domain: "contractor.org",
providerId: "contractor-azure",
samlConfig: {
// Azure AD SAML configuration for contractor.org
}
}
]
}
You can start an SSO flow in three ways:
1. Explicitly by providerId (recommended):
// Explicitly specify which provider to use
await authClient.signIn.sso({
providerId: "company-okta",
callbackURL: "/dashboard"
});
2. By email domain matching:
// Automatically matches provider based on email domain
await authClient.signIn.sso({
email: "[email protected]",
callbackURL: "/dashboard"
});
3. By specifying domain:
// Explicitly specify domain for matching
await authClient.signIn.sso({
domain: "partner.com",
callbackURL: "/dashboard"
});
Important Notes:
localhost:3000 - adjust URLs for your environmentcallbackUrl is the SAML ACS endpoint URL. If omitted, it defaults to {baseURL}/sso/saml2/sp/acs/{providerId}. The post-login destination is controlled by callbackURL in signIn.sso()For dynamic registration, you should register SAML providers using the API. See the SSO Plugin Documentation for detailed registration instructions.
Example registration:
await authClient.sso.register({
providerId: "okta-prod",
issuer: "https://your-domain.com",
domain: "your-domain.com",
samlConfig: {
// Your production SAML configuration
}
});