Releases: teamhanko/hanko
Hanko 2.3
This release brings several updates to Hanko’s 3rd party (OAuth, OIDC) integration:
- Authenticated users can now connect and manage configured 3rd party identities directly in the profile
- Added support for OIDC ACR request parameter to enable custom communication between the 3rd party and Hanko
- 3rd party identities no longer have to return an email address
What's Changed
- feat: add acr values to custom thridparty provider by @FreddyDevelop in #2305
- Feat oauth connection management by @FreddyDevelop in #2304
Full Changelog: backend/v2.2.1...backend/v2.3.0
Hanko 2.2.1
A smaller release, but with some important fixes and improvements. Most notably:
- Flow locking mechanism to prevent concurrent execution of the same flow, addressing possible race conditions and side effects in actions (setting header tokens, sending emails, ...) in concurrent request scenarios
- Option to configure (or omit) the 3rd-party
promptparameter to fine-tune the social SSO UX - Hanko Elements attributes working again (e.g. prefilled email or the mode attribute)
- Hanko Elements UI fixes
What's Changed
- fix: consistently use persisters with connection by @lfleischmann in #2276
- fix: don't show the divider on login by @FreddyDevelop in #2277
- fix: unwarranted passcode data in webhooks by @lfleischmann in #2279
- feat: add last used badge by @FreddyDevelop in #2283
- fix: ensure WebAuthn session data expires time is in UTC by @FreddyDevelop in #2287
- feat: add flow locking mechanism by @lfleischmann in #2285
- docs: fix redis config password schema by @lfleischmann in #2293
- feat: change default thirdparty prompt parameter behaviour by @lfleischmann in #2292
- fix: elements attribute handling by @lfleischmann in #2295
Full Changelog: backend/v2.2.0...backend/v2.2.1
Hanko 2.2: PKCE
PKCE (Proof Key for Code Exchange)
The main feature of this release is PKCE support for 3rd-party OAuth flows of the Hanko API. When using Hanko with a mobile app, the oauth_state cookie might not be stored, so the thirdparty_oauth action now accepts a code_verifier. When the code_verifier ist set, the state cookie is optional, but the code_verifier is required when exchanging the Hanko token with the exchange_token action.
What's Changed
- fix: user verification on passkey creation by @lfleischmann in #2239
- fix: change module name corresponding to version by @FreddyDevelop in #2257
- fix: export the Claims type by @FreddyDevelop in #2268
- fix: check for SAML before email existence by @FreddyDevelop in #2270
- Feat oauth prompt by @FreddyDevelop in #2260
- PKCE OAuth flow by @FreddyDevelop in #2266
Full Changelog: backend/v2.1.1...backend/v2.2.0
Hanko 2.1.1
This release includes a license change along with several improvements and fixes.
License change
- The proprietary enterprise license in the /ee folder has been removed.
- Hanko Backend is now fully licensed under AGPLv3.
Hanko Elements visual improvements
We’ve refined the look and feel of <hanko-auth>, <hanko-login>, and <hanko-registration>:
- Passcode views: user’s email address is now highlighted.
- Social SSO buttons:
- Logos and text (e.g. “Sign in with Google”) are now centered.
- Order updated: SSO buttons now appear first, with the passkey option listed last.
- Passkey button icon removed for clearer visual separation from SSO options.
- Login/registration switch UI in :
- Now centered at the bottom of the element (previously right-aligned).
- Text and link split for clarity — the prompt (e.g. “Already got an account?”) is separate from the action link (e.g. “Sign in”), making the link more prominent.
Hanko Elements nonce property added
- Added an optional nonce property to Hanko Elements.
- This enables a stricter Content Security Policy (CSP) without requiring
unsafe-inline. - Improves overall security posture by allowing Hanko Element's inline styling in combination with a stricter CSP when a valid nonce is provided.
What's Changed
- Update LICENSE by @FlxMgdnz in #2184
- Delete backend/ee/README.md by @FlxMgdnz in #2183
- Delete backend/ee/LICENSE by @FlxMgdnz in #2182
- fix: add types for react 19 by @FreddyDevelop in #2067
- fix: oauth third party authentication with case insensitive email by @loeffert in #2196
- feat: support nonce for styles by @FreddyDevelop in #2197
- fix: update multiple backend dependencies by @FreddyDevelop in #2209
- Update en.ts by @FlxMgdnz in #2214
- fix user deletion when using mysql as DBMS by @FreddyDevelop in #2202
- fix: catch periodic session check error by @FreddyDevelop in #2204
- fix: take privacy setting into account when adding an email by @FreddyDevelop in #2208
- feat: highlight email address when logging in by @FreddyDevelop in #2216
- feat: change button order & content alignment by @FreddyDevelop in #2217
- feat: change flow switch UI by @FreddyDevelop in #2221
- fix: add all user properties to session by @FreddyDevelop in #2222
Full Changelog: backend/v2.1.0...backend/v2.1.1
Hanko 2.1: User Metadata
We are excited to announce the release of Hanko 2.1!
This release builds on the foundation laid by Hanko 2.0 and introduces new customization capabilities, component enhancements, and bug fixes to improve the overall developer experience.
New: Customizable User Metadata
Hanko now supports user metadata that can be attached to user profiles and managed via the Admin API. Metadata is organized into three categories:
| Metadata type | Public API | Admin API |
|---|---|---|
| Private | No read or write access | Read and write access |
| Public | Read access | Read and write access |
| Unsafe | Read access and write access | Read and write access |
Metadata can be accessed in session JWT templates to map metadata to claims in a session token.
See backend README for full details and examples.
<hanko-auth> Mode Attribute
The <hanko-auth> Web Component now supports a mode attribute, allowing you to explicitly control whether it starts in login or registration mode.
Example:
<hanko-auth mode="registration"></hanko-auth>This makes it easier to integrate the <hanko-auth> Element into a range of different onboarding flows.
Bug Fixes and Improvements
- Cross-tab communication fix: Cross-tab session events are now reliably synchronized. A bug caused by a mismatched broadcast channel name has been resolved.
- User type consistency fix: The
/userREST endpoint now returns the correct structure expected by the frontend SDK. - General improvements: Minor fixes and internal enhancements to improve stability and maintainability.
Full Changelog: backend/v2.0.0...backend/v2.1.0
Hanko 2.0
We are excited to announce the release of Hanko 2.0!
The main highlight of this release is the completely redesigned JavaScript SDK, built to work seamlessly with our Flow API introduced in version 1.0. This new SDK brings major improvements in flexibility, developer experience, and frontend state management when building custom UI using the Hanko API.
New JavaScript SDK
- New State Management: Introduces the
Stateclass for handling flow states, complete with event hooks (onBeforeStateChange,onAfterStateChange), serialization tolocalStorage, and auto-stepping through flows. - Action Execution: Provides a new
Actionclass for type-safe action invocation within authentication flows. - Passkey Autofill Support: Integrates passkey autofill activation handlers for supported states.
- Persistence: Flow state persistence via
localStorage, improving UX across sessions.
Example usage:
const hanko = new Hanko(/* params */);
const state = await hanko.createState("login");
await state.actions.continue_with_login_identifier.run({
username: "user",
});
hanko.onBeforeStateChange(({state}) => {
console.log(`Action invoked: ${state.invokedAction.name}`);
});
hanko.onAfterStateChange(({state}) => {
console.log(`Action finished: ${state.previousAction.name}`);
if (state.name == "login_init") {
state.passkeyAutofillActivation();
}
});Note
The new frontend SDK introduces breaking changes: If you are using a custom frontend based on the previous SDK, please review the SDK docs carefully. We also provide a guide on how to use the SDK to build a custom UI for the Flow API.
Updated Session Management Access
- The session management functions are now directly available on the top-level
Hankoinstance:getUser()validateSession()getSessionToken()logout()
- Previously, these functions were accessed through individual clients, which have now been removed.
- This change simplifies session handling and aligns with the overall SDK cleanup.
- Example code and documentation have been updated accordingly.
SDK Cleanup
- Removed deprecated clients (
EmailClient,ThirdPartyClient,EnterpriseClient,TokenClient) and outdated session handling logic. - Simplified configuration management by unifying internal options.
- Removed obsolete DTOs and related tests.
Backend Compatibility
There are no major changes to the backend compared to version 1.5.2. Updating the backend to use the new JavaScript SDK is not mandatory if you are currently on v1.5.2. However, we recommend upgrading to the latest backend version, as running the new frontend SDK with an older backend version is not officially supported and may lead to unexpected issues.
Custom Session Claims
Custom claims can now be added to the session token. A new configuration option, session.jwt_template, has been added that allows defining session.jwt_template.claims. Values can be arbitrarily nested and can use Go text templates.
The custom claims are also added to sessions/validate endpoint responses.
New Session Token Storage Option
A new option sessionTokenLocation was added to the HankoOptions configuration. You can now choose where the session token is stored on the client:
- cookie (default) — persists across tabs and sessions.
- sessionStorage — session ends automatically when the browser tab is closed.
This allows finer control over session lifetime, improving security for sensitive applications.
Tip
Use sessionStorage if you want user sessions to automatically end when a tab or browser window is closed.
Example configuration:
const hanko = new Hanko("https://your-hanko-instance", {
sessionTokenLocation: "sessionStorage", // ends session on tab close
});Note
This setting only works when session.enable_auth_token_header: true is set.
New Contributors
- @franklinkim made their first contribution in #2110
Full Changelog: backend/v1.5.2...backend/v2.0.0
Thanks to everyone who contributed to this release! 🫶
We are looking forward to your feedback and contributions.
v1.5.1
This release introduces more changes to the way the login flow reacts to the new privacy settings.
If onlyShowActualLoginMethods is enabled:
- Existing passkeys also show up as an option in login method chooser that is displayed after a user enters their email address or username in the login form
- If a passkey is the only available option for a user, the device's passkey UI flow is automatically triggered
- In contrast to the “Sign in with a passkey” button on the main login page, where all passkeys available on the device are displayed, the passkey selection triggered from the login method chooser is limited to the passkeys assigned to the user for whom the email address or user name was entered in the first step
What's Changed
- fix: migration issues by @lfleischmann in #2084
- feat: add passkey option to login method chooser by @FreddyDevelop in #2100
- chore: update versions to 1.5.1 by @FreddyDevelop in #2104
Full Changelog: backend/v1.5.0...backend/v1.5.1
v1.5: Privacy settings, HTML emails, improved sessions
This release contains new features and a handful of important bug fixes.
Privacy settings
Two new settings have been added to control whether the disclosure of information about user accounts should be accepted for the sake of usability:
showAccountExistenceHints: When registering or trying to log in, feedback is displayed indicating whether or not an email address already exists (e.g. “The email is already taken.” or “The email address is unknown.”). When disabled, the system hides this information and behaves identically in both cases to avoid disclosing information about existing email addresses (this has previously been the default behavior).onlyShowActualLoginMethods: Only display the authentication methods that are actually available to a user during the sign-in process (e.g. after the user enters an e-mail address as the identifier in the sign-in form, only prompt the user for a password if they actually have one). If disabled, all theoretically possible authentication options are always displayed to avoid disclosing information about existing email addresses (this has previously been the default behavior).
Please note: Full protection against email enumeration attacks is only provided if both settings, “Show account existence hints” and “Hide unavailable login methods” are disabled. Please note that this may result in a poorer user experience, as users will no longer receive direct feedback if, for example, they have entered an incorrect email address, or if they are suggested the option to enter a password even though they do not have one.
HTML emails
This version adds support for HTML email rendering and delivery alongside plain text emails. The changes ensure that both plain text and HTML versions of passcode and notification emails are generated and sent, improving email formatting and readability across different clients. We will further improve the styling of the HTML emails in a future patch.
Improved session handling in Hanko Elements
- Session management overhaul
- Added periodic session validation with customizable intervals.
- Added inter-tab communication for session events.
- Enhanced tracking of window focus and visibility to ensure session validation occurs only in active tabs, improving performance.
- Session created event updates
- Removed optional
jwtfield and deprecatedexpirationSeconds. - Token claims are now included in "session-created-event" and shared across tabs/windows.
- The JWT remains accessible via the session cookie if
httpOnlyis set tofalse.
- Removed optional
- Deprecation notice
- Deprecated
hanko.session.is_valid()(now blocking, mimicsawait hanko.sessionClient.validate()). - Recommend using non-blocking
hanko.sessionClient.validate()instead.
- Deprecated
- Local storage optimization
- Eliminated the need to store the JWT to the local storage.
Updated Go version
Hanko is now using Go version 1.24. Please note this if you want to compile the Hanko backend code.
What's Changed
- fix: create session in DB for old endpoints by @FreddyDevelop in #2052
- Parse email_verified claim correctly from Apple ID token by @FreddyDevelop in #2054
- feat: introduce html mails by @bjoern-m in #2045
- fix: use TriggerWebhook function instead of NotifyUserChange by @FreddyDevelop in #2058
- Feat periodic session checks by @bjoern-m in #2032
- feat: add privacy settings by @FreddyDevelop in #2072
- fix: third party login search param retention by @lfleischmann in #2075
- docs: add missing webhook events to schema extension by @lfleischmann in #2059
- chore: update go version to 1.24 by @lfleischmann in #2070
Full Changelog: backend/v1.4.0...backend/v1.5.0
v1.4: Login with Facebook, IdP-initiated SSO, Email i18n
This version contains important improvements and bug fixes. Highlights include:
Facebook SSO
Facebook has been added as pre-configured Social SSO provider.
SAML IdP-initiated SSO
Hanko backend is now able to handle Identity provider initiated login requests. This is a key feature for B2B customers that require their own IdP to handle authentication to apps that use Hanko. Now, those B2B users can access apps that use Hanko via their "App directories" (e.g. Entra, Google Workspace, Okta) and initiate the authentication flow right from there. The existing SAML flow (SP-initiated SSO) can continue to be used. More info about the changes here #2046.
Email i18n
Emails sent by Hanko (e.g. passcodes) are now available in all languages supported by Hanko Elements. When sending emails, the email will use the Hanko Elements locale used in the current browser session if possible.
New webhooks
New webhook event types have been added:
user.loginuser.password.changeduser.update.username.createuser.update.username.updateuser.update.username.delete
Additionally, all webhook events now include the IP address and user agent strings.
Housekeeping
A new cleanup command has been added to remove expired database entries (flows, audit logs, webauthn credential session data).
What's Changed
- chore: add same site attribute to the device trust cookie by @bjoern-m in #2006
- feat: always persist sessions server-side, config adjustments by @bjoern-m in #1997
- feat: let quickstart use session validate endpoint by @FreddyDevelop in #2014
- fix: use lowered id to get third party provider by @FreddyDevelop in #2017
- fix: don't use config file when failed to load by @FreddyDevelop in #2022
- feat: email i18n by @lfleischmann in #2023
- feat: add facebook provider by @lfleischmann in #2007
- feat: enhance session response by @bjoern-m in #2003
- fix: error handling when using zombie passkeys by @bjoern-m in #2034
- fix: webhooks missing triggers and events by @lfleischmann in #2026
- feat: add username to session JWT and public session API responses by @lfleischmann in #2036
- fix: SAML issues by @lfleischmann in #2041
- fix: third party loading spinner shown on multiple buttons fixed by @bjoern-m in #2042
- feat: add cleanup command to remove expired db entries by @bjoern-m in #2035
- feat: use exact template names for email.send webhook types by @lfleischmann in #2037
- fix: reintroduce server-side session config by @FreddyDevelop in #2043
- feat: new webhook events & user metadata enhancements by @bjoern-m in #2048
- feat(ee): saml idp initiated sso by @lfleischmann in #2046
Full Changelog: backend/v1.3.0...backend/v1.4.0
v1.3: Custom OAuth, device trust, stay signed in
This update contains a variety of frequently requested features and improvements.
Custom OAuth providers
In addition to the preconfigured providers such as Apple, Google, and GitHub, we have now added the option to configure custom OpenID Connect or OAuth providers so that they appear as “Sign in with...” buttons on the login and registration pages.
Device trust
A new device trust feature offers users the option of not having to perform 2FA again for a certain period of time after successful 2FA. Administrators can specify whether to automatically trust the device, prompt the user to trust the device, or never allow trusted devices and always enforce 2FA.
Stay signed in
This new option can be used to control whether a persistent cookie or a session cookie should be issued when the user is logging in. Persistent cookies (default) remain valid for the set session duration, i.e. the user remains logged in even if the browser is closed. Session cookies are usually deleted when the browser or browser tab is closed, so users have to log in again the next time they visit the app. A third option adds a “Stay signed in” checkbox to the login screen, which allows the user to determine the type of cookie themselves.
Last used indicators
Social SSO buttons (e.g., "Sign in with Google") now display a "Last used" label to help users remember which provider they chose on their last visit and avoid creating redundant accounts. Note that active Account Linking still allows users to change the login method to some extent, but only if the email address matches.
New admin API endpoints
The Admin API has been extended with the following new endpoints:
- password
- get
- create
- update
- delete
- webauthn
- list
- get
- delete
- otp
- get
- delete
- sessions
- list
- create
- delete
User import improvements
User import functionality has been improved. Now, more user data and credentials can be imported, e.g.:
- Usernames
- Passwords (bcrypt hashes)
- WebAuthn credentials
- OTP secrets
What's Changed
- chore: re-generate example css by @bjoern-m in #1970
- feat: add session creation endpoint by @FreddyDevelop in #1969
- fix: add missing third party provider defaults by @lfleischmann in #1976
- feat: trusted devices and 'remember me' by @bjoern-m in #1982
- feat: add last used indicator to the login page by @bjoern-m in #1957
- Admin api changes by @FreddyDevelop in #1974
- chore: autogenerate config JSON schema by @github-actions in #1986
- feat: third party custom providers by @lfleischmann in #1984
- chore: autogenerate config JSON schema by @github-actions in #1989
- fix: check server side session for REST API endpoints by @FreddyDevelop in #1988
- feat: enhance jsonschema for third_party config by @lfleischmann in #1990
- chore: autogenerate config JSON schema by @github-actions in #1991
- Fix cookie name in passcode handler by @loeffert in #1625
- Feat custom user by @FreddyDevelop in #1978
- fix: remove session id from jwt on disabled server side sessions by @lfleischmann in #1993
- chore: add missing tags by @FreddyDevelop in #1994
- Feat extend user import by @FreddyDevelop in #1992
- chore: autogenerate import JSON schema by @github-actions in #1996
- chore: update versions to 1.3.0 by @FreddyDevelop in #1998
- fix: return after suspending delete session action by @lfleischmann in #2000
- chore: add same site attribute to the device trust cookie by @bjoern-m in #2006
New Contributors
Full Changelog: backend/v1.2.1...backend/v1.3.2