v26.2.19
v26.2.19
Stop forwarding the OIDC login_hint upstream parameter
Kratos no longer forwards the login_hint upstream parameter to OIDC providers. A caller-supplied login_hint cannot be trusted,
and on providers that act on it (such as Google, Microsoft, and Auth0) it can steer account, tenant, or OAuth client selection at
the identity provider and enable a phishing client swap.
The hd, prompt, auth_type, and acr_values upstream parameters are unchanged and still forwarded.
Breaking changes
login_hint is removed from the upstream_parameters of the login, registration, and settings OIDC methods. If you previously
sent upstream_parameters.login_hint when submitting one of these flows, the value is now ignored and no longer reaches the
upstream provider. The account chooser or sign-in form on the provider is no longer pre-filled from this value. No action is
required; remove the parameter from your integration to avoid confusion.
Bind an identity to an organization through the settings flow
The self-service settings flow now accepts an optional organization query parameter. Calling createBrowserSettingsFlow or
createNativeSettingsFlow with an organization ID scopes the flow to that organization's SSO providers. The organization query
parameter is only honored when one of the identity's email addresses is under the organization's configured domains; otherwise the
flow falls back to a regular (unscoped) settings flow. The flow's UI returns only link nodes for the matching OIDC and SAML
providers, with already-linked providers shown as disabled. Submitting a link runs the upstream IDP authentication and, on the
callback, links the credential and sets identity.organization_id — no logout, no manual account linking.
The email-domain check uses the identity's email verifiable addresses. Identities whose schema has no verification.via: email
annotation have no email verifiable addresses and therefore cannot use the organization query parameter — the flow silently
falls back to an unscoped settings flow.
If the authenticated identity is already bound to an organization, that organization wins over the query parameter. Unlink submissions are rejected for organization-scoped flows. Link submissions are restricted to the flow's organization scope: an organization-scoped flow links only that organization's providers, and an unscoped flow links only providers that belong to no organization.
If the identity's organization_id references an organization that has since been deleted, the settings flow falls back to the
unscoped path — accounts offboarded from a deleted organization keep working with account recovery and self-service settings.
Browser autofill and logout hardening for self-service flows
Several self-service flows now emit the standard hints that browsers and password managers use to autofill credentials and one-time codes:
- One-time code inputs in the login, registration, recovery, and verification code flows carry
autocomplete="one-time-code", which lets browsers offer the code straight from the SMS or email and enables the Web OTP API on supported platforms. - The identifier input in the password login form carries
autocomplete="username", so password managers offer the saved username. The identifier-first and passkey flows keep their existingusername webauthntoken. - SMS one-time code messages for login, registration, and verification now end with an origin-bound last line
(
@<domain> #<code>), matching the recovery code message. This binds the code to the requesting origin for the Web OTP API.
A new public endpoint, GET /.well-known/change-password, implements the W3C change-password URL. It responds with
303 See Other and redirects to the configured settings UI (selfservice.flows.settings.ui_url), so password managers can
deep-link users to where they change their password.
Browser logout can now clear site data. When the new selfservice.flows.logout.clear_browser_data setting is enabled, a
successful browser logout over HTTPS sends the Clear-Site-Data response header, instructing the browser to clear cookies,
storage, and caches for the origin. The setting is off by default to avoid clearing data that other applications on the same
origin may rely on.
Cursor-based pagination for SCIM
The SCIM Users and Groups list endpoints now support cursor-based pagination as described in RFC 9865. Request the first page
by sending an empty cursor query parameter (for example GET /Users?cursor&count=100), then follow the nextCursor value
returned in each response to fetch the next page. Pagination ends when a response no longer includes nextCursor.
Cursor pagination keeps database load bounded no matter how deep you page, so it is the recommended way to read large numbers of
users or groups — it has no equivalent of the startIndex offset limit. The existing count/startIndex offset pagination is
unchanged and remains the default. Cursor responses omit totalResults.
Support for both methods is advertised under pagination in GET /ServiceProviderConfig. Cursors are valid for one hour; an
expired or malformed cursor returns a 400 error with the expiredCursor or invalidCursor SCIM error type.
Filter SCIM users by group membership
The SCIM API now supports filtering users by group membership. GET /Users?filter=groups.value eq "<group-id>" returns the direct
members of the given group. The filter combines with both pagination modes — startIndex / count and cursor pagination — so
members of large groups can be enumerated page by page:
GET /Users?filter=groups.value eq "47ac10b5-58cc-4372-a567-0e02b2c3d479"&cursor=...&count=100
Fix SCIM timeouts and conflicts on large group updates
A membership change now re-evaluates the mapper only for the members that actually changed: the members added or removed, plus all current members when the group's display name changes.
Fix missing schemas and meta in SCIM ServiceProviderConfig
The GET /ServiceProviderConfig response now includes the required schemas and meta attributes, as defined in RFC 7644. They
were previously omitted because the response was serialized in a way that skipped the custom JSON encoder. SCIM clients that
validate the resource against the SCIM schema now receive a compliant response.
Improved SCIM protocol conformance
SCIM list and query responses now follow RFC 7643/7644 more closely:
count=0returns onlytotalResultswithout fetching a page, also when combined with cursor pagination.- Empty result pages always render
Resources: []and includeitemsPerPage. - The
attributesandexcludedAttributesquery parameters support dotted sub-attribute paths such asname.givenNameormembers.value. - Group
externalIdfiltering is now case-exact, matching user filtering. - PATCH operations normalize multi-valued attributes so at most one entry is
primary, and patched resources are re-validated before they are saved. - Update conflicts return
409withscimType: uniquenessonly for genuine unique-attribute collisions; other failures return500so identity providers retry instead of giving up.
Kratos OEL now ships the full enterprise feature set
Kratos OEL release adds enterprise features: organization OIDC sign-in, SCIM provisioning, FedCM, CAPTCHA, and device authentication.
On upgrade, Kratos OEL applies additional enterprise schema migrations. These are additive and run automatically as part of the
standard migrate step.
Require a privileged session to change a recovery address
Changing an identity's recovery address through the settings flow now requires a privileged (recently authenticated) session, matching the protection that already applied to credentials and verifiable addresses.
Previously, an identity using a recovery-only address schema could have its recovery address changed by a stale, non-privileged
session without re-authentication. Such a change is now rejected and prompts the user to re-authenticate
(session_refresh_required).
The default email-as-identifier schema was already protected and is unaffected.
