v26.3.1
v26.3.1
Address picker on the code refresh login screen
Refresh (privileged re-authentication) logins that use the code method can now show a "Send code to
" button for each available address instead of asking for the identifier again. Because the active session already fixes the identity, re-entering the identifier is unnecessary and makes a privileged login look like a fresh login.The behavior is controlled by a new feature flag, feature_flags.refresh_login_choose_address, which defaults to off. On Ory
Network, set it through the project configuration field kratos_feature_flags_refresh_login_choose_address. New projects enable
it by default; existing projects keep the previous identifier-input behavior until you turn it on. The flag is safe to toggle back
and forth.
Device key IDs are now a deterministic fingerprint of the device key
The client_key_id of a device authentication key is now derived by the server as the lowercase-hex SHA-256 of the enrolled
device's public key. The enrollment request no longer accepts a client_key_id field; the id is always the fingerprint of the
attested key.
- The
client_key_idfield has been removed from the enrollment (add) request. Clients that still send it are not rejected: the field is ignored. - The id is bound to the key material that the platform attestation vouches for. At login, the server looks the key up by its stored fingerprint and verifies the assertion against the public key stored at enrollment time, so a login-provided id can no longer point the server at a different key.
- The device recomputes the identical id locally from its own public key, so it is never returned by the server and can be used directly for login.
- Because the id is a fingerprint of the key, the same physical device key can no longer be enrolled twice.
Existing keys keep their stored id and continue to work unchanged; the new derivation applies to keys enrolled from now on.
Fix device key enrollment on iOS
Enrolling a device key from an iOS app now succeeds. Apple App Attest sends only the leaf certificate and the App Attest sub-CA in the attestation; the root is pinned on the server and never transmitted. The chain verifier previously treated the last certificate as the root and dropped the sub-CA, so a genuine two-certificate chain failed with "certificate signed by unknown authority". The verifier now treats every certificate except the leaf as an intermediate and anchors on the pinned root.
Pin device authentication keys to your own mobile apps
Device authentication now supports optional App ID pinning, so a device key can only be enrolled from, and used to sign in from, an app you control.
Configure the allow-lists under the deviceauthn method:
selfservice:
methods:
deviceauthn:
config:
# Apple App IDs ("<TeamID>.<BundleID>").
ios_app_ids:
- ABCDE12345.com.example.app
# Android app signing-certificate digests (lowercase-hex SHA-256).
android_app_ids:
- 5f2e...c1a9
On iOS the App Attest rpIdHash (the SHA-256 of the App ID) is checked against ios_app_ids. On Android the attested
AttestationApplicationId signing-certificate digest is checked against android_app_ids; the signing certificate is pinned
rather than the package name, which an app cannot forge.
iOS pinning is enforced at both enrollment and login. Android pinning is enforced at enrollment only, because Android login is a bare signature that carries no attestation.
Pinning is opt-in: when a list is empty (the default), any Apple- or Google-attested app is accepted, so existing deployments are unchanged.
Reduce registration latency
An improvement has been made to reduce latency of the Ory Kratos self-service registration API.