Page MenuHomePhabricator

[WE5.5.3 research spike] Understand how rate limiting of applications and users works and where it's enforced
Closed, ResolvedPublic

Description

What layers of the MediaWiki traffic stack involve rate limiting? Do they interact?

Event Timeline

For api.wikimedia.org:

  • The OAuth extension provides an OAuthClaimStoreGetClaims hook for adding claims (essentially, arbitrary fields inside the JWT data structure) to OAuth 2access and refresh tokens.
  • OAuthRateLimiter implements the hook to add fields like "ratelimit": { "requests_per_unit": 5000, "unit": "HOUR" }. This is based on $wgOAuthRateLimiterTierConfig, with the tier coming from the oauth_ratelimit_client_tier table (set via maintenance script). Currently there are 12 clients which are set to a non-default tier via this mechanism.
  • The API gateways is configured to interpret this field as a rate limit (Envoy docs, API gateway docs).

JWT encryption / decryption is handled via $wgOAuth2PublicKey / $wgwgOAuth2PrivateKey in PrivateSettings.php on the MediaWiki side, and the api-gateway deployment chart (via secrets) on the Envoy side. Expiry is managed via $wgOAuth2GrantExpirationInterval in MediaWiki.

In MediaWiki we have two rate limiting systems, User::pingLimiter() / UserAuthority::limit() / RateLimiter and Throttler (see T134953: Merge Throttler and ping limiter).

The first is configured via $wgRateLimits, and is mostly used for throttling actions with a vandalism potential (edits, emails etc) but also some other things like 2FA checks. It is integrated with the permission system (every permission check is also a limit check) but can check custom throttles as well. Users with the noratelimit right can skip most throttles that weren't explicitly configured as unskippable. The outcome of the throttle check can be overridden with the PingLimiter hook. Settings can be inspected via the uiprop=ratelimits API.

The second is used for login/signup only, is configured via $wgPasswordAttemptThrottle (login) / $wgAccountCreationThrottle (signup) / $wgTempAccountCreationThrottle and $wgTempAccountNameAcquisitionThrottle (temp user creation), can be customized by the ExemptFromAccountCreationThrottle hook for signup, and can trigger custom actions via the AuthenticationAttemptThrottled hook.

Both systems use a Memcached backend. RateLimiter uses a leaky bucket algorithm, and Throttler a very simplistic expiring counter.

There is also a limit system for the action API but that only affects the number of items that can be returned in a single request. That is managed via the apihighlimits right and all APIs having a normal and high version of the max limit.

The action API also has some rate limiting that relies entirely on the client being nice (see the maxlag parameter).

Tgr claimed this task.

I think this is done. There's also rate limiting in Varnish but there's a separate task for that.