How to Set Up Logto SSO for Enterprise: OIDC and SAML Configuration Guide
Logto enables enterprise SSO through configurable OIDC or SAML connectors stored in the sso_connectors table, which trigger domain-based authentication flows and optionally provision users into organizations via Just-In-Time (JIT) provisioning.
Setting up Logto SSO for enterprise requires configuring SSO connectors that bridge your identity provider (IdP) with Logto's authentication system. The open-source logto-io/logto repository implements this through a modular architecture where connector metadata, provider configurations, and user identities are stored across dedicated tables. This guide walks through the complete implementation based on the actual source code, from creating connectors via the Management API to handling the authentication callback flow.
Understanding Logto Enterprise SSO Architecture
Logto implements enterprise SSO through SSO connectors—configurable OIDC or SAML providers that link to user identities. The architecture comprises three core components:
- Connector Configuration: Metadata and provider settings stored in the
sso_connectorstable, validated byssoConnectorMetadataGuardinpackages/schemas/src/types/sso-connector.ts - Interaction Flow: Domain-based detection that routes users to the IdP via
POST /api/interaction/single-sign-on/:connectorId/authorization-url - User Provisioning: Automatic creation of records in
user_sso_identities(managed bypackages/core/src/queries/user-sso-identities.ts) and optional JIT organization membership
The providerConfig field within SsoConnectorWithProviderConfig stores provider-specific settings such as OIDC discovery URLs, SAML metadata, and token storage flags.
Step 1: Create an SSO Connector via Management API
You can create an SSO connector through the Logto Console (Organization → SSO connectors) or programmatically via the Management API. The endpoint POST /api/sso-connectors accepts connector metadata and provider configuration.
import fetch from 'node-fetch'
const response = await fetch('https://your-logto.example.com/api/sso-connectors', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${ADMIN_API_TOKEN}`,
},
body: JSON.stringify({
connectorName: 'MyCompany Azure AD',
providerName: 'AzureAdOidc',
providerType: 'oidc',
providerLogo: 'https://example.com/logo.png',
providerConfig: {
discoveryUrl: 'https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration',
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
enableTokenStorage: true,
},
domain: ['mycompany.com'],
}),
})
const connector = await response.json()
console.log('Created connector:', connector)
The connector metadata is validated against ssoConnectorMetadataGuard in packages/schemas/src/types/sso-connector.ts, which ensures proper structure for fields like connectorName, logo, and providerType.
Step 2: Configure OIDC or SAML Provider Settings
The providerConfig object within SsoConnectorWithProviderConfig contains provider-specific authentication parameters. For OIDC providers, you must supply:
discoveryUrl: The OpenID Connect discovery endpointclientIdandclientSecret: Application credentials from your IdPenableTokenStorage: Boolean flag to persist IdP tokens for downstream API calls
For SAML providers, you provide SAML metadata XML or URLs instead of OIDC discovery documents. These settings are stored in the sso_connectors table and retrieved during the authentication flow by packages/core/src/libraries/sso-connector.ts.
Step 3: Assign Corporate Email Domains
Logto uses email domain matching to trigger SSO authentication automatically. When a user enters an email address, Logto normalizes it to lower-case and checks against the domains associated with enabled connectors.
Domains are validated against singleSignOnDomainBlackList in packages/schemas/src/types/sso-connector.ts to prevent conflicts with reserved domains. Configure this in the connector's domain array field as shown in the API example above.
Step 4: Enable Just-In-Time (JIT) Provisioning
Just-In-Time provisioning automatically adds new SSO-authenticated users to specified organizations without manual invitation. Enable this in the Console under Organization → Just-in-time provisioning, or via the Management API.
When JIT is enabled, successful authentication through packages/core/src/routes/experience/verification-routes/enterprise-sso-verification.ts creates both a user account and an organization membership record. The verification record is stored as enterprise-sso type, and the user is linked via the user_sso_identities table as implemented in packages/core/src/queries/user-sso-identities.ts.
The SSO Authentication Flow
The enterprise SSO interaction flow involves two primary API endpoints managed by Logto's core interaction system:
-
Authorization URL Generation: The frontend calls
POST /api/interaction/single-sign-on/:connectorId/authorization-urlto obtain the IdP redirect URL. This endpoint is defined in the core changelog and implemented in the experience API routes. -
Authentication Callback: After the IdP authenticates the user, Logto receives the callback via
POST /api/interaction/single-sign-on/:connectorId/authentication. The backend validates the response, creates or updates the user record, and establishes the session.
// Frontend: Initiate SSO flow
const authRes = await fetch(`/api/interaction/single-sign-on/${connectorId}/authorization-url`, {
method: 'POST',
credentials: 'include',
})
const { redirectUrl } = await authRes.json()
window.location.href = redirectUrl
// After IdP redirects back, the backend handles the rest automatically
// and returns a session token to the client
The enterprise-sso-verification.ts file in packages/core/src/routes/experience/classes/verifications/ handles the verification state during this process.
Accessing Stored IdP Tokens
When enableTokenStorage is set to true in the provider configuration, Logto persists the IdP access token. Retrieve this token to call downstream APIs on behalf of the user:
const tokenRes = await fetch('/api/sso-connector-token', {
method: 'GET',
credentials: 'include',
})
const { accessToken } = await tokenRes.json()
// Use accessToken to authenticate with the third-party API
This functionality is managed by the SSO connector token library and exposed through the /api/sso-connector-token endpoint.
Key Implementation Files
packages/schemas/src/types/sso-connector.ts: Defines the data model and validation guards includingssoConnectorMetadataGuardandSsoConnectorWithProviderConfigpackages/core/src/queries/sso-connectors.ts: Database operations for thesso_connectorstablepackages/core/src/queries/user-sso-identities.ts: Manages theuser_sso_identitiestable for linking users to SSO providerspackages/core/src/routes/experience/verification-routes/enterprise-sso-verification.ts: Handles verification records for enterprise SSO flowspackages/core/src/libraries/sso-connector.ts: Core library for building authorization URLs and processing callbackspackages/integration-tests/src/tests/api/experience-api/sign-in-interaction/enterprise-sso.test.ts: End-to-end tests demonstrating the full SSO flow
Summary
- SSO connectors in Logto are stored in the
sso_connectorstable and configured viaPOST /api/sso-connectorswith metadata validated byssoConnectorMetadataGuard - Domain-based routing automatically detects enterprise users by matching email domains against connector configurations
- OIDC and SAML are supported through the
providerConfigfield inSsoConnectorWithProviderConfig - JIT provisioning automatically adds new users to organizations when enabled in the organization settings
- Token storage allows persisting IdP access tokens for downstream API calls by setting
enableTokenStorage: true
Frequently Asked Questions
What identity providers does Logto support for enterprise SSO?
Logto supports any OIDC or SAML 2.0 compatible identity provider. This includes Microsoft Azure AD, Okta, Google Workspace, Auth0, and custom corporate IdPs. The providerType field in the connector configuration accepts either oidc or saml, with provider-specific settings stored in the providerConfig object.
How does domain-based SSO detection work in Logto?
When a user enters an email address during sign-in, Logto normalizes the domain to lower-case and checks it against the domain arrays of all enabled SSO connectors. If a match is found, the user is redirected to the corresponding IdP. Domains are validated against singleSignOnDomainBlackList to prevent conflicts with reserved system domains.
Can I store the identity provider token for downstream API calls?
Yes. Set enableTokenStorage: true in the providerConfig when creating the connector. Logto will store the IdP access token after authentication, which you can retrieve via GET /api/sso-connector-token. This allows your application to call the identity provider's APIs on behalf of the user.
What is Just-In-Time (JIT) provisioning in Logto?
JIT provisioning automatically adds newly registered SSO users to specified organizations without requiring manual invitations. When enabled for an organization, users who authenticate through an enterprise SSO connector for the first time are immediately granted membership. This is handled by the verification logic in enterprise-sso-verification.ts and recorded in the user_sso_identities table.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →