Releases: logto-io/logto
v1.27.0
Security center in Logto Console
We have introduced a new"Security" page in the Logto console, which includes the following features:
- Password policy: This feature has been migrated from the "Sign-in Experience" page to the new "Security" page.
- CAPTCHA: Enable CAPTCHA for sign-up, sign-in, and password recovery to mitigate automated threats.
- Identifier lockout: Temporarily lock an identifier after multiple failed authentication attempts (e.g., consecutive incorrect passwords or verification codes) to prevent brute force access.
Refer to documentation for more details.
Captcha bot protection
As mentioned in the above "Security" update, you can now enable CAPTCHA bot protection for your sign-in experience with providers such as Google reCAPTCHA enterprise and Cloudflare Turnstile.
To enable CAPTCHA bot protection, you need to:
- Go to Console > Security > CAPTCHA > Bot protection.
- Select the CAPTCHA provider you want to use.
- Configure the CAPTCHA provider by following our step-by-step guide.
- Save the settings.
- Enable CAPTCHA in the Security page.
Then take a preview of your sign-in experience to see the CAPTCHA in action.
Refer to documentation for more details.
Identifier lockout (sentinel)
The identifier lockout has always been there protecting your Logto instance. However, previously it is hard-coded and not configurable. Now you can fully customize and override the default rules in the Security center.
This update includes the follow 3 parts:
- Maximum failed attempts:
- This limits the number of consecutive failed authentication attempts per identifier within an hour. If the limit is exceeded, the identifier will be temporarily locked out.
- Default value: 100
- Lockout duration (minutes):
- This specifies the period during which all authentication attempts for the given identifier are blocked after exceeding the maximum failed attempts.
- Default value: 60 minutes
- Manual unblock:
A new API endpoint has been introduced to manually unblock a specified list of identifiers. This feature is useful for administrators to unlock users who have been temporarily locked out due to exceeding the maximum failed attempts.
Endpoint: POST /api/sentinel-activities/delete
This endpoint allows for the bulk deletion of all sentinel activities within an hour in the database based on the provided identifiers, effectively unblocking them.
Refer to documentation for details.
Magic link (one-time token) support
You can now use the "one-time token" to compose magic links, and send them to the end user's email.
With a magic link, one can register a new account or sign in directly to the application, without the need to enter a password, or input verification codes.
You can also use magic link to invite users to your organizations.
Example API request to create a one-time token
POST /api/one-time-tokens
Request payload:
Compose your magic link
After you get the one-time token, you can compose a magic link and send it to the end user's email address. The magic link should at least contain the token and the user email as parameters, and should navigate to a landing page in your own application. E.g. https://yourapp.com/landing-page
.
Here's a simple example of what the magic link may look like:
https://yourapp.com/landing-page?token=YHwbXSXxQfL02IoxFqr1hGvkB13uTqcd&email=user@example.com
Refer to documentation for more details.
Bump node to v22
We've updated Node.js to v22 for better performance and security.
Improvements
- f419382: respond 404 for non-existing paths in
/assets
- 7dbceda: move password encyption to separate worker thread
- cfedfb3: clean up legacy Experience package
- 752d406: support string-typed boolean claims in OIDC connector
- 59c3984: add Ukrainian translation to Experience (credit @HighError)
- ba76210: convert Windows absolute paths to file URLs for dynamic imports (credit @jtmaveryk)
Security updates and vulnerability fixes
New Contributors
- @HighError made their first contribution in #7205
- @jtmaveryk made their first contribution in #7126
Full Changelog: v1.26.0...v1.27
v1.26.0
Support multiple sign-up identifiers
Logto now supports configuring multiple required identifiers for user registration. This enhancement extends the previous single-identifier limitation, enabling a more comprehensive sign-up process.
Sign-in experience schema
Introduces a new optional field, secondaryIdentifiers
, to the sign-in experience sign-up settings. This enhancement allows developers to specify multiple required user identifiers during the user sign-up process. Available options include email
, phone
, username
and emailOrPhone
.
The difference between signUp.identifiers
and new signUp.secondaryIdentifiers
:
Primary identifiers (signUp.identifiers
):
- Maintains backward compatibility with existing sign-in experience settings
- Represents the initial registration form
- Uses OR logic: Only one type of identifier will be collected
- Special case:
[email, phone]
allows either email OR phone registration, treated as a single requirement.
Secondary identifiers (signUp.secondaryIdentifiers
):
- Optional
- New field introduced for multi-identifier support
- Collects additional required identifiers after primary registration
- Uses AND logic: all configured identifiers are mandatory
- Supports
emailOrPhone
type: requires either email OR phone, treated as a single requirement
Examples:
Example 1: Username with Required Email and Phone
Primary: username
Secondary: 'emailand
phone`
{
"identifiers": ["username"],
"secondaryIdentifiers": [
{
"type": "email",
"verify": true
},
{
"type": "phone",
"verify": true
}
],
"verify": true,
"password": true
}
Example 2: Username with Either Email or Phone
Primary: username
Secondary: emailOrPhone
{
"identifiers": ["username"],
"secondaryIdentifiers": [
{
"type": "emailOrPhone",
"verify": true
}
],
"verify": true,
"password": true
}
Example 3: Email/Phone with Required Username
Primary: email
OR phone
Secondary: username
{
"identifiers": ["email", "phone"],
"secondaryIdentifiers": [
{
"type": "username",
"verify": true
}
],
"verify": true,
"password": false
}
Console updates
Enhanced Sign-up Configuration UI:
- Introduced a multi-selector interface replacing the previous single-identifier selector
- Added drag-and-drop functionality for prioritizing identifiers
- The first identifier in the list serves as the primary identifier (
signUp.identifiers
) - Subsequent identifiers are stored as secondary identifiers (
signUp.secondaryIdentifiers
)

Enhanced sign-in experience configuration
We've relaxed several configuration constraints to give you more flexibility in customizing your authentication flows.
-
The password requirement is now optional when using
username
as a sign-up identifier. Please note, when configuringusername
as the sole sign-up identifier with password disabled, users will be unable to authenticate after registration. Ensure at least one of the following:- Enable password requirement at sign-up
- Configure additional sign-up identifiers
-
Removed the constraint requiring sign-up identifiers to be enabled as sign-in methods. We have fully decoupled the sign-up identifier settings from the sign-in methods. Developers can now require as many user identifiers as needed during the sign-up process without impacting the sign-in process.
-
Removed the requirement for password verification across all sign-in methods when password is enabled for sign-up.
Experience package migration
In this release, we have transitioned the user sign-in experience from the legacy @logto/experience-legacy
package to the latest @logto/experience package
. This change fully adopts our new Experience API, enhancing the underlying architecture while maintaining the same user experience.
- The sign-in experience front-end now uses the
@logto/experience
package by default. - Fully adopts our new Experience API for improved performance and maintainability
- Maintains complete feature parity with no visible changes to end-users
- Legacy Interaction API and
@logto/experience-legacy
will be deprecated in future releases.
CLI updates
@logto/translate
-
Improve the OpenAI prompt to better support i18n plural form suffixes
-
make method
isLanguageTag
case-insensitiveLanguage tag case inconsistency was causing translation mismatches across packages:
@logto/phrases
and@logto/phrases-experience
: using lowercase tags (e.g.,pt-br
,zh-cn
)@logto/language-kit
: using mixed-case tags (e.g.,pt-BR
,zh-CN
)
Updated
isLanguageTag
function in language kit to be case-insensitive, ensuring:- Consistent language tag matching regardless of case
- Proper detection of all language tags by translate CLI tool
- Fixed missing translations due to case mismatches
Logto integrations updates
- WordPress integration guide: Added out-of-box WordPress plugin integration documentation to Logto console
- Azure AD social connector enhancement: Added OAuth
scopes
field to@logto/connector-azuread
- Enables customization of requested user permissions
- Provides greater flexibility in access control
- OIDC SSO connector authentication bug fixes: Removed
client_id
from token request body
- Resolves compatibility issues with OIDC providers like Okta
- Eliminates redundant client authentication method
- Before:
client_id
included in both request body and authentication header - After: Uses authentication header only
- Before:
- This OIDC SSO connector update improves compatibility with providers that enforce strict client authentication methods. By removing the redundant
client_id
from the request body while maintaining the authentication header, we ensure consistent behavior across different OIDC providers.
v1.25.0
Support custom email templates in multiple languages via Management API
Introduce localized email template customization capabilities. This update allows administrators to create and manage multiple email templates for different languages and template types (e.g., SignIn, ForgotPassword) via the management API.
Email connectors now support automatic template selection based on the user's preferred language. If a template is not available in the user's preferred language, the default template will be used.
- For client-side API requests, like experience API and user account API, the user's preferred language is determined by the
Accept-Language
header. - For server-side API requests, like organization invitation API, email language preference can be set by passing extra
locale
parameter in themessagePayload
. - The email template selection logic is based on the following priority order:
- Find the template that matches the user's preferred language detected from the request.
- Find the template that matches the default language set in the sign-in experience settings.
- Use the default template set in the email connector settings.
Management API
PUT /email-templates
: Bulk create or update email templates.GET /email-templates
: List all email templates with filter by language and type support.DELETE /email-templates
: Bulk delete email templates by language and type.GET /email-templates/{id}
: Get a specific email template by ID.DELETE /email-templates/{id}
: Delete a specific email template by ID.PATCH /email-templates/{id}/details
: Update email template details by ID.
Supported email connectors
@logto/connector-aliyun-dm
@logto/connector-aws-ses
@logto/connector-mailgun
@logto/connector-sendgrid-email
@logto/connector-smtp
Unsupported email connectors
The following email connectors have their templates managed at the provider side and do not support reading templates from Logto.
The user's preferred language will be passed to the provider as the locale
parameter in the email sending request payload. For i18n support, administrators must manage the template selection logic at the provider side.
@logto/connector-postmark
@logto/connector-http-email
Pass additional context variables to email templates
Enhanced email template customization by introducing additional context variables that developers can utilize in message templates. These new variables provide deeper contextual information about the authentication workflow, enabling more personalized and scenario-specific email content.
user
:UserInfo
- Contains basic user profile data (name, primaryEmail, etc.) for personalizationapplication
:ApplicationInfo
- Contains basic application-specific data (name, logo, etc.) for personalizationorganization
:OrganizationInfo
- Contains basic organization-specific data (name, logo, etc.) for personalizationinviter
:UserInfo
- Contains basic inviter profile data (name, primaryEmail, etc.) for personalization
usageType | Scenario | Variables |
---|---|---|
SignIn | Users sign in using their email and verify by entering verification code instead of entering a password. | code: string application: ApplicationInfo organization?: OrganizationInfo |
Register | Users create an account using their email and verify it by entering a verification code sent by Logto to their email. | code: string application: ApplicationInfo organization?: OrganizationInfo |
ForgotPassword | If users forget their password during login, they can choose to verify their identity using the email they've already verified with Logto. | code: string application: ApplicationInfo organization?: OrganizationInfo |
Generic | This template can be used as a general backup option for various scenarios, including testing connector configurations and so on. | code: string |
OrganizationInvitation | Use this template to send users an invitation link to join the organization. | link: string organization: OrganizationInfo inviter?: UserInfo |
UserPermissionValidation | During app usage, there may be some high-risk operations or operations with a relatively high risk level that require additional user verification, such as bank transfers, deleting resources in use, and canceling memberships. The UserPermissionValidation template can be used to define the content of the email verification code users receive in these situations. |
code: string user: UserInfo application?: ApplicationInfo |
BindNewIdentifier | When a user modifies their profile, they may bind an email address to their current account. In this case, the BindNewIdentifier template can be used to customize the content of the verification email. |
code: string user: UserInfo application?: ApplicationInfo |
Check Email templates for more information on how to use these new context variables in your email templates.
Improvements
-
1c7bdf9ba: add legacy password type supporting custom hasing function, credits @fre2d0m
You can now set the type of
password_encryption_method
tolegacy
, and store info with a JSON string format (containing a hash algorithm, arguments, and an encrypted password) in thepassword_encrypted
field. By doing this, you can use any hash algorithm supported by Node.js, this is useful when migrating from other password hash algorithms, especially for the ones that include salt.The format of the JSON string is as follows:
["hash_algorithm", ["argument1", "argument2", ...], "expected_hashed_value"]
And you can use
@
as the input password in the arguments.For example, if you are using SHA256 with a salt, you can store the password in the following format:
[ "sha256", ["salt123", "@"], "c465f66c6ac481a7a17e9ed5b4e2e7e7288d892f12bf1c95c140901e9a70436e" ]
Then when the user uses the password (
password123
), thelegacyVerify
function will use thesha256
algorithm with thesalt123
and the input password to verify the password.In this case,
salt123
is the first argument,@
is the input password, then the following code will be executed:const hash = crypto.createHash("sha256"); hash.update("salt123" + "password123"); const expectedHashedValue = hash.digest("hex");
-
b0135bcd3: enhanced handlebars template processing in the connector to support nested property access in email template variables
Updates
- Updated
replaceSendMessageHandlebars
logic to handle nested property paths in template variables - Latest template processing logic now supports:
- Direct replacement of primitive values (string/number/null/undefined)
- Deep property access using dot-notation (e.g.,
organization.branding.logoUrl
) - Graceful handling of missing properties (replaces with empty string)
- Preservation of original handlebars when va...
- Updated
v1.24.1
New connectors:
- X (Twitter) social connector
- Slack social connector
- LinkedIn social connector
- Line social connector
- Amazon social connector
Bug fixes
-
cb26102: fix cli add offical connectors command missing connectors bug
Fix the bug when running the cli commend logto connectors add --official, only 8 connectors are fetched from npm registry.
This fix update logic to query additional pages of results when fetching connectors from the npm registry. -
0b785ee: display JWKS URI on application details page
-
e7accfd: prevent i18n context contamination by using request-scoped instances
This bug fix resolves a concurrency issue in i18n handling by moving from a global i18next instance to request-scoped instances.Problem
When handling concurrent requests:
- The shared global
i18next
instance's language was being modified viachangeLanguage()
calls. - This could lead to race conditions where requests might receive translations in unexpected languages.
- Particularly problematic in multi-tenant environments with different language requirements.
Solution
- Updated
koaI18next
middleware to create a cloned i18next instance for each request. - Attach the request-scoped instance to Koa context (
ctx.i18n
) All subsequent middleware and handlers should now usectx.i18n
instead of the globali18next
instance. - Maintains the global instance for initialization while preventing cross-request contamination
- The shared global
-
a5990ec: fixes an incorrect condition check in the verification code flow where
isNewIdentifier
was using inverted logic for email and phone comparisons.Changes
- Corrected
isNewIdentifier
boolean logic to useidentifier.value !== user.primaryEmail
for email checks - Fixed phone number comparison to properly use
identifier.value !== user.primaryPhone
Impact
This fixes a regression where:
- Verification codes for existing emails/phones were incorrectly using the
BindNewIdentifier
template - New identifiers were mistakenly getting the
UserPermissionValidation
template - Affected both email and phone verification flows
- Corrected
-
28643c1: fix the email/phone identifier conflict handling logic during user registration.
When a user attempts to register with an email/phone that already exists:
Previous Behavior
"Sign in instead" modal will be shown when:
- The email/phone identifier has been verified through a verification code validation
- Identifier type (email/phone) was enabled in sign-in methods
This caused an issue when:
- Only password authentication method was enabled in the sign-in method settings.
- When users clicked "Sign in instead" action button, the API call will throw an sign-in method not enabled error. Which is confusing for the user.
Expected behavior: Show the "Email/phone already exists" error modal directly. If only password authentication is enabled. User should not be able to sign in with email/phone directly.
Fixed Behavior
Shows the "Sign in instead" modal if:
- The email/phone identifier type is enabled in the sign-in method settings and the verification code is enabled for the identifier.
Otherwise, shows the "Email/phone already exists" error modal directly.
-
bd18da4: properly filter WeChat connectors by platform (Web | Native) in SSR sign-in experience settings
Previously, platform-based social connector filtering was applied during the sign-in experience settings fetch process but not in the SSR sign-in experience data. As a result, platform-specific connectors were not correctly filtered when rendering the page using SSR data.
This update ensures that the same filtering logic is applied to SSR sign-in experience data, resolving the issue.
Affected connectors: WeChat Web and WeChat Native.
v1.24.0
Support SAML applications
Logto now supports acting as a SAML identity provider (IdP), enabling enterprise users to achieve secure Single Sign-On (SSO) through the standardized SAML protocol. Key features include:
- Full support for SAML 2.0 protocol
- Flexible attribute mapping configuration
- Metadata auto-configuration support
- Enterprise-grade encryption and signing
View full documentation for more details.
Add HTTP email connector
Users can now use HTTP email connector for sending emails.
The HTTP email connector allows you to send emails via HTTP call. To use the HTTP email connector, you'll need to have your own email service that expose an HTTP API for sending emails. Logto will call this API when it needs to send an email. For example, when a user registers, Logto will call the HTTP API to send a verification email.
Bug fixes
v1.23.1
Support custom endpoint and addressing style for S3
Add support for configurable S3 endpoint and addressing style (path-style/virtual-hosted)
to improve compatibility with S3-compatible storage services.
- Add forcePathStyle option to control URL addressing style
- Fix custom endpoint support implementation
- Improve URL generation logic for different configurations
Bug fixes
Fix the broken image on Logto console sign-in page
Remove the image element's cross-origin="anonymous"
attribute.
Some public image resources may not have the proper cross-origin headers configured, those images may fail to load when the cross-origin="anonymous" attribute is present.
Since sign-in page image elements are only used for display purposes, Logto does not need to access the image data, so the cross-origin="anonymous"
attribute is not necessary.To make the image elements more compatible with public image resources, remove the attribute from the image elements.
v1.23.0
Customizable MFA prompt policy
You can now customize the MFA prompt policy in the Console.
First, choose if you want to enable Require MFA:
- Enable: Users will be prompted to set up MFA during the sign-in process, which cannot be skipped. If the user fails to set up MFA or deletes their MFA settings, they will be locked out of their account until they set up MFA again.
- Disable: Users can skip the MFA setup process during the sign-up or sign-in flow.
If you choose to Disable, you can continue to choose the MFA setup prompt:
- Do not ask users to set up MFA.
- Ask users to set up MFA during registration (skippable, one-time prompt). The same prompt as the previous policy (UserControlled)
- Ask users to set up MFA on their next sign-in attempt after registration (skippable, one-time prompt).
Relaxed redirect URI restrictions
We have been following the industry best practices for OAuth2.0 and OIDC from the start. However, in the real world, there are things we cannot control, like third-party services or operation systems like Windows.
This update relaxes restrictions on redirect URIs to allow the following:
- A mix of native and HTTP(S) redirect URIs. For example, a native app can now use a redirect URI like
https://example.com/
. - Native schemes without a period (
.
). For example,myapp://callback
is now allowed.
When such URIs are configured, Logto Console will display a prominent warning. This change is backward-compatible and will not affect existing applications.
We hope this change will make it easier for you to integrate Logto with your applications.
New connectors
- 3fa2b79 Added Xiaomi social connector (credit @u0x01 ).
- 3004ae9 Added YunPian SMS connector (credit @u0x01 ).
Bug fixes
- 2178589 Fixed the CLI command for fetching official connectors by updating the npm registry API integration.
v1.22.0
Account API
The new Account API is now available, giving end users direct API access without needing to go through the Management API. With this new API:
- Users can directly manage their profiles, including basic information, password, email, and phone
- Admins have full control over access settings for each field
- Integration is simple with
client.getAccessToken()
for authorization - Social identities management is supported out of the box
Check out the Interact with Account API for more details.
Microsoft EntraID SSO connector enhancement
Added trustUnverifiedEmail
setting for Microsoft EntraID OIDC SSO connector.
This addresses a common issue where email addresses from EntraID weren't being synced to Logto because they lacked explicit verification.
Organizations can now choose to trust these email addresses, enabling smoother user onboarding through EntraID SSO.
You can configure this setting in the EntraID OIDC SSO connector settings page in the Logto console or through the management API.
Sign-in experience improvements
Support contact information
Added support email and website information display on error pages.
When users encounter issues (like 404 errors or social callback failures), they can now easily find ways to contact support for assistance.
You may configure the support email and website info in the Sign-in experience > Content > Support settings in the Logto Console or through the management API.
Unknown session handling
Introduced unknown session redirect URL configuration.
This helps users who land on sign-in pages with expired sessions or through bookmarked URLs - instead of seeing a 404 error, they can be automatically redirected to a specified URL to restart their authentication process.
You may configure the unknown session redirect URL in the Sign-in experience > Sign-up and sign-in > Advanced options settings in the Logto Console or through the management API.
v1.21.0
GatewayAPI SMS connector
You can now send SMS messages via GatewayAPI.
Australia region
The Australia region is now available in Logto Cloud.
Improvements and fixes
- #6734 update Google Connector default
prompts
to beselect_account
- #6630 fix an issue that prevent mp4 video from playing in custom sign-in pages on Safari browser
- #6674 add environment variable to override default database connection timeout
New Contributors
- @michaelgiraldo made their first contribution in #6615
- @bpow made their first contribution in #6328
- @GeisonPiegas made their first contribution in #6642
- @buchen made their first contribution in #6655
- @luis815 made their first contribution in #6674
Coming Soon: Account API
The new Account API is on its way, designed to give end users direct API access without needing to go through the Management API. Here’s a sneak peek of what you can expect:
- Direct access: The Account API empowers end users to directly access and manage their own account profile without requiring the relay of Management API.
- User profile and identities management: Users can fully manage their profiles and security settings, including the ability to update identity information like email, phone, and password, as well as manage social link connections. May also support MFA and SSO in the future.
- Global access control: Admin will have full, global control over access settings, can customize each fields.
- Seamless authorization: Authorizing is easier than ever! Simply use
client.getAccessToken()
to obtain an access token and attach it to the Authorization header.
v1.20.0
Arabic translation and RTL support
- #6422 Added new Arabic language translation to both Console and Experience UI (credit @zaaakher).
- Improved UI layout and details to better support RTL languages.


Personal access token (PAT)
Personal access tokens (PATs) provide a secure way for users to grant access tokens without using their credentials and interactive sign-in.
You can create a PAT by going to the user's detail page in Console or using the Management API POST /users/:userId/personal-access-tokens
.
Refer to documentation for more details.
Support additional first-screen options
In addition to sign-in
and register
, we now enabled more options that allowing developers to customize the initial screen presented to users. These new first-screen options are:
identifier:sign_in
: Only display specific identifier-based sign-in methods to users.identifier:register
: Only display specific identifier-based registration methods to users.reset_password
: Allow users to directly access the password reset page.single_sign_on
: Allow users to directly access the single sign-on (SSO) page.
Refer to documentation for more details.
New connectors
- #6227 Added Kook connector (credit @Misaka-L).
- #6514 Added Patreon connector (credit @devtekve).
- #6529 Added GitLab connector (credit @devtekve).
Improvements
- #6400 Supported
login_hint
as additional sign-in parameter. - #6445 Implemented well-known swagger endpoints.
- #6451 Split
translate
command from@logto/cli
to make the CLI small and simple. - #6451 Added a dedicated
@logto/translate
package to translate i18n phrases in Console and Experience. - #6523 Supported entering name while creating a user in Console.
- #6525 Added new query parameter
parse_error
and explicitly set it tofalse
to return raw OIDC error message only. - #6532 Added
denyAccess()
api to custom JWT context in order to conditionally block user token request. - #6534 Supported nested attribute profile mapping in OAuth connector (credit @devtekve).
- #6543 Added
hasPassword
property to/users
Management API response. - #6544 Added user password information in user details. Admin can easily check if a user has set password or not, and can then perform set/reset action accordingly.
- #6567 Added new management API to check password against current password policy settings.
Fixes
- #6425 Prevented potential error caused by cached identifiers across Experience pages.
- #6441 Fixed the issue that blocked users from creating Custom JWT.
- #6481 Fixed wecom connector platform. Use
Universal
instead ofnull
. - #6536 Set
lang
attribute correctly to<html>
in Console, preventing unexpected browser translator prompt. - #6560 Allowed linking new social identity to an existing user account when registration is disabled.
- #6576 Prevented user registration and profile fulfillment with SSO-only email domains.