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 Errorinstead of409 Conflict. A409tells an identity provider to stop retrying, so pushes that would have succeeded on a retry were abandoned. Only a genuine unique-attribute collision still answers409withscimType: uniqueness. - A push that would change more than 12,000 members is rejected up front with
400 Bad RequestandscimType: 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 RequestwithscimType: invalidValueand names the identities, instead of a generic500. Provision those identities through/Usersfirst.
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.