Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: #23. Cap conveyed throughput. See #19. #34

Merged
merged 11 commits into from May 4, 2021
49 changes: 48 additions & 1 deletion draft-ietf-httpapi-ratelimit-headers.md
Expand Up @@ -259,6 +259,10 @@ An example policy of 100 quota-units per minute.
100;w=60
~~~

The definition of a quota-policy does not imply any specific
distribution of quota-units over time.
Such service specific details can be conveyed in the `quota-comments`.

Two examples of providing further details via custom parameters
in `quota-comments`.

Expand Down Expand Up @@ -405,6 +409,12 @@ When using a policy involving more than one `time-window`,
the server MUST reply with the `RateLimit` fields related to the window
with the lower `RateLimit-Remaining` values.

A service returning `RateLimit` fields MUST NOT convey values
exposing an unwanted volume of requests
and SHOULD implement mechanisms to cap the ratio between `RateLimit-Remaining`
and `RateLimit-Reset` (see {{sec-resource-exhaustion}});
this is especially important when quota-policies use a large `time-window`.

Under certain conditions, a server MAY artificially lower `RateLimit` field values between subsequent requests,
eg. to respond to Denial of Service attacks or in case of resource saturation.

Expand Down Expand Up @@ -935,7 +945,33 @@ and your server returns the `RateLimit-Reset` accordingly

there's a high probability that all clients will show up at `18:00:00`.

This could be mitigated adding some jitter to the field-value.
This could be mitigated by adding some jitter to the field-value.

Resource exhaustion issues can be associated with quota policies
using a large `time-window`, because a user agent by chance or purpose might
consume most of its quota-units in a significantly shorter interval.

This behavior can be even triggered by the provided `RateLimit` fields.
The following example describes a service
with an unconsumed quota-policy of 10000 quota-units per 1000 seconds.

~~~ example
RateLimit-Limit: 10000, 10000;w=1000
RateLimit-Remaining: 10000
RateLimit-Reset: 10
~~~

A client implementing a simple ratio between `RateLimit-Remaining` and
`RateLimit-Reset` could infer an average throughput of
1000 quota-units per second,
while `RateLimit-Limit` conveys a quota-policy
with an average of 10 quota-units per second.
If the service cannot handle such load, it should return
either a lower `RateLimit-Remaining` value
or an higher `RateLimit-Reset` value.
ioggstream marked this conversation as resolved.
Show resolved Hide resolved
Moreover, complementing large `time-window` quota-policies with
a short `time-window` one mitigates those risks.


## Denial of Service

Expand Down Expand Up @@ -1138,6 +1174,17 @@ RateLimit-Limit: 100, 100;w=60;burst=1000;comment="sliding window", 5000;w=3600;
or when they are an active component of the service.
In those case we will consider them as part of the originating infrastructure.

14. Why the `w` parameter is just informative?
Could it be used by a client to determine the request rate?

A non-informative `w` parameter might be fine in an environment
where clients and servers are tightly coupled. Conveying policies
with this detail on a large scale would be very complex and implementations
would be likely not interoperable. We thus decided to leave `w` as
an informational parameter and only rely on `RateLimit-Limit`,
`RateLimit-Remaining` and `RateLimit-Reset` for defining the throttling
behavior.
Comment on lines +1183 to +1186
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In connection with the above changes, we might want to have another informational parameter r to convey an expected maximum rate in quota units.

The problem might then arise from not really knowing how many units requests consume until you have performed a few of them. Providing a hint based on the current request might also require another parameter, say u. The following example might convey the rate to be 25 requests like this one in terms of quota-unit cost per second:

~~~ example
RateLimit-Limit: 10000, 10000;w=1000,r=250,u=10
RateLimit-Remaining: 10000
RateLimit-Reset: 10
~~~

The benefit of doing this is that the client might have better information about the effective maximum rate before performing more requests and actually forcing the service to modify the returned values.

The bad thing is that we make it a bit more complex and add more standardized informational (but optional) parameters when we have tried to leave this area more or less pristine to allow future drafts to expand on.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could exposing a maximum rate make things more complex without gains?

  1. it is hard to enforce since it is conveyed in the informative part of the fields;
  2. clients might be tempted to consider that value "the real limit";

Since parameters are always allowed in Limit we could define a "registry" and add them subsequently as soon as implementers needs them.

Copy link
Collaborator Author

@ioggstream ioggstream Mar 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see the latest proposal https://github.com/ietf-wg-httpapi/ratelimit-headers/pull/34/files#diff-d26a6f407efe0e4913cbcf7bf0e2a164bee5edea8bf2fdc4aa97a7ceb3acc03cR950

I moved normative language outside security considerations too

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More complex for sure, but more information is conveyed at once, and the server can always fall back to changing the values to force clients who don't understand these informational parameters to lower their rates.

Agree on having some place or section in the document to track these parameters, even if we just populate it with w, so any extensions can refer to and expand to it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@unleashed filed #49 Limit parameter registry


# RateLimit fields currently used on the web
{:numbered="false"}

Expand Down