140 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Markdown
		
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Markdown
		
	
	
# Refresh Tokens
 | 
						|
 | 
						|
Synapse supports refresh tokens since version 1.49 (some earlier versions had support for an earlier, experimental draft of [MSC2918] which is not compatible).
 | 
						|
 | 
						|
 | 
						|
[MSC2918]: https://github.com/matrix-org/matrix-doc/blob/main/proposals/2918-refreshtokens.md#msc2918-refresh-tokens
 | 
						|
 | 
						|
 | 
						|
## Background and motivation
 | 
						|
 | 
						|
Synapse users' sessions are identified by **access tokens**; access tokens are
 | 
						|
issued to users on login. Each session gets a unique access token which identifies
 | 
						|
it; the access token must be kept secret as it grants access to the user's account.
 | 
						|
 | 
						|
Traditionally, these access tokens were eternally valid (at least until the user
 | 
						|
explicitly chose to log out).
 | 
						|
 | 
						|
In some cases, it may be desirable for these access tokens to expire so that the
 | 
						|
potential damage caused by leaking an access token is reduced.
 | 
						|
On the other hand, forcing a user to re-authenticate (log in again) often might
 | 
						|
be too much of an inconvenience.
 | 
						|
 | 
						|
**Refresh tokens** are a mechanism to avoid some of this inconvenience whilst
 | 
						|
still getting most of the benefits of short access token lifetimes.
 | 
						|
Refresh tokens are also a concept present in OAuth 2 — further reading is available
 | 
						|
