...

Text file src/github.com/letsencrypt/boulder/ratelimits/README.md

Documentation: github.com/letsencrypt/boulder/ratelimits

     1# Configuring and Storing Key-Value Rate Limits
     2
     3## Rate Limit Structure
     4
     5All rate limits use a token-bucket model. The metaphor is that each limit is
     6represented by a bucket which holds tokens. Each request removes some number of
     7tokens from the bucket, or is denied if there aren't enough tokens to remove.
     8Over time, new tokens are added to the bucket at a steady rate, until the bucket
     9is full. The _burst_ parameter of a rate limit indicates the maximum capacity of
    10a bucket: how many tokens can it hold before new ones stop being added.
    11Therefore, this also indicates how many requests can be made in a single burst
    12before a full bucket is completely emptied. The _count_ and _period_ parameters
    13indicate the rate at which new tokens are added to a bucket: every period, count
    14tokens will be added. Therefore, these also indicate the steady-state rate at
    15which a client which has exhausted its quota can make requests: one token every
    16(period / count) duration.
    17
    18## Default Limit Settings
    19
    20Each key directly corresponds to a `Name` enumeration as detailed in `//ratelimits/names.go`.
    21The `Name` enum is used to identify the particular limit. The parameters of a
    22default limit are the values that will be used for all buckets that do not have
    23an explicit override (see below).
    24
    25```yaml
    26NewRegistrationsPerIPAddress:
    27  burst: 20
    28  count: 20
    29  period: 1s
    30NewOrdersPerAccount:
    31  burst: 300
    32  count: 300
    33  period: 180m
    34```
    35
    36## Override Limit Settings
    37
    38Each override key represents a specific bucket, consisting of two elements:
    39_name_ and _id_. The name here refers to the Name of the particular limit, while
    40the id is a client identifier. The format of the id is dependent on the limit.
    41For example, the id for 'NewRegistrationsPerIPAddress' is a subscriber IP
    42address, while the id for 'NewOrdersPerAccount' is the subscriber's registration
    43ID.
    44
    45```yaml
    46NewRegistrationsPerIPAddress:10.0.0.2:
    47  burst: 20
    48  count: 40
    49  period: 1s
    50NewOrdersPerAccount:12345678:
    51  burst: 300
    52  count: 600
    53  period: 180m
    54```
    55
    56The above example overrides the default limits for specific subscribers. In both
    57cases the count of requests per period are doubled, but the burst capacity is
    58explicitly configured to match the default rate limit.
    59
    60### Id Formats in Limit Override Settings
    61
    62Id formats vary based on the `Name` enumeration. Below are examples for each
    63format:
    64
    65#### ipAddress
    66
    67A valid IPv4 or IPv6 address.
    68
    69Examples:
    70  - `NewRegistrationsPerIPAddress:10.0.0.1`
    71  - `NewRegistrationsPerIPAddress:2001:0db8:0000:0000:0000:ff00:0042:8329`
    72
    73#### ipv6RangeCIDR
    74
    75A valid IPv6 range in CIDR notation with a /48 mask. A /48 range is typically
    76assigned to a single subscriber.
    77
    78Example: `NewRegistrationsPerIPv6Range:2001:0db8:0000::/48`
    79
    80#### regId
    81
    82The registration ID of the account.
    83
    84Example: `NewOrdersPerAccount:12345678`
    85
    86#### regId:domain
    87
    88A combination of registration ID and domain, formatted 'regId:domain'.
    89
    90Example: `CertificatesPerDomainPerAccount:12345678:example.com`
    91
    92#### regId:fqdnSet
    93
    94A combination of registration ID and a comma-separated list of domain names,
    95formatted 'regId:fqdnSet'.
    96
    97Example: `CertificatesPerFQDNSetPerAccount:12345678:example.com,example.org`
    98
    99## Bucket Key Definitions
   100
   101A bucket key is used to lookup the bucket for a given limit and
   102subscriber. Bucket keys are formatted similarly to the overrides but with a
   103slight difference: the limit Names do not carry the string form of each limit.
   104Instead, they apply the `Name` enum equivalent for every limit.
   105
   106So, instead of:
   107
   108```
   109NewOrdersPerAccount:12345678
   110```
   111
   112The corresponding bucket key for regId 12345678 would look like this:
   113
   114```
   1156:12345678
   116```
   117
   118When loaded from a file, the keys for the default/override limits undergo the
   119same interning process as the aforementioned subscriber bucket keys. This
   120eliminates the need for redundant conversions when fetching each
   121default/override limit.
   122
   123## How Limits are Applied
   124
   125Although rate limit buckets are configured in terms of tokens, we do not
   126actually keep track of the number of tokens in each bucket. Instead, we track
   127the Theoretical Arrival Time (TAT) at which the bucket will be full again. If
   128the TAT is in the past, the bucket is full. If the TAT is in the future, some
   129number of tokens have been spent and the bucket is slowly refilling. If the TAT
   130is far enough in the future (specifically, more than `burst * (period / count)`)
   131in the future), then the bucket is completely empty and requests will be denied.
   132
   133Additional terminology:
   134
   135  - **burst offset** is the duration of time it takes for a bucket to go from
   136    empty to full (`burst * (period / count)`).
   137  - **emission interval** is the interval at which tokens are added to a bucket
   138    (`period / count`). This is also the steady-state rate at which requests can
   139    be made without being denied even once the burst has been exhausted.
   140  - **cost** is the number of tokens removed from a bucket for a single request.
   141  - **cost increment** is the duration of time the TAT is advanced to account
   142    for the cost of the request (`cost * emission interval`).
   143
   144For the purposes of this example, subscribers originating from a specific IPv4
   145address are allowed 20 requests to the newFoo endpoint per second, with a
   146maximum burst of 20 requests at any point-in-time, or:
   147
   148```yaml
   149NewFoosPerIPAddress:172.23.45.22:
   150  burst: 20
   151  count: 20
   152  period: 1s
   153```
   154
   155A subscriber calls the newFoo endpoint for the first time with an IP address of
   156172.23.45.22. Here's what happens:
   157
   1581. The subscriber's IP address is used to generate a bucket key in the form of
   159   'NewFoosPerIPAddress:172.23.45.22'.
   160
   1612. The request is approved and the 'NewFoosPerIPAddress:172.23.45.22' bucket is
   162   initialized with 19 tokens, as 1 token has been removed to account for the
   163   cost of the current request. To accomplish this, the initial TAT is set to
   164   the current time plus the _cost increment_ (which is 1/20th of a second if we
   165   are limiting to 20 requests per second).
   166
   1673. Bucket 'NewFoosPerIPAddress:172.23.45.22':
   168    - will reset to full in 50ms (1/20th of a second),
   169    - will allow another newFoo request immediately,
   170    - will allow between 1 and 19 more requests in the next 50ms,
   171    - will reject the 20th request made in the next 50ms,
   172    - and will allow 1 request every 50ms, indefinitely.
   173
   174The subscriber makes another request 5ms later:
   175
   1764. The TAT at bucket key 'NewFoosPerIPAddress:172.23.45.22' is compared against
   177   the current time and the _burst offset_. The current time is greater than the
   178   TAT minus the cost increment. Therefore, the request is approved.
   179
   1805. The TAT at bucket key 'NewFoosPerIPAddress:172.23.45.22' is advanced by the
   181   cost increment to account for the cost of the request.
   182
   183The subscriber makes a total of 18 requests over the next 44ms:
   184
   1856. The current time is less than the TAT at bucket key
   186   'NewFoosPerIPAddress:172.23.45.22' minus the burst offset, thus the request
   187   is rejected.
   188
   189This mechanism allows for bursts of traffic but also ensures that the average
   190rate of requests stays within the prescribed limits over time.

View as plain text