Skip to content

v0.23.0

Compare
Choose a tag to compare
@sebadob sebadob released this 10 May 09:18
· 478 commits to main since this release
d540a74

This release does the first preparations to prepare a future v1.0.0 release.
Quite a few values have been cleaned up or improved.

Breaking

rauthy-client compatibility

If you are using the rauthy-client, you should upgrade to v0.4.0 before
upgrade Rauthy to v0.23.0. Any older client version will not understand the new grant type for the OAuth2
Device Authorization grant.

Removal of UNSAFE_NO_RESET_BINDING in favor of PASSWORD_RESET_COOKIE_BINDING

The config variable UNSAFE_NO_RESET_BINDING has been removed in favor of PASSWORD_RESET_COOKIE_BINDING.
The logic for this security feature has been reversed. The default behavior until now was to block subsequent
requests to the password reset form if they provided an invalid binding cookie. This created issues for people
that were using evil E-Mail providers. These would scan their users E-Mails and use links inside them.
This link usage however made it impossible for "the real user" to use the link properly, because it has been
used already by its provider.
In some cases, this hurts the UX more than it is a benefit to the security, so this feature is now an opt-in
hardening instead of opt-out evil provider error fixing.
Additionally, to improve the UX even further, the additional E-Mail input form has been removed from the password
reset page as well. The security benefits of this were rather small compared to the UX degradation.
#365
1af7b92

Removal of OFFLINE_TOKEN_LIFETIME config var

OFFLINE_TOKEN_LIFETIME has been removed from the config. This variable has been deprecated since a lof
of versions now. The offline_access scope was not even allowed via the UI for a long time now, so these offline
tokens were never issued anyway.
The "new" mechanism Rauthy uses with the switch in the Admin UI to issue / allow refresh tokens for a client
is much more clear, since the offline_access scope produces a lot of confusion for people new to OIDC.
From the name, it simply makes no sense that you need to activate offline_access to get a refresh token.
Having an option named "allow refresh tokens" is just so much better.
71db7fe

Change in GET /clients/{id}/secret

If you used the endpoint for retrieving a client secret with an API key before, you need to change the method.
The endpoint works exactly the same, but the method has been changed from a GET to a POST to request and validate
the additional CSRF token from the Admin UI.
72f077f

Removal of the Refresh Token switch in Admin UI

The Refresh Token switch for a client config in the Admin UI has been removed.
The old behavior was misleading and unintuitive, I just got rid of that switch.

If you want to use the refresh flow with a client, the only thing you need to do is to allow the refresh_token flow.
You needed to do this before anyway, but in addition enable the switch further down below. So this is not really a
breaking change, but could lead to confusion, if this switch is just gone.
2ece6ed

Features

OAuth 2.0 Device Authorization Grant

This release brings support for the OAuth 2.0 Device Authorization Grant.
On top of the default RFC spec, we have some additional features like optional rate limiting and being able to
do the flow with confidential clients as well. The rauthy-client has the
basics implemented as well for fetching tokens via the device_code flow. An automatic refresh token handler is
on the TODO list though. A small
example exists as well.
You will find new sections in the account and admin -> user view, where you can see all linked devices, can give
them a friendly name and revoke refresh tokens, if they exist.
544bebe
8d028bf
e8077ce
62d41bc
51a50ac
9352b3c

Dynamic Server Side Search + Pagination

Until now, the Admin UI used client side searching and pagination. This is fine for most endpoints, but
the users can grow quite large depending on the instance while all other endpoints will return rather small
"GET all" data.
To keep big Rauthy instances with many thousands of users fast and responsive, you can set a threshold for
the total users count at which Rauthy will dynamically switch from client side to server side pagination
and searching for the Admin UI's Users and Sessions page.

# Dynamic server side pagination threshold
# If the total users count exceeds this value, Rauthy will dynamically
# change search and pagination for users in the Admin UI from client
# side to server side to not have a degradation in performance.
# default: 1000
SSP_THRESHOLD=1000

For smaller instances, keeping it client side will make the UI a bit more responsive and snappy.
For higher user counts, you should switch to do this on the server though to keep the UI fast and not
send huge payloads each time.

b4dead3
9f87af3
e6d39d1

UX Improvement on Login

The login form now contains a "Home" icon which will appear, if a client_uri is registered for the current
client. A user may click this and be redirected to the client, if a login is not desired for whatever reason.
Additionally, if the user registration is configured to be open, a link to the user registration will be shown
at the bottom as well.
b03349c
b03349c

Unlink Account from Provider

A new button has been introduced to the account view of federated accounts.
You can now "Unlink" an account from an upstream provider, if you have set it up with at least
a password or passkey before.

8b1d9a8

Link Existing Account to Provider

This is the counterpart to the unlink feature from above.
This makes it possible to link an already existing, unlinked user account to an upstream auth provider.
The only condition is a matching email claim after successful login. Apart from that, there are quite a few things
going on behind the scenes and you must trigger this provider link from an authorized, valid session from inside your
user account view. This is necessary to prevent account takeovers if an upstream provider has been hacked in some way.

fdc683c

Bootstrap default Admin in production

You can set environment variables either via rauthy.cfg, .env or as just an env var during
initial setup in production. This makes it possible to create an admin account with the very first
database setup with a custom E-Mail + Password, instead of the default [email protected] with
a random password, which you need to pull from the logs. A single API Key may be bootstrapped as well.

#####################################
############# BOOSTRAP ##############
#####################################

# If set, the email of the default admin will be changed
# during the initialization of an empty production database.
BOOTSTRAP_ADMIN_EMAIL="[email protected]"

# If set, this plain text password will be used for the
# initial admin password instead of generating a random
# password.
#BOOTSTRAP_ADMIN_PASSWORD_PLAIN="123SuperSafe"

# If set, this will take the argon2id hashed password
# during the initialization of an empty production database.
# If both BOOTSTRAP_ADMIN_PASSWORD_PLAIN and
# BOOTSTRAP_ADMIN_PASSWORD_ARGON2ID are set, the hashed version
# will always be prioritized.
BOOTSTRAP_ADMIN_PASSWORD_ARGON2ID='$argon2id$v=19$m=32768,t=3,p=2$mK+3taI5mnA+Gx8OjjKn5Q$XsOmyvt9fr0V7Dghhv3D0aTe/FjF36BfNS5QlxOPep0'

# You can provide an API Key during the initial prod database
# bootstrap. This key must match the format and pass validation.
# You need to provide it as a base64 encoded JSON in the format:
#
# ```
# struct ApiKeyRequest {
#     /// Validation: `^[a-zA-Z0-9_-/]{2,24}$`
#     name: String,
#     /// Unix timestamp in seconds in the future (max year 2099)
#     exp: Option<i64>,
#     access: Vec<ApiKeyAccess>,
# }
#
# struct ApiKeyAccess {
#     group: AccessGroup,
#     access_rights: Vec<AccessRights>,
# }
#
# enum AccessGroup {
#     Blacklist,
#     Clients,
#     Events,
#     Generic,
#     Groups,
#     Roles,
#     Secrets,
#     Sessions,
#     Scopes,
#     UserAttributes,
#     Users,
# }
#
# #[serde(rename_all = "lowercase")]
# enum AccessRights {
#     Read,
#     Create,
#     Update,
#     Delete,
# }
# ```
#
# You can use the `api_key_example.json` from `/` as
# an example. Afterwards, just `base64 api_key_example.json | tr -d '\n'`
#BOOTSTRAP_API_KEY="ewogICJuYW1lIjogImJvb3RzdHJhcCIsCiAgImV4cCI6IDE3MzU1OTk2MDAsCiAgImFjY2VzcyI6IFsKICAgIHsKICAgICAgImdyb3VwIjogIkNsaWVudHMiLAogICAgICAiYWNjZXNzX3JpZ2h0cyI6IFsKICAgICAgICAicmVhZCIsCiAgICAgICAgImNyZWF0ZSIsCiAgICAgICAgInVwZGF0ZSIsCiAgICAgICAgImRlbGV0ZSIKICAgICAgXQogICAgfSwKICAgIHsKICAgICAgImdyb3VwIjogIlJvbGVzIiwKICAgICAgImFjY2Vzc19yaWdodHMiOiBbCiAgICAgICAgInJlYWQiLAogICAgICAgICJjcmVhdGUiLAogICAgICAgICJ1cGRhdGUiLAogICAgICAgICJkZWxldGUiCiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJncm91cCI6ICJHcm91cHMiLAogICAgICAiYWNjZXNzX3JpZ2h0cyI6IFsKICAgICAgICAicmVhZCIsCiAgICAgICAgImNyZWF0ZSIsCiAgICAgICAgInVwZGF0ZSIsCiAgICAgICAgImRlbGV0ZSIKICAgICAgXQogICAgfQogIF0KfQ=="

# The secret for the above defined bootstrap API Key.
# This must be at least 64 alphanumeric characters long.
# You will be able to use that key afterwards with setting
# the `Authorization` header:
#
# `Authorization: API-Key <your_key_name_from_above>$<this_secret>`
#BOOTSTRAP_API_KEY_SECRET=

1a7d9e4

New config var USERINFO_STRICT

You can now set a new config variable called USERINFO_STRICT. If set so true, Rauthy will do additional
validations on the /userinfo endpoint and actually revoke (even otherwise still valid) access tokens,
when any user / client / device it has been issued for has been deleted, expired or disabled. The non-strict
mode will simply make sure the token is valid and that the user still exists. The additional validations
will consume more resources because they need 1-2 additional database lookups but will provide more strict
validation and possible earlier token revocation. If you don't need it that strict, and you are resource
constrained, set it to false.
198e7f9

