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.
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.
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.
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 admin@localhost.de
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="alfred@batcave.io"
# 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=
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:*
.
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
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 postgresINT4
to Rusti64
as been fixed. This came with the advantage of hacing
a few more compile-time checked queries for theusers
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