Rate Limiting

Conduit rate-limits security/privacy sensitive and resource intensive endpoints, to protect against things like:

  • Denial of service attacks, caused by things like overloading the media store
  • Abuse by spammers, attempting to make use of your server to send spam in mass, which usually leads to your server being put in policy lists, making it unable to participate in many rooms.

Note: The easiest way to prevent this is to disable public registration, and use a strong registration token to allow selective registration.

  • Brute-force attacks to guess user's password or the servers registration token, the former leading to potential impersination, as well as denial of service if an admin account is accessed.

Presets

By default, Conduit uses the rate-limiting preset private_small, but there are more available if this isn't the type of server you're planning on running:

  • private_small: The default preset, designed for small private servers (i.e. single-user or for family and friends).
  • private_medium: Designed for medium-sized private servers (e.g. for an entire school class or year-group).
  • public_medium: For medium-sized public servers (i.e. you intend 20-100 users to actively use it).
  • public_large: For larger public server (i.e. you intend 200-1000 users to actively use it).

Here is an example configuration using the private_medium preset:

[global.rate_limiting]
preset = "private_medium"

Overrides

Despite the variety of presets available, you may find the presets to be too restrictive and/or liberal. You can override all the preset configurations directly in the configuration, and if you think your overrides should be part of the preset, you can contribute and change them!

The overrides are split into client and federation sections, for limits that apply to the client and federation APIs respectively, which are both then split into target and global sections, which apply to singular targets or to all of them respectively.

Rate-limiting is implemented as a leaky bucket algorithm, where there is a burst-capacity for each restriction, which is filled when requests are made, and emptied over time at a speed determined by the timeframe. The format is as follows:

# The burst capacity, like the timeframe, either being the number of requests
# for request restrictions, or number of bytes for media restrictions.
burst_capacity = <integer for requests/byte-size for media>
# The timeframe, with either seconds, minutes, hours, or days.
per_<second/minute/hour/day> = <integer for requests/byte-size for media>

When overriding a restriction, both the timeframe and burst capacity must be specified.

Targets

A target is any client that call's Conduit's API endpoints, and are identified by one of the following:

  • A user ID
  • A Server Name (domain)
  • An appservice ID
  • An IP address, if it cannot be addressed by any of the above (i.e. the client is not authenticated)

The rate limiting configurations under both target parts allow you to configure how many resources/requests each unique client can access within the configured timeframe. For example, while on a small server you might allow for all logged-in users to send out 100 invites per day between them, you can set a cap of 5 for each individual user, not only so that they can't use up the entire global cap, but also prevent potential spam from being spread by that user alone.

Request restrictions

Request restrictions are one-to-many mappings to endpoints that have potential for abuse. Like the overrides mentioned above, they are split into client and federation restrictions.

The configuration format is as follows:

[global.rate_limiting.<client/federation>.<global/target>.<restriction>]
per_<second/minute/hour/day> = <number of requests>
burst_capacity = <number of requests>

# Examples:
[global.rate_limiting.client.target.registration]
per_hour = 1
burst_capacity = 4

[global.rate_limiting.federation.target.invite]
burst_capacity = 15
per_minute = 2

[global.rate_limiting.client.global.media_download]
per_second = 1
burst_capacity = 50

Each possible request <restriction> is listed below:

Client

Applies for endpoints on the client-server API, which are used by clients, appservices, and bots. Appservices can bypass rate-limiting though if rate_limited is set to false in their registration file.

registration

For registering a new user account. May be called multiples times for a single registration if there are extra steps, e.g. providing a registration token.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small10 requests per day20 requests3 requests per day10 requests
private_medium20 requests per day20 requests3 requests per day10 requests
public_medium5 requests per hour20 requests3 requests per day10 requests
public_large4 requests per minute25 requests3 requests per day10 requests
login