at_hash in id_token

The Rauthy id_token now contains the access token hash at_hash claim. This is needed for additional
downstream validation, if a client provides both tokens and they are not coming from Rauthy directly.
With the additional validation of the at_hash claim, clients can be 100% sure, that a given id_token
belongs to a specific access_token and has not been swapped out.
d506865

Better roles, groups and scopes names

The allowed names for roles, groups and scopes have been adjusted. Rauthy allows names of up to 64 characters
now and containing : or *. This will make it possible to define custom scopes with names like
urn:matrix:client:api:guest or urn:matrix:client:api:*.

a5982d9
50d0214

Configurable Cookie Security

Depending on your final deployment, you may want to change the way Rauthy's set's its cookies, for instance if you
want to create your own UI endpoints but still want to be able to communicate with the API.

The default cookie setting has been changed in a way that all cookies will have the __Host- prefix now, which provides
the highest level of security. There might be cases where you don't want this and rather have the path restriction to
/auth from before, for instance when you host an additional app on the same origin behind a reverse proxy, that should
not be able to read Rauthy's cookies.

And finally, for all Safari users, since Safari does not consider localhost to be secure when testing, you can even
set insecure cookies for testing purposes.

# You can set different security levels for Rauthy's cookies.
# The safest option would be 'host', but may not be desirable when
# you host an application on the same origin behind a reverse proxy.
# In this case you might want to restrict to 'secure', which will then
# take the COOKIE_PATH from below into account.
# The last option is 'danger-insecure' which really should never be used
# unless you are just testing on localhost and you are using Safari.
#COOKIE_MODE=host

# If set to 'true', Rauthy will bind the cookie to the `/auth` path.
# You may want to change this only for very specific reasons and if
# you are in such a situation, where you need this, you will know it.
# Otherwise don't change this value.
# default: true
#COOKIE_SET_PATH=true

e697389

Auto-Blacklisting of suspicious requests

Rauthy can now auto-blacklist IP's that do suspicious requests, like for instance:

  • /.ssh/
  • /.kube/config
  • /backup.zip
  • /wp-admin/

... and so on.
Rauthy has a "catch all" API route handler on / which looks for these by default.
By default, IPs from such requests will be blacklisted for 24 hours, but you can of course configure this.

# The "catch all" route handler on `/` will compare the request path
# against a hardcoded list of common scan targets from bots and attackers.
# If the path matches any of these targets, the IP will be blacklisted
# preemptively for the set time in minutes.
# You can disable it with setting it to `0`.
# default: 1440
SUSPICIOUS_REQUESTS_BLACKLIST=1440

# This will emit a log with level of warning if a request to `/` has
# been made that has not been caught by any of the usual routes and
# and handlers. Apart from a request to just `/` which will end in
# a redirect to `/auth/v1`, all additional path's will be logged.
# This can help to improve the internal suspicious blocklist in the
# future.
# default: false
SUSPICIOUS_REQUESTS_LOG=flase

Changes for /auth/v1/whoami

The whoami endpoint has been changed. It does not return all headers anymore, because this could possibly leak sensitive
headers in some environments, especially with the new auth headers feature in some situations.
Instead, it only returns the peer IP that Rauthy extracted for this request. This can be very helpful if you need to
configure the extraction, for instance when you are behind a reverse proxy or CDN.
758b31c

New sorting options for users

Users in the Admin UI can now be sorted by their created_at or last_login timestamp.
Users that never have logged in will always be at the end of the list, since this value might be undefined.
4c41d64

Bugfixes

  • The button for requesting a password reset from inside a federated account view has been
    disabled when it should not be, and therefore did not send out requests.
    39e585d
  • A really hard to reproduce bug where the backend complained about a not-possible mapping
    from postgres INT4 to Rust i64 as been fixed. This came with the advantage of hacing
    a few more compile-time checked queries for the users table.
    1740177
  • A fix for the /users/register endpoint in the OpenAPI documentation has been fixed, which
    was referencing the wrong request body
    463e424
  • The page title for a password reset now shows "New Account" if this is a fresh setup and only
    "Password Reset" when it actually is a reset
    84bbdf7
  • The "User Registration" header on the page for an open user registration as only showing up,
    when the domain was restricted.
    fc3417e
  • Button labels were misplaced on chrome based browsers
    901eb55
  • /authorize for logins had a bit too strict validation for the user password, which had a chance that
    a new password a user just set, would be rejected because of some invalid special chars not being allowed
    9bb0a72
  • when resources in the Admin UI have been re-fetched, for instance because of a user deletion, the search input
    has not been emptied
    033db25
  • the deprecated x-xss-protection header has been removed
    5008438

Images

Postgres

ghcr.io/sebadob/rauthy:0.23.0

SQLite

ghcr.io/sebadob/rauthy:0.23.0-lite