- DATE:
- AUTHOR:
- Ory Team
Ory Network, Ory Hydra, Ory Kratos, Ory Polis v26.3.1 released
Ory Network
JWT bearer grant no longer copies the assertion audience by default
The urn:ietf:params:oauth:grant-type:jwt-bearer grant no longer copies the
aud (audience) claim of the assertion JWT into the resulting access token by
default. Per RFC 7523, the assertion's aud identifies the authorization server
as the intended recipient; it is not meant to define the audience of the issued
access token.
A new setting, oauth2.grant.jwt.omit_assertion_audience, controls this
behavior. It defaults to true (omit). Set it to false to restore the
previous behavior of copying the assertion audience into the access token.
Breaking changes
Self-hosted Ory Hydra (OSS) and Ory Enterprise License (OEL): after upgrading, the assertion audience is omitted from access tokens by default. Set
oauth2.grant.jwt.omit_assertion_audience: falseif you rely on the old behavior.New Ory Network projects: created with the assertion audience omitted.
Existing Ory Network projects: unchanged — they keep copying the assertion audience. To adopt the new behavior, set the option explicitly.
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.
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.
Refresh identities from SAML claims on login
SAML connections now support an "Update identity on login" option. When set to
automatic, Ory re-runs the connection's Jsonnet claims mapper on every SAML
login and refreshes the identity's traits and metadata (including the
metadata_public group claims used for just-in-time provisioning) whenever they
change.
You can set the option from the SAML connection dialog in the Ory Console, or
directly in the project configuration under
selfservice.methods.saml.config.providers[].update_identity_on_login.
The default is never, so existing SAML connections keep their current
behavior — their identities are not modified on login until you opt in. This
mirrors the existing OIDC "Update identity on login" option.
This is now available on Ory Network, for the Ory Enterprise License, and will be part of the next Ory Open Source release.
Ory Hydra
JWT bearer grant no longer copies the assertion audience by default
The urn:ietf:params:oauth:grant-type:jwt-bearer grant no longer copies the
aud (audience) claim of the assertion JWT into the resulting access token by
default. Per RFC 7523, the assertion's aud identifies the authorization server
as the intended recipient; it is not meant to define the audience of the issued
access token.
A new setting, oauth2.grant.jwt.omit_assertion_audience, controls this
behavior. It defaults to true (omit). Set it to false to restore the
previous behavior of copying the assertion audience into the access token.
Breaking changes
Self-hosted Ory Hydra (OSS) and Ory Enterprise License (OEL): after upgrading, the assertion audience is omitted from access tokens by default. Set
oauth2.grant.jwt.omit_assertion_audience: falseif you rely on the old behavior.New Ory Network projects: created with the assertion audience omitted.
Existing Ory Network projects: unchanged — they keep copying the assertion audience. To adopt the new behavior, set the option explicitly.
This is now available on Ory Network, for the Ory Enterprise License, and will be part of the next Ory Open Source release.
Ory Kratos
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...c1a9On 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.
Refresh identities from SAML claims on login
SAML connections now support an "Update identity on login" option. When set to
automatic, Ory re-runs the connection's Jsonnet claims mapper on every SAML
login and refreshes the identity's traits and metadata (including the
metadata_public group claims used for just-in-time provisioning) whenever they
change.
You can set the option from the SAML connection dialog in the Ory Console, or
directly in the project configuration under
selfservice.methods.saml.config.providers[].update_identity_on_login.
The default is never, so existing SAML connections keep their current
behavior — their identities are not modified on login until you opt in. This
mirrors the existing OIDC "Update identity on login" option.
This is now available on Ory Network, for the Ory Enterprise License, and will be part of the next Ory Open Source release.
Ory Polis
Serve Polis over HTTPS with a built-in TLS sidecar
The Polis Helm chart can now terminate TLS in front of Polis without an external
ingress. Set tlsSidecar.enabled: true and point tlsSidecar.tls.secretName at
an existing Secret that holds tls.crt and tls.key (managed by you or
cert-manager):
tlsSidecar:
enabled: true
tls:
secretName: polis-tlsThe chart then runs an nginx sidecar that terminates HTTPS and proxies to Polis
in the same pod. The Service keeps the same port and name; when the sidecar is
enabled the Service routes to it (HTTPS) instead of the plain-HTTP Polis
listener, so plain HTTP is no longer served. The sidecar image defaults to
docker.io/nginxinc/nginx-unprivileged:stable and is overridable via
tlsSidecar.image.
The feature is off by default, so existing deployments are unchanged and continue to serve plain HTTP.
For advanced cases, the chart also exposes deployment.extraContainers,
deployment.extraVolumes, deployment.extraVolumeMounts, and
deployment.extraEnvs to add arbitrary sidecars or volumes.
This is now available for the Ory Enterprise License.
Ory Keto, Ory Oathkeeper, Ory Elements, and Ory Terraform
No significant changes in this release.