For logging into an existing account.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small10 requests per hour10 requests5 requests per day20 requests
private_medium25 requests per hour15 requests5 requests per day20 requests
public_medium25 requests per hour15 requests5 requests per day20 requests
public_large10 requests per minute25 requests5 requests per day20 requests
registration_token_validity

For checking whether a given registration token would allow the user to register an account.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small10 requests per day20 requests10 requests per day20 requests
private_medium20 requests per day20 requests10 requests per day20 requests
public_medium1 requests per day1 requests10 requests per day20 requests
public_large1 requests per day1 requests10 requests per day20 requests
send_event

For sending an event to a room.

Note that this is not used for state events, but for users who are unprivliged in a room, the only state event they'll be able to send are ones to update their room profile.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small2 requests per second100 requests15 requests per minute60 requests
private_medium10 requests per second100 requests15 requests per minute60 requests
public_medium10 requests per second100 requests15 requests per minute60 requests
public_large100 requests per second50 requests15 requests per minute60 requests
join

For joining a room.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small1 requests per minute30 requests5 requests per hour30 requests
private_medium5 requests per minute30 requests5 requests per hour30 requests
public_medium5 requests per minute30 requests5 requests per hour30 requests
public_large1 requests per second20 requests5 requests per hour30 requests
invite

For inviting a user to a room.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small10 requests per hour20 requests2 requests per hour20 requests
private_medium1 requests per minute20 requests2 requests per hour20 requests
public_medium1 requests per minute20 requests2 requests per hour20 requests
public_large10 requests per minute40 requests2 requests per hour20 requests
knock

For knocking on a room.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small1 requests per minute30 requests5 requests per hour30 requests
private_medium5 requests per minute30 requests5 requests per hour30 requests
public_medium5 requests per minute30 requests5 requests per hour30 requests
public_large1 requests per second20 requests5 requests per hour30 requests
send_report

For reporting a user, event, or room.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small1 requests per hour25 requests5 requests per day20 requests
private_medium10 requests per hour25 requests5 requests per day20 requests
public_medium10 requests per hour25 requests5 requests per day20 requests
public_large5 requests per minute25 requests5 requests per day20 requests
create_alias

For adding an alias to a room.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small5 requests per hour20 requests2 requests per day20 requests
private_medium1 requests per minute50 requests2 requests per day20 requests
public_medium1 requests per minute50 requests2 requests per day20 requests
public_large30 requests per minute20 requests2 requests per day20 requests
media_download

For downloading a media file.

For rate-limiting based on the size of files downloaded, see the media rate-limiting configuration.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small5 requests per minute150 requests30 requests per hour100 requests
private_medium1 requests per second200 requests30 requests per hour100 requests
public_medium1 requests per second200 requests30 requests per hour100 requests
public_large25 requests per second200 requests30 requests per hour100 requests
media_create

For uploading a media file.

For rate-limiting based on the size of files uploaded, see the media rate-limiting configuration.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small20 requests per minute50 requests4 requests per minute20 requests
private_medium2 requests per second20 requests4 requests per minute20 requests
public_medium2 requests per second20 requests4 requests per minute20 requests
public_large10 requests per second30 requests4 requests per minute20 requests
authentication_failures

This request restriction is a bit different from the previous ones. This one only starts to have it's capacity used if authenticated requests are made with an invalid authentictation token.

This may happen non-maliciously, e.g. when a device is logged out. But a bad actor can keep making requests with random values as the authentication tokens until one of them are found to be valid. This restriction prevents that by preventing all authenticated (client) requests while this limit is exceeded.

Because of this, this restriction cannot be applied globally, only per-target, because an exceeded global limit would prevent all global requests, which can be exploited.

Defaults:
PresetTarget TimeframeTarget Burst Capacity
private_small1 requests per hour20 requests
private_medium10 requests per hour20 requests
public_medium10 requests per hour20 requests
public_large1 requests per minute20 requests

Federation

Applies for endpoints on the federation API of this server, hence restricting how many times other servers can use these endpoints on this server in a given timeframe.

join

