v26.3.5
v26.3.5
Passkey display names now follow one deterministic precedence rule
When an identity schema flags more than one trait with passkey.display_name: true (for example email and phone), the
settings flow previously picked the display name for a new passkey at random from the populated flagged traits. A user adding a
passkey from account settings would sometimes see it named after their email and sometimes after their phone number.
The display name is now resolved by a single rule in every flow: traits flagged with passkey.display_name take precedence over
traits flagged with webauthn.identifier, and within each group the alphabetically-first trait with a non-empty value wins. With
email and phone flagged, the email address is now always used when it is set.
For schemas that flag both passkey.display_name and webauthn.identifier traits, this also changes the candidate order the
registration flow publishes to the browser: passkey.display_name traits now come first, where previously all flagged traits were
sorted alphabetically in one list. A passkey created during registration may therefore get its name from a passkey.display_name
trait where an alphabetically-earlier webauthn.identifier trait was used before. Existing passkeys keep their names, and schemas
that flag only one kind of trait see no change at registration.
Prometheus metrics for the Jsonnet process pool
The Prometheus endpoint now reports the state of the Jsonnet worker process pool, which evaluates webhook payload templates, OIDC claims mappers, and session token claims. Use these metrics to see whether requests are queueing for a free worker.
The metrics mirror the existing SQL connection pool metrics and carry no labels, because each process holds exactly one pool:
| Metric | Type | Description |
|---|---|---|
ory_jsonnet_pool_max_processes | gauge | Maximum number of worker processes. |
ory_jsonnet_pool_processes | gauge | Started worker processes, in use and idle. |
ory_jsonnet_pool_in_use_processes | gauge | Worker processes currently in use. |
ory_jsonnet_pool_idle_processes | gauge | Idle worker processes. |
ory_jsonnet_pool_constructing_processes | gauge | Worker processes currently starting. |
ory_jsonnet_pool_wait_count_total | counter | Acquires that had to wait for a worker. |
ory_jsonnet_pool_wait_duration_seconds_total | counter | Total time blocked waiting for a worker. |
ory_jsonnet_pool_acquired_processes_total | counter | Worker processes ever acquired. |
ory_jsonnet_pool_acquired_duration_seconds_total | counter | Total duration of all acquires. |
ory_jsonnet_pool_canceled_acquires_total | counter | Acquires canceled before a worker was free. |
The courier now evaluates Jsonnet in an isolated process
The courier renders the request body of an HTTP delivery channel from a Jsonnet template, and SMS delivery always uses an HTTP channel. It was evaluating those templates inside the courier process instead of in a sandboxed worker, so a template that consumed excessive memory or CPU affected message delivery as a whole. The courier now uses the same isolated worker pool as the rest of Kratos, where evaluation runs under a memory limit and a filesystem sandbox.
No configuration changes are needed, and template behavior is unchanged.
Serve the WebAuthn Related Origin Requests document
Ory Kratos now serves the WebAuthn Related Origin Requests document at /.well-known/webauthn. It lists the relying party origins
configured for the enabled WebAuthn and passkey methods.
Browsers that support Related Origin Requests (Chrome 128+, Safari 18+) consult this document when a page requests a WebAuthn relying party ID that does not match the page's own origin. This lets passkeys bound to a relying party ID served by Ory work on additional origins, for example across several custom domains: add the extra origins to the relying party origins of the WebAuthn or passkey configuration and they appear in the document automatically.
See https://www.w3.org/TR/webauthn-3/#sctn-related-origins for details.
Webhooks now receive enrolled credential types and available AAL
Login, registration, settings, recovery, and verification webhooks now receive the identity's enrolled credential types and
available authenticator assurance level. The payload's identity.credentials lists each enrolled credential's type and
identifiers, plus its version and its creation and update timestamps when known — never secrets: credential configuration is
stripped and identity-provider (OIDC and SAML) credentials list no identifiers. identity.available_aal reports whether the
identity has a usable second factor. Use this to build risk-based skip-vs-challenge decisions in your webhook.