Rate Limiting Policy Files

Configure rate limiting with a policy file.

The policy file consists of four key portions.

The first portion is matching criteria. If a request matches the criteria the rest of the policy is applied. The two parts of matching criteria are HTTP method and the request URL. The URL pattern supports wild cards. The HTTP method is a list of methods to match on, or the value of "*" to indicate that all HTTP methods must match. A single rate limiting policy can contain multiple matching criteria. For example, multiple URLs and methods. Each matching criteria will correspond to a single rate limiting bucket. In other words, the access rate for each matching criteria is treated separately.

All matching on URL and method is case insensitive.

An example of limiting attempts to log into the reverse proxy with the login form is: 

resources:
  - url: /pkmslogin.form
    method:
      - POST
method: POST If you want to match this configuration to every request the following can be specified:

resources:
  - url: "*"
    method: "*"
An example to match all POST and GET requests regardless of URL:

resources:
  - url: "*"
    method:
      - GET
      - POST
An example to apply this policy to all requests to a given application path:

resources:
  - url: "/jct_a"
    method: "*"

Once a request is matched, the configured values of cookies, headers, query string parameters, client IP, and credential attributes are included.

These criteria support wild cards for the value. When a match occurs the matched value is used to identify the request not the pattern. All matching is case insensitive.

When these values are matched and the request does not contain a specified header, cookie, query string parameter, or credential attribute, the request is not rate limited.

An example of limiting incoming requests based on the Basic Authentication credentials:

header:
   Authorization: "Basic *"
An example to limit bearer token usage

header:
   Authorization: "Bearer *"
An example of limiting a session involves rate limiting on the PD-S-SESSION-ID cookie:

cookie:
   PD-S-SESSION-ID: "*"
An example of including a query string. For a request like /junction?resource=123, limit with:

query:
   resource: 123
An example of limiting any resource:

query:
   resource: "*"
An example of limiting on a credential attribute, to limit access of users based on username:

credential:
   AZN_CRED_PRINCIPAL_NAME: "*"
An example of limiting access is to limit based on an OAuth client ID when you are using OAuth. See OAuth Authentication

credential:
    oauth_token_client_id: "*"
There's a true and false flag to set to include the client IP in the request:

ip: true

The matching information identified from the request, such as URL, Method, IP, cookies, headers, and query parameters are then built into a consistent lookup key.

A counter is kept for this value. This counter has two properties, the maximum value and how often the count is set down to zero. These values are controlled by two configuration properties; a capacity which indicates the number of requests that are allowed until rate limiting occurs and an interval which is the number of seconds that must pass until the capacity is reset.

To allow 100 requests per minute, set the following:

capacity: 100
interval: 60

The length of time that matching requests are locked out, after the capacity is exceeded, can be set by using the lockout-time configuration entry. If the lockout-time configuration entry is not specified the capacity is not reset until the current interval has elapsed.

To allow 100 requests per minute, with a lock-out time of 30 seconds, set the following:
capacity: 100
interval: 60
lockout-time: 30
The final part of the configuration is the reaction method. There are four ways to react:
CLOSE
Closes the connection without any information written to the client.
TEMPLATE
Writing back the rate limiting template with the status code 429.
IGNORE
No action is taken, except the logging of the reaction if logging has been enabled.
Specify URL
A URL can be specified. This URL rewrites the request URL to the defined value. This is used to route a rate limited request to a dummy resource. This allows the concept of hosting a dummy resource which appears to produce the same functionality as the actual resource, only never actually making any change. The intent of this is to mislead a malicious client into thinking they are performing numerous operations while actually not having any negative impact. This can also be used to log a user out. For example, you can direct them to /pkmslogout to terminate their session.
Note: Providing a reaction configuration is optional, if nothing is specified TEMPLATE behavior is the default.
Close the connection with:
reaction: CLOSE
Return the template with configured with:
reaction: TEMPLATE
Rewrite the URL with:
reaction: /dummy-login
Rate limiting policy files support comments by including a leading # character. Here is a full and commented policy file for rate limiting bearer token usage per client IP to 10 times / second:

resources:
  - url: "*"
    method:
      - "*"

# Limit based on the authorization header, with a leading "Bearer " prefix:
header: 
  Authorization: "Bearer *"

# Tokens can be used 10 times in a second.  If this number is exceeded
# matching requests will be locked out for 5 seconds. 
capacity: 10
interval: 1
lockout-time: 5

# Include the IP of the client
ip: true

# Return the template if a client is rate-limited.
reaction: TEMPLATE
When performing rate limiting with a reverse proxy, some information about the number of requests made for a client and policy must be stored. This information is stored in a cache which has a size limit. When this limit is exceeded the oldest entry is ejected. It is important to ensure that you set the configuration entry max-ratelimiting-buckets in the [server] stanza to a suitably high number so a malicious client cannot saturate the cache. For example, a base rate limiting policy on all URLs, methods and IP as a matching criteria can be used to ensure a user is rate limited before they can saturate the cache.
Note: When you are using shared rate limiting, max-ratelimiting-buckets only applies to the in-memory cache. WebSEAL does not enforce a limit on the number of entries created on the Redis server.