Skip to main content

OAuth

OAuth, or Open Authorization, is a standard protocol that provides a method for clients to access server resources on behalf of a user. It acts as an intermediary on behalf of the end-user, providing the service with an access token that authorizes specific account information to be shared. This allows users to grant third-party applications access to their information on other services without sharing their credentials. For security reasons, it is strongly recommended to always use OAuth to authenticate your users and, if possible, disable the Basic authentication scheme altogether.

OAuth 2.0 is automatically enabled in Stalwart Mail Server and does not require any special configurations to function. There are however some settings that can be tweaked to control when tokens expire, how often they need to be renewed, as well as other security settings.

Authorization Flows

In order to facilitate and encourage OAuth adoption by system administrators, Stalwart Mail Server includes support for both the OAuth 2.0 Authorization Code Flow (RFC6749) and OAuth 2.0 Device Authorization Flow (RFC8628). Deciding which authorization flow to use is up to the client accessing the Mail Server account.

Authorization Code

The Authorization Code Flow is one of the most commonly used OAuth 2.0 flows, ideal for server-side applications where the source code is not publicly exposed. It begins with the client directing the user to the authorization server. The user authenticates with the server and gives consent for the client to access their protected resources. The server then redirects the user back to the client with an authorization code. The client exchanges this code with the server for an access token and, optionally, a refresh token. These tokens are then used by the client to access the user's protected resources.

Device Authorization

The Device Authorization Flow, also known as the Device Flow, is an OAuth 2.0 extension that enables devices with no browser or limited input capability, such as smart TVs, consoles, and printers, to obtain user authorization. In this flow, the client instructs the user to perform the authorization request on a secondary device, like a smartphone. The client polls the authorization server until the user completes the authorization request, at which point the server issues tokens to the client. This flow ensures a smooth user experience for devices that cannot conveniently use other OAuth flows.

Encryption

All tokens issued by Stalwart Mail Server are cryptographically signed using a mechanism inspired by PASETO security tokens:

  • An encryption key is derived using the BLAKE3 cryptographic hash function combining the principal encryption key (configurable with the oauth.key parameter) with the device id, the expiration time, account details and an Argon2 hash of the account's password.
  • A nonce is generated using a BLAKE3 hash of the user details and the expiration time of the token.
  • Finally, the derived encryption key and nonce are employed to digitally sign the token using AES-256-GCM-SIV.

During installation, a 512 bits long encryption key is automatically generated for you. If you wish to replace it, you can generate a new one using OpenSSL or alternatively in Linux systems using the command LC_ALL=C tr -dc '[:alpha:]' < /dev/urandom | head -c 64. Once you have your new key, update the oauth.key parameter, for example:

[oauth]
key = "sDRvvROsJmRUnjIfcUiDUSaAxdQpfixuLvdwlSffptaxUnSQZALenZSYUPQQByUI"

Or, to read the key from the environment variable OAUTH_KEY:

[oauth]
key = "%{env:OAUTH_KEY}%"
Be aware that
  • If the encryption key is changed, all existing OAuth tokens will be immediately revoked.

  • On distributed systems, all nodes have to use the exact same encryption key. Otherwise, tokens issued in one node will not be valid in other nodes.

  • The encryption key must be kept private. It is recommended that it is specified using an environment variable, which will prevent the key from being stored in the configuration file in plain text. If using an environment variable is not possible or practical, then make sure that only the Stalwart Mail Server process has access to the configuration file where it is stored. In Unix systems this can be done with the commands:

    sudo chown stalwart-mail /opt/stalwart-mail/etc/config.toml
    sudo chmod 600 /opt/stalwart-mail/etc/config.toml

Expiration

System administrators can configure under the oauth.expiry section the expiration time of both access and refresh tokens as well as the authorization codes issued to users and devices:

  • token: Expiration time of an OAuth access token in seconds, defaults to 3600 seconds (1 hour).
  • refresh-token: Expiration time of an OAuth refresh token in seconds. Defaults to 2592000 seconds (1 month).
  • refresh-token-renew: Number of remaining seconds in a refresh token before a new one is issued to the client. Defaults to 345600 seconds (4 days).
  • user-code: Expiration time in seconds of a user code issued by the device authentication flow. Defaults to 1800 seconds (30 minutes).
  • auth-code-expiry: Expiration time in seconds of an authorization code issued by the authorization code flow. Defaults to 600 seconds (10 minutes).

Example:

[oauth.expiry]
user-code = "30m"
auth-code = "10m"
token = "1h"
refresh-token = "30d"
refresh-token-renew = "4d"

The oauth.auth.max-attempts parameter can be used to prevent brute-force attacks against the authorization code flow. If the user fails to authenticate after the configured number of attempts, the authorization code is invalidated and the user has to start the flow again.

Example:

[oauth.auth]
max-attempts = 3

Revocation

Access and refresh tokens issued by Stalwart Mail Server can be revoked by both account owners and system administrators simply by changing the account's password. In the near future it will also be possible to revoke individual tokens issued to a specific OAuth client id.

OAuth Endpoints

OAuth clients conforming to RFC8414 can obtain all available OAuth endpoints by requesting the authorization server metadata which is published at /.well-known/oauth-authorization-server. Clients that do not support RFC8414 need to be manually configured to use the appropriate endpoint:

  • /auth/token: Token endpoint, used by all flows to obtain and refresh access tokens.
  • /auth/device: Device authorization endpoint, used by the device flow.

Once the OAuth client obtains the authorization code, users are then authenticated on any of these two endpoints:

  • /authorize/code: Used by the authorization code flow to authenticate accounts.
  • /authorize: Used by the device authorization flow to authenticate accounts.

Conformed RFCs