[here](https://datatracker.ietf.org/doc/html/rfc6749#section-1.5).
 | 
						|
 | 
						|
When refresh tokens are in use, both an access token and a refresh token will be
 | 
						|
issued to users on login. The access token will expire after a predetermined amount
 | 
						|
of time, but otherwise works in the same way as before. When the access token is
 | 
						|
close to expiring (or has expired), the user's client should present the homeserver
 | 
						|
(Synapse) with the refresh token.
 | 
						|
 | 
						|
The homeserver will then generate a new access token and refresh token for the user
 | 
						|
and return them. The old refresh token is invalidated and can not be used again*.
 | 
						|
 | 
						|
Finally, refresh tokens also make it possible for sessions to be logged out if they
 | 
						|
are inactive for too long, before the session naturally ends; see the configuration
 | 
						|
guide below.
 | 
						|
 | 
						|
 | 
						|
*To prevent issues if clients lose connection half-way through refreshing a token,
 | 
						|
the refresh token is only invalidated once the new access token has been used at
 | 
						|
least once. For all intents and purposes, the above simplification is sufficient.
 | 
						|
 | 
						|
 | 
						|
## Caveats
 | 
						|
 | 
						|
There are some caveats:
 | 
						|
 | 
						|
* If a third party gets both your access token and refresh token, they will be able to
 | 
						|
  continue to enjoy access to your session.
 | 
						|
  * This is still an improvement because you (the user) will notice when *your*
 | 
						|
    session expires and you're not able to use your refresh token.
 | 
						|
    That would be a giveaway that someone else has compromised your session.
 | 
						|
    You would be able to log in again and terminate that session.
 | 
						|
    Previously (with long-lived access tokens), a third party that has your access
 | 
						|
    token could go undetected for a very long time.
 | 
						|
* Clients need to implement support for refresh tokens in order for them to be a
 | 
						|
  useful mechanism.
 | 
						|
  * It is up to homeserver administrators if they want to issue long-lived access
 | 
						|
    tokens to clients not implementing refresh tokens.
 | 
						|
    * For compatibility, it is likely that they should, at least until client support
 | 
						|
      is widespread.
 | 
						|
      * Users with clients that support refresh tokens will still benefit from the
 | 
						|
        added security; it's not possible to downgrade a session to using long-lived
 | 
						|
        access tokens so this effectively gives users the choice.
 | 
						|
    * In a closed environment where all users use known clients, this may not be
 | 
						|
      an issue as the homeserver administrator can know if the clients have refresh
 | 
						|
      token support. In that case, the non-refreshable access token lifetime
 | 
						|
      may be set to a short duration so that a similar level of security is provided.
 | 
						|
 | 
						|
 | 
						|
## Configuration Guide
 | 
						|
 | 
						|
The following configuration options, in the `registration` section, are related:
 | 
						|
 | 
						|
* `session_lifetime`: maximum length of a session, even if it's refreshed.
 | 
						|
  In other words, the client must log in again after this time period.
 | 
						|
  In most cases, this can be unset (infinite) or set to a long time (years or months).
 | 
						|
* `refreshable_access_token_lifetime`: lifetime of access tokens that are created
 | 
						|
  by clients supporting refresh tokens.
 | 
						|
  This should be short; a good value might be 5 minutes (`5m`).
 | 
						|
* `nonrefreshable_access_token_lifetime`: lifetime of access tokens that are created
 | 
						|
  by clients which don't support refresh tokens.
 | 
						|
  Make this short if you want to effectively force use of refresh tokens.
 | 
						|
  Make this long if you don't want to inconvenience users of clients which don't
 | 
						|
  support refresh tokens (by forcing them to frequently re-authenticate using
 | 
						|
  login credentials).
 | 
						|
* `refresh_token_lifetime`: lifetime of refresh tokens.
 | 
						|
  In other words, the client must refresh within this time period to maintain its session.
 | 
						|
  Unless you want to log inactive sessions out, it is often fine to use a long
 | 
						|
  value here or even leave it unset (infinite).
 | 
						|
  Beware that making it too short will inconvenience clients that do not connect
 | 
						|
  very often, including mobile clients and clients of infrequent users (by making
 | 
						|
  it more difficult for them to refresh in time, which may force them to need to
 | 
						|
  re-authenticate using login credentials).
 | 
						|
 | 
						|
**Note:** All four options above only apply when tokens are created (by logging in or refreshing).
 | 
						|
Changes to these settings do not apply retroactively.
 | 
						|
 | 
						|
 | 
						|
### Using refresh token expiry to log out inactive sessions
 | 
						|
 | 
						|
If you'd like to force sessions to be logged out upon inactivity, you can enable
 | 
						|
refreshable access token expiry and refresh token expiry.
 | 
						|
 | 
						|
This works because a client must refresh at least once within a period of
 | 
						|
`refresh_token_lifetime` in order to maintain valid credentials to access the
 | 
						|
account.
 | 
						|
 | 
						|
(It's suggested that `refresh_token_lifetime` should be longer than
 | 
						|
`refreshable_access_token_lifetime` and this section assumes that to be the case
 | 
						|
for simplicity.)
 | 
						|
 | 
						|
Note: this will only affect sessions using refresh tokens. You may wish to
 | 
						|
set a short `nonrefreshable_access_token_lifetime` to prevent this being bypassed
 | 
						|
by clients that do not support refresh tokens.
 | 
						|
 | 
						|
 | 
						|
#### Choosing values that guarantee permitting some inactivity
 | 
						|
 | 
						|
It may be desirable to permit some short periods of inactivity, for example to
 | 
						|
accommodate brief outages in client connectivity.
 | 
						|
 | 
						|
The following model aims to provide guidance for choosing `refresh_token_lifetime`
 | 
						|
and `refreshable_access_token_lifetime` to satisfy requirements of the form:
 | 
						|
 | 
						|
1. inactivity longer than `L` **MUST** cause the session to be logged out; and
 | 
						|
2. inactivity shorter than `S` **MUST NOT** cause the session to be logged out.
 | 
						|
 | 
						|
This model makes the weakest assumption that all active clients will refresh as
 | 
						|
needed to maintain an active access token, but no sooner.
 | 
						|
*In reality, clients may refresh more often than this model assumes, but the
 | 
						|
above requirements will still hold.*
 | 
						|
 | 
						|
To satisfy the above model,
 | 
						|
* `refresh_token_lifetime` should be set to `L`; and
 | 
						|
* `refreshable_access_token_lifetime` should be set to `L - S`.
 |