How to Set Up Custom Domains in Logto: Complete Configuration Guide
You can set up custom domains in Logto by adding your domain in the Admin Console, verifying DNS ownership via TXT records, and updating your application Redirect URIs to use the new branded endpoint instead of the default *.logto.app domain.
Setting up custom domains in Logto allows you to replace the default *.logto.app endpoints with your own branded hostname (e.g., auth.my-company.com), ensuring brand consistency across the sign-in experience, OIDC issuer URLs, and SDK endpoints. According to the logto-io/logto source code, this feature operates at the tenant level and automatically propagates to all URL-generating components including the admin console, SAML applications, and protected apps.
What Are Custom Domains in Logto?
Custom domains in Logto are branded hostnames that replace the default Logto Cloud endpoints. Each tenant can store up to 10 custom domains in an array defined in packages/core/src/utils/tenant.ts. The first verified domain in this list becomes the primary endpoint, meaning all OIDC issuer URLs, authorization endpoints, and SDK configurations automatically switch to use your custom hostname instead of the generic Logto domain.
The system enforces ownership verification through DNS TXT records validated via Cloudflare before activation, preventing unauthorized domain usage. Once verified, the domain-aware URL generators—specifically getTenantUrls and getIssuerUrl in packages/core/src/utils/tenant.ts and packages/core/src/app/init.ts—automatically build URLs using your custom domain.
How the Custom Domain System Works
Tenant-Level Domain Storage
Logto stores the custom domain list directly on the tenant object. The utility functions getTenantUrls and getTenantIdFromCustomDomain in packages/core/src/utils/tenant.ts resolve which domain to use based on the incoming request host. If a custom domain matches and is verified, the system uses it as the base URL for all subsequent operations.
Domain Verification Architecture
Before a domain becomes active, you must prove ownership through the verification flow defined in packages/core/src/routes/domain.openapi.json. When you create a domain via the API at POST /domains, Logto generates a unique TXT record value. You publish this record with your DNS provider, and Logto validates it through Cloudflare. Only after successful verification can the domain status change to "verified" and become eligible for use.
Automatic URL Propagation
Once verified, the custom domain automatically propagates throughout the system. The getIssuerUrl function ensures that OIDC discovery documents, authorization endpoints, and token endpoints all reference your custom domain. This propagation extends to the frontend through the Admin Console UI located at packages/console/src/pages/TenantSettings/TenantDomainSettings/MultipleCustomDomainsFormField/index.tsx, which monitors domain status in real-time.
Protected App Synchronization
When you add or remove a custom domain, Logto updates protected application configurations automatically. The library in packages/core/src/libraries/protected-app.ts synchronizes the SDK endpoint URL to ensure token-exchange calls continue functioning after domain changes. This prevents authentication disruptions for applications using Logto's protected app features.
SAML Application Integration
For enterprise SAML SSO scenarios, the custom domain integration is handled in packages/core/src/libraries/saml-application/saml-applications.ts. This file injects the active custom domain into the SAML entityId and redirectUri values, ensuring identity providers redirect users back to the correct branded endpoint after authentication.
Step-by-Step Guide to Configure Custom Domains
-
Reserve a DNS hostname – Choose a subdomain such as
auth.example.comorlogin.yourcompany.com. -
Create the custom domain entry – Navigate to Tenant Settings → Domain in the Admin Console, click Add custom domain, and enter your hostname. Alternatively, use the API endpoint
POST /api/v2/tenants/{tenantId}/domainsdefined inpackages/core/src/routes/domain.openapi.json. -
Publish the verification TXT record – Logto returns a
verificationRecordvalue. Create a DNS TXT record with this value at your DNS provider. Propagation typically takes a few minutes. -
Verify ownership – Logto automatically detects the TXT record via Cloudflare validation. Once verified, the domain status changes to "Verified" in the console.
-
Activate as primary endpoint – The first verified domain automatically becomes the primary domain. All OIDC URLs (
issuer,authorization_endpoint,token_endpoint) now usehttps://your-domain.com. -
Update application Redirect URIs – Replace any instances of
*.logto.appin your application configurations, social connector callbacks, and SDK endpoints with your custom domain. The Admin Console displays notices reminding you to complete this step.
Programmatic Domain Management
Adding a Domain via the Management API
You can automate domain creation using the REST API. The endpoint expects your tenant ID and domain name:
curl -X POST https://<your-tenant>.logto.io/api/v2/tenants/<tenant-id>/domains \
-H "Authorization: Bearer <admin-access-token>" \
-H "Content-Type: application/json" \
-d '{
"domain": "auth.example.com"
}'
The response includes the verificationRecord you must publish as a DNS TXT record.
Verifying Domain Ownership via API
Trigger verification manually or poll for status using the verify endpoint:
curl -X POST https://<your-tenant>.logto.io/api/v2/tenants/<tenant-id>/domains/<domain-id>/verify \
-H "Authorization: Bearer <admin-access-token>"
A successful verification returns "verified": true, allowing the domain to serve traffic.
Configuring the Node.js SDK
Update your Logto client configuration to use the custom domain endpoint:
import { LogtoClient } from '@logto/node';
const logto = new LogtoClient({
endpoint: 'https://auth.example.com', // ← custom domain
appId: '<your-app-id>',
appSecret: '<your-app-secret>',
});
await logto.fetchUserInfo(); // OIDC flows now use your branded domain
Ensure the endpoint matches your verified custom domain exactly, including the protocol.
Deploying Protected Apps with the CLI
When using the Logto CLI for protected app deployments, specify the custom domain using the --resource flag handled in packages/tunnel/src/commands/deploy/index.ts:
logto tunnel deploy --resource https://auth.example.com
This command synchronizes the protected-app remote configuration to point SDK endpoints to your custom domain rather than the default Logto host.
Summary
- Maximum 10 domains: Tenants can store up to 10 custom domains by default in the array managed in
packages/core/src/utils/tenant.ts. - Primary domain selection: The first verified domain automatically becomes the primary OIDC issuer endpoint.
- DNS TXT verification: Ownership proof requires publishing a TXT record validated via Cloudflare through the API defined in
packages/core/src/routes/domain.openapi.json. - Automatic propagation: URL generators in
packages/core/src/app/init.tsand SDK endpoints automatically use the active custom domain without code changes. - Protected app updates: The library at
packages/core/src/libraries/protected-app.tssynchronizes SDK endpoints when domains change. - SAML compatibility: Enterprise SAML configurations automatically update their entity IDs and redirect URIs through
packages/core/src/libraries/saml-application/saml-applications.ts.
Frequently Asked Questions
How many custom domains can I add to a Logto tenant?
By default, you can add up to 10 custom domains per tenant. The first verified domain in the array automatically becomes the primary endpoint used for OIDC issuer URLs and SDK endpoints. If you require additional domains, you must adjust the tenant configuration limits in the source code at packages/core/src/utils/tenant.ts.
Why do I need to verify my domain with a DNS TXT record?
Logto requires domain verification to prove ownership before activation. When you create a domain entry via the API at POST /domains, Logto returns a unique verification string that you must publish as a DNS TXT record. The system validates this record via Cloudflare to prevent unauthorized use of domains you do not control, ensuring security across the multi-tenant platform.
Will custom domains affect my existing SAML or protected applications?
Yes, but Logto automatically handles the updates. When a custom domain becomes active, the protected-app library in packages/core/src/libraries/protected-app.ts synchronizes the SDK endpoint, and the SAML application logic in packages/core/src/libraries/saml-application/saml-applications.ts updates the entityId and redirectUri to use the custom domain. However, you must manually update the Redirect URIs in your OIDC client configurations to match the new domain.
How do I use a custom domain with the Logto CLI for protected apps?
When deploying protected apps via the CLI, use the --resource flag to specify your custom domain endpoint. For example: logto tunnel deploy --resource https://auth.example.com. This ensures the tunnel command in packages/tunnel/src/commands/deploy/index.ts synchronizes the correct endpoint configuration and validates SSL certificates against your custom domain rather than the default Logto host.
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 →