Upgrading from 1.1.0-rc.13 to 1.1.0-rc.14¶
This release comes from a self-run of the OpenID Foundation conformance suite against every OpenID Connect OP certification profile (OpenID Connect conformance-suite run). Most of it is new and off until you use it. Two changes reach every installation: tokens now carry the standard profile claims only for the scopes granted, and userinfo no longer returns the access token's own claims. Check your relying parties for those two before you upgrade.
Before you upgrade (summary)¶
- Migrations V192 to V195 add nullable columns to
service_provider_oauth:jwks(V192);logo_uri,policy_uri,tos_uri,userinfo_signed_response_alg,request_uris(V193);session_management(V194);initiate_login_uri(V195). Migration V196 adds a change-notification trigger onrealm_provisioning_config. All catalog-only: no table rewrite, no value touched. - Relying parties that use the email address, name or other profile claims must ask for the scope (below). Most
do already; check the ones that send only
scope=openid. - Relying parties that read token claims from userinfo (
iss,aud,exp,scope,client_id,sid,acr,amr, ...) must read them from the ID token or the access token instead (below). - Nothing else changes until you configure it: the implicit and hybrid flows and session management are off for every client, and the new client fields are empty.
Tokens carry profile, email, address and phone claims only for the scopes granted¶
- What changed. An ID token or access token carries the claims of the
profile,email,addressandphonescopes (OpenID Connect Core 1.0 §5.4) only when that scope was granted, or when the claim is named in theclaimsrequest parameter (§5.5) for that token's channel (id_tokenfor the ID token,userinfofor the access token) and belongs to a scope the client is registered for and that was granted: by the user's consent, or, for a client without a consent screen, by its registration. Before, every token carried the user's whole standard profile whatever was requested. Userinfo is built from the access token, so it follows the same rule. Unchanged:realm_access,resource_access, organizations, claims released by protocol mappers, workload-identity tokens and the tokens a client or agent gets as itself (client_credentials). - Who is affected.
- Relying parties that request only
openidand reademail,name,preferred_usernameor other profile claims: those claims are now absent. - Token-exchange on-behalf-of tokens: they carry these claims only when their scope includes the scope the claims belong to.
- The admin console: its
helix-consoleclient was seeded withopenid,profile. It is now seeded withopenid,profile,email, the server addsemailto the existinghelix-consoleclient of every realm at start-up, and the console requestsopenid profile email. Nothing to do. - What to do. Make each relying party request the scopes whose claims it uses, typically
openid profile email(many already do, for example Nextclouduser_oidc), and make sure each client is registered for those scopes. For token exchange, request the scope in the exchange.
Userinfo returns claims about the end-user only¶
- What changed. Userinfo (OpenID Connect Core 1.0 §5.3.2) returns
sub, the released standard claims,claims-parameter claims,realm_access,resource_access, organizations, verified claims and the BSN where released. It no longer returns the access token's own claims:iss,aud,exp,iat,nbf,jti,scope,client_id,sid,azp,auth_time,nonce,acr,amr,cnf,act,may_act. For a client withuserinfoSignedResponseAlgset, the response is a JWT (application/jwt) signed with the realm's ID-token key at that algorithm, withissandaud(the client) besides the end-user claims; for every other client it stays JSON. - Who is affected. Relying parties or gateways that read token metadata (expiry, scopes, session id,
acr/amr) from the userinfo response.realm_accessis still there. - What to do. Read those values from the ID token (
sid,auth_time,acr,amr) or from token introspection (exp,scope,client_id).
Standard claims in their JSON types¶
- What changed (OpenID Connect Core 1.0 §5.1, §5.1.1):
updated_atis a number (seconds since the epoch),phone_number_verifieda boolean, andaddressone JSON object withformatted,street_address,locality,region,postal_codeandcountry. Before,updated_atandphone_number_verifiedwere strings and the address members were flat claims (address.locality, ...). A stored value that is no such value is left out rather than sent mistyped. - Who is affected. Code that parsed
updated_atorphone_number_verifiedas strings, or readaddress.*as separate claims. - What to do. Read them as the specification types them; read the address members from the
addressobject.
Dynamic Client Registration defaults and metadata¶
- What changed.
- A registration without
scopegetsopenid, plusoffline_accessfor a client of therefresh_tokengrant (RFC 7591 §2 lets the server choose the default). Before, such a client got no scope, and itsscope=openidrequest failed withinvalid_scope. - A response that issues a
client_secretcarriesclient_secret_expires_at: 0(the secret does not expire; RFC 7591 §3.2.1); without a secret it is absent. - Accepted and returned:
jwks(mutually exclusive withjwks_uri),id_token_signed_response_alg,userinfo_signed_response_alg,logo_uri,policy_uri,tos_uri,request_urisandinitiate_login_uri. - Response types with
id_tokenortokenneed theimplicitgrant, which registration may add only when the realm administrator allows that grant for registration (never by default). - Who is affected. Clients that register themselves. A client registered without
scopethat needs more thanopenid(andoffline_access) gets nothing further by default. - What to do. Nothing for existing registrations. A registering client that needs
profileoremailsends them inscope.
New client settings, all off or empty by default¶
- What changed. Per client, in the admin API, Dynamic Client Registration, the realm export/import and the console (OpenID Connect flows and OIDC client settings):
- The implicit and hybrid flows (
id_token,id_token token,code id_token,code token,code id_token token): theimplicitgrant type, off by default and only together withauthorization_code. Refused (400, fieldgrantTypes) for a client with a FAPI setting (a required signed request object, certificate-bound access tokens, a JARM mode) and in a realm with the HIGH key-custody profile. The HIGH rule holds at use too: in a HIGH realm the authorization endpoint never answers an implicit or hybrid request, whatever a client has stored, and a move to HIGH is refused (409, codeimplicitFlowClients, naming the clients) while a client of the realm has theimplicitgrant. An ID token from the authorization endpoint needs anonce; an access token from it lives at most 5 minutes and never comes with a refresh token, and a second use of a hybrid flow's code revokes it with the code's other tokens. jwks(a JWK Set by value, instead ofjwksUrl),logoUri,policyUri,tosUri,userinfoSignedResponseAlg,requestUris(request objects by reference, fetched only from a registered URI),sessionManagement(session_stateand the check-session iframe, off by default) andinitiateLoginUri.- Who is affected. Nobody until a setting is used.
- What to do. Turn the implicit or hybrid flow on only for a relying party that cannot use the code flow, and put the proxy setting below in place first.
Discovery states more¶
- What changed.
/.well-known/openid-configurationnow lists: scopes_supported:openid,profile,email,address,phone; andaddressinclaims_supported;request_parameter_supported,request_uri_parameter_supportedandrequire_request_uri_registration, alltrue, withrequest_object_signing_alg_values_supported(RS256);userinfo_signing_alg_values_supported(those ofRS256,PS256,ES256the realm publishes ID-token keys for);response_modes_supported:queryandform_post, plusfragmentin a realm that advertises the implicit and hybrid flows (response_mode=form_postis now honoured for every response type, errors included; before it was ignored);frontchannel_logout_supportedandfrontchannel_logout_session_supported:true;check_session_iframe, only in a realm where a client uses session management;- the implicit and hybrid response types and the
implicitgrant, only in a realm where a client has that grant or registration may add it. - These per-realm facts come from the configuration cache (V196 keeps it current), so a warm discovery request still reads nothing from the database.
- Who is affected. Relying parties that configure themselves from discovery; they may now choose
form_postor request objects by reference. - What to do. Nothing.
Implicit and hybrid responses need a larger proxy response-header buffer¶
- What changed. Implicit and hybrid responses carry the ID token and access token in the
Locationheader of the redirect. With many claims that header exceeds the 4 KB default response-header buffer of ingress-nginx (4 to 8 KB in other proxies), and the proxy answers502. - Who is affected. Installations that turn the implicit or hybrid flow on for a client.
- What to do. Behind ingress-nginx, set the annotation
nginx.ingress.kubernetes.io/proxy-buffer-size: "32k"(chart:ingress.annotations."nginx\.ingress\.kubernetes\.io/proxy-buffer-size"="32k"); behind nginx,proxy_buffer_size 32k; proxy_buffers 8 32k;. The chart does not set it by default.
A client assertion without client_id is accepted¶
- What changed. A
private_key_jwtorclient_secret_jwtrequest that leaves outclient_id(OPTIONAL with an assertion, RFC 7521 §4.2) is accepted on every endpoint that authenticates clients: the client is the assertion'sisswhen it equals itssub(RFC 7523 §3). Before, it was refused withinvalid_request. The assertion is verified exactly as before (signature against the client's keys, audience, lifetime, single use); one that names no single client isinvalid_request. - Who is affected. Clients that send only the assertion.
- What to do. Nothing.