For joining a room.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small10 requests per minute10 requests10 requests per hour10 requests
private_medium25 requests per minute25 requests30 requests per hour10 requests
public_medium25 requests per minute25 requests30 requests per hour10 requests
public_large1 requests per second50 requests90 requests per hour30 requests
knock

For knocking on a room.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small10 requests per minute10 requests10 requests per hour10 requests
private_medium25 requests per minute25 requests30 requests per hour10 requests
public_medium25 requests per minute25 requests30 requests per hour10 requests
public_large1 requests per second50 requests90 requests per hour30 requests
invite

For inviting a local user to a room.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small10 requests per minute10 requests10 requests per hour10 requests
private_medium25 requests per minute25 requests30 requests per hour10 requests
public_medium25 requests per minute25 requests30 requests per hour10 requests
public_large1 requests per second50 requests90 requests per hour30 requests
media_download

For downloading media.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small10 requests per second250 requests10 requests per minute50 requests
private_medium10 requests per second100 requests100 requests per minute50 requests
public_medium10 requests per second100 requests100 requests per minute50 requests
public_large50 requests per second100 requests100 requests per minute50 requests

Media Restrictions

Media restrictions are used to limit resources used by the media endpoints, by controlling how many bytes can be used in a given timeframe for certain media actions.

Restriction limits are applied such that media requests are allowed if they are below the limit at the time of making the request. Once any restrictions are beyond the permitted limit, media requests of that type will be rejected until the restriction is below the limit again.

The configuration format is as follows:

[global.rate_limiting.<client/federation>.<global/target>.media.<restriction>]
per_<second/minute/hour/day> = <number of bytes>
burst_capacity = <number of bytes>

# Examples:
[global.rate_limiting.client.target.media.upload]
per_day = "150MB"
burst_capacity = "0.5GB"

[global.rate_limiting.federation.global.media.download]
burst_capacity = "5GB"
per_hour = "15GB"

[global.rate_limiting.client.global.media.fetch]
per_minute = "8000B"
burst_capacity = "250MB"

The format for both fields is specified by ByteSize (e.g. "10000MB", "15GiB", "1.5TB", etc.)

Client

download

This restriction is applied whenever a client downloads media from the server.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small250.0 MB per minute100.0 MB100.0 MB per minute50.0 MB
private_medium500.0 MB per minute200.0 MB100.0 MB per minute50.0 MB
public_medium500.0 MB per minute200.0 MB100.0 MB per minute50.0 MB
public_large2.0 GB per minute500.0 MB100.0 MB per minute50.0 MB
upload

This restriction is applied whenever a client uploads media to the server.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small50.0 MB per minute100.0 MB10.0 MB per minute100.0 MB
private_medium100.0 MB per minute200.0 MB10.0 MB per minute100.0 MB
public_medium100.0 MB per minute200.0 MB10.0 MB per minute100.0 MB
public_large500.0 MB per minute500.0 MB10.0 MB per minute100.0 MB
fetch

In addition to the download, the fetch restriction is also applied when the media that a client has downloaded was had to be fetched from a remote server, due to it not already being stored.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small250.0 MB per minute100.0 MB100.0 MB per minute50.0 MB
private_medium500.0 MB per minute200.0 MB100.0 MB per minute50.0 MB
public_medium500.0 MB per minute200.0 MB100.0 MB per minute50.0 MB
public_large2.0 GB per minute500.0 MB100.0 MB per minute50.0 MB

Federation

download

This restriction is applied whenever a remote server downloads media from this server.

Defaults:
PresetGlobal TimeframeGlobal Burst CapacityTarget TimeframeTarget Burst Capacity
private_small250.0 MB per minute250.0 MB100.0 MB per minute100.0 MB
private_medium500.0 MB per minute500.0 MB200.0 MB per minute200.0 MB
public_medium500.0 MB per minute500.0 MB200.0 MB per minute200.0 MB
public_large2.0 GB per minute1.0 GB600.0 MB per minute300.0 MB