How to Use Logto for SSO: Enterprise Single Sign-On Implementation Guide

Logto implements native SSO support through OpenID Connect and SAML connectors that automatically authenticate users via external identity providers, storing federated identities in the user_sso_identities table while enabling just-in-time provisioning for enterprise domains.

Logto is an open-source identity infrastructure that treats single sign-on (SSO) as a first-class feature. The logto-io/logto repository provides a complete implementation allowing any OIDC or SAML identity provider to integrate seamlessly into the authentication flow. This guide explains how to configure and implement SSO using Logto's management APIs, interaction endpoints, and frontend hooks.

Understanding Logto SSO Architecture

Logto's SSO implementation consists of three architectural layers that work together to orchestrate authentication between your application and external identity providers.

Connector Management Layer

The connector management layer stores SSO configurations in the sso_connectors table, including metadata, client credentials, and token storage flags. After successful authentication, identity data returned by the IdP is persisted in the user_sso_identities table. This schema design is documented in packages/schemas/CHANGELOG.md (lines 1319-1322), which introduces these tables for enterprise connector storage.

Interaction API Layer

The core routing layer in packages/core/src/routes/interaction/single-sign-on.ts exposes three critical endpoints that drive the SSO flow:

  • POST /api/interaction/single-sign-on/:connectorId/authorization-url – Builds the IdP authorization URL for redirecting users
  • POST /api/interaction/single-sign-on/:connectorId/authentication – Processes the IdP callback, validates token sets, and stores SSO identities
  • GET /api/interaction/single-sign-on/connectors – Returns enabled connectors for a given email domain, enabling just-in-time provisioning decisions

Verification Helpers Layer

The low-level SSO logic resides in packages/core/src/libraries/verification-helpers/single-sign-on.ts. This library handles building authorization URLs, exchanging authorization codes for tokens, and persisting federated token sets when the storage flag is enabled. Session-specific SSO data is managed through single-sign-on-session.ts, which maintains the sso_identities claim containing details, issuer, and identityId fields.

Configuring SSO Connectors via Management API

To enable SSO, first create a connector configuration using Logto's Management API. The endpoint POST /api/sso-connectors accepts OIDC or SAML configurations and associates them with specific email domains.

POST https://<your-logto-domain>/api/sso-connectors
Content-Type: application/json
Authorization: Bearer <management-api-token>

{
  "name": "Okta OIDC",
  "type": "oidc",
  "connectorId": "okta-oidc",
  "config": {
    "clientId": "YOUR_CLIENT_ID",
    "clientSecret": "YOUR_CLIENT_SECRET",
    "authorizationEndpoint": "https://dev-123.okta.com/oauth2/v1/authorize",
    "tokenEndpoint": "https://dev-123.okta.com/oauth2/v1/token",
    "userinfoEndpoint": "https://dev-123.okta.com/oauth2/v1/userinfo",
    "issuer": "https://dev-123.okta.com"
  },
  "domains": ["example.com"],
  "metadata": {
    "tokenStorageEnabled": true
  }
}

The domains array determines which email addresses trigger this specific connector. Setting tokenStorageEnabled to true allows Logto to store the federated token set, enabling later retrieval of IdP access tokens without re-authentication.

Implementing Domain-Based SSO Detection

The Logto Experience SPA automatically detects SSO requirements based on email domains. The frontend uses the useCheckSingleSignOn hook defined in packages/experience/src/hooks/use-check-single-sign-on.ts to query the backend and initiate the flow.

import { useEffect } from 'react';
import useCheckSingleSignOn from '@/hooks/use-check-single-sign-on';

export default function SignIn() {
  const { startSingleSignOn } = useCheckSingleSignOn();

  const handleEmailSubmit = async (email: string) => {
    // Contacts GET /api/interaction/single-sign-on/connectors
    const connector = await startSingleSignOn(email);
    if (connector) {
      // Redirect to the IdP authorization URL
      window.location.href = connector.authorizationUrl;
    } else {
      // Proceed with standard password authentication
    }
  };

  return /* UI calling handleEmailSubmit on form submit */;
}

When a domain is marked as SSO-only, Logto rejects normal password sign-in attempts with the session.sso_required error code, forcing users through the SSO flow. This enforcement occurs in the interaction layer defined in packages/core/src/routes/interaction/single-sign-on.ts.

Processing SSO Authentication Callbacks

After the identity provider authenticates the user, Logto processes the callback at the authentication endpoint. The backend logic in packages/core/src/libraries/verification-helpers/single-sign-on.ts performs the following steps:

  1. Exchanges the authorization code for tokens (access token, ID token)
  2. Validates the ID token and fetches userinfo from the IdP
  3. Persists the federated token set if tokenStorageEnabled is true
  4. Creates or updates the user_sso_identities claim with the identity data
  5. Issues a Logto session and redirects back to the application

The session schema defined in packages/core/src/libraries/verification-helpers/single-sign-on-session.ts stores the SSO identity as an array of objects containing details, issuer, and identityId, which downstream APIs include in issued tokens.

Just-in-Time Provisioning and Security

Logto supports Just-in-Time (JIT) provisioning for enterprise SSO connectors. When a user signs in with an email domain matching a configured connector, Logto automatically provisions the user into the associated organization. This feature is documented in packages/schemas/CHANGELOG.md (lines 1040-1048) under the JIT provisioning section.

For security-sensitive deployments, you can configure email domains to require SSO exclusively. When enabled, authentication attempts using passwords for those domains are blocked at the API level, ensuring enterprise users always authenticate through the corporate identity provider.

Summary

  • Logto stores SSO configurations in the sso_connectors table and identity data in user_sso_identities, enabling persistent federated authentication.
  • Three interaction endpoints (authorization-url, authentication, connectors) orchestrate the complete SSO flow in packages/core/src/routes/interaction/single-sign-on.ts.
  • Frontend detection uses the useCheckSingleSignOn hook to automatically redirect users based on email domain matching.
  • Token storage can be enabled per-connector to cache IdP access tokens for downstream API calls without re-authentication.
  • JIT provisioning automatically adds SSO users to organizations when they first sign in with a matching domain.
  • SSO-only domains enforce strict identity provider authentication by rejecting password-based logins with session.sso_required errors.

Frequently Asked Questions

What identity provider protocols does Logto support for SSO?

Logto supports both OpenID Connect (OIDC) and SAML identity providers for enterprise SSO. The connector configuration in packages/core/src/libraries/verification-helpers/single-sign-on.ts abstracts the protocol differences, allowing you to configure OIDC endpoints (authorization, token, userinfo) or SAML assertions through the same Management API.

Can Logto store tokens from the external identity provider?

Yes. When creating an SSO connector, set metadata.tokenStorageEnabled to true. This persists the federated token set (access tokens, refresh tokens) in Logto's storage, allowing your applications to retrieve IdP access tokens via subsequent API calls without requiring the user to re-authenticate with the external provider.

How does Logto handle user provisioning for SSO authentication?

Logto implements Just-in-Time (JIT) provisioning through the domain-matching system. When a user attempts to sign in with an email domain associated with an SSO connector (queried via GET /api/interaction/single-sign-on/connectors), Logto automatically provisions the user into the corresponding organization if they don't already exist, creating a seamless onboarding experience for enterprise users.

What happens if a user tries to use a password for an SSO-only domain?

Logto enforces email-domain guards that reject password authentication attempts for domains marked as SSO-only. When the useCheckSingleSignOn hook detects a matching domain or when a password login is attempted for such domains, the API returns the session.sso_required error code, forcing the user to authenticate through the configured identity provider rather than traditional credentials.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →