Skip to main content

v26.3.13

v26.3.13

Creating an identity with an unknown schema ID now fails with 400

Sending a schema_id that your project does not define to POST /admin/identities, PUT /admin/identities/{id}, or PATCH /admin/identities/{id} now returns 400 Bad Request with the reason Unable to find JSON Schema ID: <id>. It previously returned 500 Internal Server Error.

You are affected if your integration treats these endpoints' errors by status class — for example by retrying on 5xx. Requests carrying an unknown schema ID were never going to succeed, and are now reported as the client error they are, so they stop being retried. The response for a schema ID your project does define is unchanged.

Listing identities by ids returns every match in one response

GET /admin/identities?ids=... is a bulk lookup, not a listing. It now returns every identity you asked for in one response and sends no pagination headers.

Self-hosted deployments previously paginated this request at 100 ids by default, so a caller that asked for 300 ids and did not follow the Link header silently received 100 identities. Pass at most 500 ids per request, as before. If you read X-Total-Count or follow Link on this request, drop that handling — the response is complete as it stands.

On the Ory Network, these identities now come back in the same shape as GET /admin/identities/{id}: each carries its schema_url, which this filter previously left empty, and legacy credentials are upgraded to their current representation. Identities are also validated, so a request that matches an identity whose schema_id no longer resolves to a configured schema now fails instead of returning that identity with an empty schema_url.

Raise a login's AAL from the after web_hook response

A login after web_hook with response.parse enabled can now return {"required_aal": "aal2"} to require step-up for that login. One response can both update the identity and raise the AAL. Users who do not yet have a second factor are routed to enrollment rather than let through.

This is off by default. Enable it with the new feature flag feature_flags.webhook_response_directives, or on Ory Network by setting kratos_feature_flags_webhook_response_directives on the project. While the flag is off, a required_aal field in a web_hook response is ignored exactly as it is today, so existing hooks are unchanged. Once it is on, a required_aal value other than "aal2" fails the login rather than being silently dropped; on a web_hook at another position the directive is logged and ignored.

Route generic social sign-in with an organization-claimed email to the organization's SSO

Signing in with a generic social sign-in provider (for example Google) using an email address whose domain is claimed by an organization no longer fails with an error. Kratos now responds with a login flow scoped to the matched organization that contains only the organization's SSO provider buttons and an informational message (ID 1010026), matching the identifier-first behavior. This covers both existing accounts and first-time sign-ins.

SCIM group pushes with large memberships are batched

Pushing a group with a large membership through SCIM no longer times out. A PUT, PATCH, or DELETE on /scim/{client}/v2/Groups/{id} used to process members one at a time, which past a few hundred members exceeded the request budget and rolled the write back, leaving the identity provider with a group that had been emptied. Members are now processed in batches. Very large pushes can still exceed the request budget, especially on multi-region deployments.

Error responses on these endpoints changed:

  • A transient failure while processing a member now answers 500 Internal Server Error instead of 409 Conflict. A 409 tells an identity provider to stop retrying, so pushes that would have succeeded on a retry were abandoned. Only a genuine unique-attribute collision still answers 409 with scimType: uniqueness.
  • A push that would change more than 12,000 members is rejected up front with 400 Bad Request and scimType: tooMany, naming the group and the limit. Split the group into smaller ones to provision it.
  • A push whose membership includes an identity that was not provisioned through SCIM answers 400 Bad Request with scimType: invalidValue and names the identities, instead of a generic 500. Provision those identities through /Users first.

Session-to-JWT key set hardening and load failures returning 400

When Ory converts a session to a JSON Web Token, a key set loaded from the tokenize template's jwks_url at a file:// location is now cached for up to 3 minutes instead of up to one hour, so a rotated key file is picked up faster. If the file becomes unreadable, Ory keeps signing with the previously loaded keys for up to one hour before requests fail, where previously requests failed as soon as the cached keys expired. Key set documents larger than 1 MiB are rejected.

A jwks_url whose key set cannot be loaded now fails the request with 400 Bad Request instead of 500 Internal Server Error, because it is a defect of the selected tokenize template.

TOTP authenticator setup no longer breaks after a rejected settings submission

Enrolling a TOTP (authenticator app) two-factor method could fail permanently when the settings flow used a webhook that can interrupt the request. After the first interrupted submission, every retry on the same flow returned an internal server error, and the user could not finish setup without starting a new flow.

TOTP setup now stays usable after an interrupted submission: the user can submit again on the same flow and is given a fresh secret and QR code to scan when the previous one is no longer available.