Skip to content

v0.36.1

Latest

Choose a tag to compare

@sebadob sebadob released this 24 Jul 18:28
7c2d493

Security

There was a security issue with Moderate severity during token refresh under some circumstances that allows cross-client token minting and identity/scope confusion during token refresh. You should do a timely update or at least make sure you are not vulnerable. If you run the default config, you should be good.

If you have public clients with the refresh_token flow enabled and either you have configured dynamic_clients.enable = true + dynamic_clients.reg_token not set or ephemeral_clients.enabled = true + ephemeral_clients.allowed_flows contains refresh_token, it
might be possible to abuse an issue. There is a slight chance to make it work without ephemeral or dynamic clients, but that is out of Rauthys control. The main thread comes from the combination of a public client with allowed token refresh, and a stolen or leaked refresh token.

An advisory and CVE / PoC will be made public at a later point.

Changes

Per-Client Favicons

Client branding now supports a dedicated browser favicon for each client, independently of the login logo. Favicons can be uploaded, previewed, and removed from the Admin UI.

#1653

Session MFA Upgrade after Passkey Registration

Registering a Passkey from the Account dashboard upgrades the current session to MFA now. Before, is_mfa stayed false until the next login, which meant a fresh admin account that just enrolled its first Passkey was still rejected by admin_force_mfa and had to log out and back in. The Account dashboard also updates the MFA indicator directly after registering or deleting a Passkey instead of only after a manual page reload.

#1649

Token Exchange (RFC 8693)

Rauthy supports the RFC 8693 token exchange now, via the urn:ietf:params:oauth:grant-type:token-exchange grant on the existing token endpoint. It lets a service trade an access token it received for one that is scoped to a downstream service, instead of forwarding a token that was never minted for that target.

Both impersonation and delegation are supported. With an actor_token, the exchanged token carries an act claim naming the acting party, so a resource server can tell "A acting for B" apart from "B"; a delegation chain stays nested inside it.

The exchange is deny-by-default and needs two things on the exchanging client: token_exchange in its flows_enabled, and the requested target in its allowed_resources, which is the same allow-list the RFC 8707 resource indicators use. Only confidential clients may exchange.

Rauthy only accepts access tokens as subject_token / actor_token, and only ever issues an access token in return. An exchanged token deliberately never comes with a refresh token. may_act is not supported yet.

#1652

RFC 8414 Metadata Endpoints

Rauthy now correctly serves the .well-known metadata documents under additional endpoints matching the RRFC 8414. This was necessary for CIMD discovery that's used by e.g. Claude.ai.

#1656

Opt-in to ignore unknown grant-types from ephemeral clients

This is a fix for clients relying on CIMD (like AI agents) when you don't have control over the client documents, and they include unknown / invalid grant types, even when they are unused.

[ephemeral_clients]
# A dynamic client registration is always rejected when it advertises a grant
# type Rauthy does not support. Some spec-valid CIMD clients (e.g. claude.ai)
# advertise an unsupported grant (`urn:ietf:params:oauth:grant-type:jwt-bearer`)
# in their metadata document without ever using it, which would otherwise cause
# the whole document to be rejected. Setting this to `true` lets an ephemeral
# (CIMD) client document through by sanitizing - stripping - the unsupported
# grant types instead of rejecting it.
#
# This applies ONLY to ephemeral clients. Dynamic client registration (DCR) and
# admin-managed clients always keep rejecting unknown grant types.
#
# default: false
# overwritten by: EPHEMERAL_CLIENTS_IGNORE_UNKNOWN_AUTH_FLOWS
ignore_unknown_auth_flows = false

#1658

RFC 8252 for localhost callbacks

Rauthy uses a more-strict requirement for redirect_uris back to localhost. If you want to match any port, you need to specifically allow it using the glob pattern with e.g. http://localhost:*. However, CIMD clients do not know this and rely on RFC 8252 which allows any port for localhost. This is the standard, but less secure. You can now opt-in to it:

[access]
# If set to `true`, loopback redirect URIs (to `localhost`, `127.0.0.1`
# or `[::1]`) will match on any port, as required by RFC 8252 section 7.3
# for native / CLI apps that bind an ephemeral loopback port at runtime.
# Both the port-less form and an explicit `*` wildcard are accepted for
# `localhost` when this is enabled.
#
# This only applies to dynamic and ephemeral clients. Static clients
# always require an exact match or an explicit `*` wildcard, even with
# this option set, because an admin has full control over their config.
#
# Only enable this if you need it, e.g. an MCP client whose loopback
# redirect port is not known in advance and cannot be pre-registered.
# It is `false` by default to keep redirect matching as strict as
# possible out of the box.
#
# default: false
# overwritten by: RFC_8252_ENABLE
rfc_8252_enable = false

#1621

preferred_username during User Registration

It is now possible to provide a preferred_username during the user registration when using API Keys. This gets rid of an additional round-trip that was necessary when working with the API instead of the UI.

#1640

Relaxed regex for Client Names

Client names are now allowed to also contain ( and ).

#1621

Bugfix

  • The sub claim is now omitted from tokens if it is null anyway.
    #1655
  • The resource claim was dropped during UI-initiated, immediate session / login refreshes.
    #1657
  • A callback for an upstream auth provider login is deleted as soon as it has been validated now. Before, only a failed state, XSRF token or PKCE verifier check deleted it. A callback that passed all three stayed in the cache until its 300 second TTL ran out, whether the login then succeeded or failed. This also makes the behaviour match what the function documented all along.
    #1664
  • user.last_login was wrongly updated on token refreshes.
    #1659