Breaking
Empty User-Agent
s rejected
While implementing Geoblocking (see below), a check for the User-Agent
has been added. If this is empty, requests will be rejected. If you are doing something via API-Keys, make sure your clients send a proper User-Agent
header. This rejection does not provide any security at all, it just catches a few bots out of the box.
Changes
Remembered Login Locations
Rauthy will now remember Login locations / IPs for each user and send out an E-Mail notification, if a login from a new IP / location was done. This E-Mail will also contain a link to revoke all Sessions and Refresh tokens for this user, which will also trigger a backchannel logout to all configured clients, in case an invalid login was done for a user. Users should be able to handle these situations without the need of an Admin in this case.
IP-Geoblocking
Rauthy can now block requests depending on the origin country of the peer IP address. You can either provide a custom header value, which is inserted for instance by a WAF or CDN, like in case of Cloudflare the CF-IPCountry
header, or you can opt-in and provide a Maxmind AccountID + License for either the free GeoLite databases, or a paid version of it. These GeoLite databases are published under the Creative Commons License, you only need to create a free account to generate a License. Rauthy will download the configured DB and update it regularly.
This IpGeo information will also be used for the Remembered Login Locations feature above. The country and depending on the chosen DB type also the city will be added to the E-Mail notice.
[geolocation]
# If you have a configured and working Geolocation setup, you can
# define if un-resolvable IP addresses should be blocked. By default,
# if a Country cannot be found for a certain IP address, it will be
# allowed anyway. This is necessary to allow private network connections
# for instance. Only if you run a public Rauthy instance, and you will
# guaranteed always connect with a public Peer IP, you might want to
# set this to `true`.
#
# default: false
# overwritten by: GEO_BLOCK_UNKONW
block_unknown = false
# If you have a WAF or CDN which injects a geoloaction header
# with the country code, provide the name here. For instance,
# in case of Cloudflare, this would be 'CF-IPCountry'.
#
# This header will only be accepted, if Rauthy runs in proxy_mode,
# and the source IP is a trusted proxy, to prevent spoofing.
#
# default: not set
# overwritten by: GEO_COUNTRY_HEADER
country_header = 'CF-IPCountry'
# You can black- or whitelist countries, if you have a configured
# and working Geolocation, either via `country_header` or a
# Maxmind database.
#
# The `country_list_type` can be either `whitelist` or `blacklist`,
# and it will specify the behavior of the `country_list`.
# For instance, if you have `country_list_type = 'whitelist'` and
# `country_list = ['DE', 'FR']`, only access from Germany and France
# will be allowed.
#
# The `whitelist` type is a `default-deny`, while `blacklist` is
# `default-allow`.
#
# If `country_list_type` is not set at all, Geoblocking will be
# disabled.
#
# default: not set
country_list_type = 'whitelist'
# default: not set
country_list = []
# If you don't have a header with a country code, you can
# also provide a Maxmind account. Rauthy will then download
# the 'GeoLite2 Country' database regularly and use it for
# geolocating IPs.
#
# The GeoLite databases from Maxmind are free and published
# under the Creative Commons License. You can also provide
# an Enterprise database, which will have more accurate data.
# Check the `maxmind_db_type` below.
#
# default: not set
# overwritten by: GEO_MAXMIND_ACC_ID
maxmind_account_id = ''
# overwritten by: GEO_MAXMIND_LICENSE
maxmind_license_key = ''
# If `maxmind_account_id` and `maxmind_license_key`, this
# will be the directory being used for DB download and storage.
#
# default: 'data'
# overwritten by: GEO_MAXMIND_DIR
maxmind_db_dir = 'data'
# By default, the `GeoLite2-Country` database from Maxmind is
# being used. The IP Geolocation databases are loaded fully into
# memory at startup to speedup lookups. The size therefore makes
# a big difference, not only for lookup speed, but also in terms
# of memory usage. The Country DB adds ~10MB of memory overhead,
# while the City DB is around 65MB.
#
# Possible Values (case-sensitive):
# - GeoLite2-Country
# - GeoLite2-City
#
# If you have access to paid Maxmind databases, you can add the
# db_type in a way that it resolves to a valid download link.
# The link will be created with the following template:
# `https://download.maxmind.com/geoip/databases/{maxmind_db_type}/download?suffix=tar.gz`
#
# default: 'GeoLite2-Country'
# overwritten by: GEO_MAXMIND_DB_TYPE
maxmind_db_type = 'GeoLite2-Country'
# If you configured a `maxmind_account_id` + `maxmind_license_key`,
# you can change the time when the DB update job runs. By default,
# it runs every night at 05:00. It will check if y new version of
# the MaxMind DB is available and if so, download it.
#
# Accepts cron syntax:
# "sec min hour day_of_month month day_of_week year"
#
# default: "0 0 5 * * * *"
# overwritten by: GEO_MAXMIND_UPDATE_CRON
maxmind_update_cron = "0 0 5 * * * *"
While IP Geo data is very helpful and can boost your security, it is fully optional. Everything will work if you don't provide any of the > options. You just won't have Geo data in the "Login from new location" notifications and other places, and you will of course not be > able to block requests depending on the origin country.
TLS Hot-Reload
Rauthy can now hot-reload TLS Key + Certificates. If started with server.scheme
set to any https
value and TLS certificates are used, Rauthy will watch for file changes on tls.cert_path
+ tls.key_path
and will do a hot-reload of the TLS configuration if anything changes. This is a real hot-reload, meaning there is no restarting the server, and it does it without any interruption in service.
OIDC-backed Forward-Auth
In addition to the already existing, very simple /forward_auth
endpoint, which has limited compatibility, Rauthy now provides a very much advanced version of it. This new version is not a replacement of the old approach, but an addition.
The already existing endpoint is very simple: It expects a valid JWT token to be present in the Authorization
header, parses and validates it, and if it's valid, it returns an HTTP 200 and a 401 otherwise. Depending on auth_headers.enable
, it will also append the Forward-Auth headers to the request, which the reverse proxy could inject into the request sent to the downstream client.
The new version is much improved. It does not work with stateless JWT tokens, but it binds to the Rauthy session. This makes it possible to revoke access as any time. It can also do proper CSRF checks, validates the client and user configuration, and it can make everything work without any modification to the client. On auth success, it behaves in the same way as the already existing endpoint. On invalid though, it will redirect to Rauthys Login, which then again will do another redirect to a Callback UI and therefore trigger a complete OIDC flow. On the callback page, Rauthy can now set fully-secured session cookies and do others things like check the Sec-Fetch-Site
header. This is the most secure it can get, without modifications to the client. The callback page is exposed by Rauthy itself, and can be "injected" into the client app at your reverse proxy level, which makes all of this as secure as possible.
You can do this new Forward-Auth for any client, as long as it's configured properly. Rauthy is quite a bit more strict about the correct client config upfront. This makes it possible to have a few additional safety hooks which will help you prevent unwanted, invalid reverse proxy config, which can happen very quickly for complex setups.
CAUTION: Even though this is probably the most secure you can get with Forward-Auth, it should still only be the last resort, and you should always prefer a native OIDC client implementation, if it exists! If you screw up the reverse proxy config, or if an attacker can find a way around your reverse proxy and skip it, all your security will be gone immediately.
The Rauthy book will be updated in the upcoming days and provide a bit more documentation about the setup.
To help during Forward-Auth setup and making sure you got it right in your environment, the /auth/v1/whoami
endpoint has received an update as well. You can now set access.whoami_headers = true
or use WHOAMI_HEADERS
. This will make the /whoami
endpoint not only return the extracted "real IP", but it will also return all request headers it received. This will help you make sure your setup is working correctly, if you use auth_headers
. By default, this is set to false
. Depending on your internal network setup, this could expose sensitive headers, if you inject any. It will not return values for Cookie
and Rauthys own CSRF token headers, but all others return will show their raw values.
Backups via Admin UI
If Rauthy is running with Hiqlite as the database, you can now view and download existing backups via the Admin UI -> Config -> Backups
section. It shows local backup files and the ones on S3 storage, if it's configured. You also get the option to trigger manual backups with a new button, which gets rid of the issue of updating the cron task to "a few minutes in the future" to trigger a backup on demand.
If you run a HA cluster and want to download local backups via the Admin UI, you will most probably run into errors when downloading older ones, that have been created before this version, if running behind a load balancer. The timestamp part of the filename was dynamically set by each node independently before and only new backups from this version on will have the exact same filename on all nodes.
Re-Authenticate for MFA keys modifications
To be able to modify MFA / Passkeys in any way, a user now needs to re-authenticate. This re-authentication will open a 2-minute window that allows modifications for MFA keys, like adding new ones and deleting existing ones.
Load config from Vault
The ability to load the config file from a Vault source has been added. To do this, you need to provide the ENV var USE_VAULT_CONFIG=true
and a vault.toml
file, that contains the necessary information on how to connect and / or override the settings with ENV vars.
[vault]
# The full address to your vault including scheme and port
#
# default: <empty>
# overwritten by: VAULT_ADDR
addr = ''
# The token that rauthy uses to access the secret
#
# default: <empty>
# overwritten by: VAULT_TOKEN
token = ''
# Secret engine mount point
#
# default: <empty>
# overwritten by: VAULT_MOUNT
mount = ''
# Path within the mount point containing the secret
#
# default: <empty>
# overwritten by: VAULT_PATH
path = ''
# The key (name) of the secret
#
# default: <empty>
# overwritten by: VAULT_CONFIG_KEY
config_key = ''
# KV Version that the secret engine uses.
# Valid values are '1' or '2'.
#
# default: '2'
# overwritten by: VAULT_KV_VERSION
kv_version = ''
# You can provide a root certificate bundle, if you
# are running servers / clients Rauthy needs to connect
# to with self-signed certificates.
# The certificates need to be in PEM format.
#
# overwritten by: HTTP_CUST_ROOT_CA_BUNDLE
#root_ca_bundle = """
#-----BEGIN CERTIFICATE-----
#...
#-----END CERTIFICATE-----
#"""
# If you are testing locally with insecure connections,
# you can set the following var to make it work.
#
# Note: This must be an ENV var and cannot be
# given as a normal TOML value. It only exists here
# for completeness / documentation.
#
#DANGER_VAULT_INSECURE=true
Bluesky / AT Protocol
This version supports Bluesky's at-proto. This is probably not used by most people and it's opt-in:
[atproto]
# Set to `true` to enable the ATProto provider. If the public URL is
# 'localhost' it should be changed to '127.0.0.1', if `dev_mode = true`
# this also applies for the `provider_callback_url`.
#
# default: false
enable = false
Additional Event Types
Some new Rauthy Event types have been added. These are now configurable in their notification level as all the other ones. The new Events are the following:
- An
Event::ForceLogout
will be created duringDELETE /sessions/{user_id}
. This will happen when and Admin clicks "Force Logout" for a user in the Admin UI. - An
Event::UserLoginRevoke
will be created after a user clicked the login revoke link in the (new) notification E-Mail that is sent out after a login from an unknown location. - An
Event::SispiciousApiScan
will be created when Rauthy detects a suspicious, very much likely malicious API scan.
Anti-Lockout hooks in Admin UI
The Admin UI already had anti-lockout hooks for some important things like the rauthy
client or the rauthy_admin
role. This release adds some of these hooks to user edit and delete pages, if the currently looked at user matches the currently logged-in admin from the session. These hooks prevent, disabling, expiring, and deleting this user, and also removing the rauthy_admin
role from itself. This means a Rauthy admin cannot degrade itself to a non-admin or delete itself by accident. Only other admins can do this. This makes sure, that at least always at least one rauthy_admin
exists and you can never fully lock yourself out of Rauthy.
IPv6 Support for IP Blacklisting
You can now also blacklist IPv6 address via the Admin UI -> Blacklist.
Default difficulty for PoWs reduced
Since PoWs have been added to the Login UI, and a user needs to calculate 2 PoWs if it's a password-account, the default difficulty of 20
was a bit too high for not that powerful devices. Therefore, the default value has been reduced from 20
to 19
to compensate for that.
Bugfix
- The
cluster.backup_keep_days_local
setting was not always read properly and might not have been working like
expected. This lead to local backup cleanup not working properly. Additionally, the default value in docs was wrong.
It's not3
days by default, but30
. This was fixed inhiqlite
directly and the version has been bumped.