Global rule
Global rules run their plugins on every request the engine handles.
global_ruleWhat a global rule is
A global rule holds plugins that run on every request the gateway of the environment handles: on every route, whatever plugins the route carries itself, and on a request that no route takes.
Put on it what every request needs, for example real-ip behind your load balancers and one limit-count for each client. A plugin that refuses requests refuses them here on every route at once, routes meant to stay open included.
When its plugins run
The gateway picks the route first, by its matching rules. It then works through the request in phases, as How G8 handles a request explains, and in each phase the plugins of the global rules run before the route's own:
- the route is matched before any of them, so its Client addresses still see your load balancer's address, real-ip on a global rule or not;
- key-auth and real-ip on a global rule act before any plugin of the route: with real-ip here, the plugins of every route see each client's own address;
- limit-count acts in a later phase than key-auth: on a global rule it counts once the route's key-auth has named the consumer, so a global limit-count with Key
consumer_namecounts each consumer apart; - a limit-count that the route carries itself does not replace the global one: both count each request.
No global rule runs on a stream route.
When to use it
- Your gateway nodes sit behind load balancers, and the plugins of every route should see each client's own address: real-ip once, on a global rule.
- Every client should get one limit over all routes, for example 1000 requests a minute, whatever route it calls.
- Every consumer should get the same limit over every route that asks for its key, each counted apart.
- Every request of the environment should be recorded, with kafka-logger for example, the requests no route takes included.
Not for plugins that only the routes of one backend need, for example one limit they share — see Service (Services hold the upstream and plugins that several routes share), plugins that several routes share while each keeps instances of its own — see Plugin config (Plugin configs hold a set of plugins that several routes reference) or a limit or another plugin for one client alone — see Consumer (Consumers identify the callers of your APIs; their credentials live under each consumer).
Guides
Pages that walk through a job with a global rule, step by step.
- Apply a plugin to every requestPut a plugin on a global rule so it runs on every request of the environment.
Set it up
Give each client 1000 requests a minute on every route, behind your load balancers
real-ip takes each client's address from X-Forwarded-For, believed from your load balancers only, and limit-count counts every request of the environment under that address; real-ip acts before limit-count counts, whatever the order you add them in.
Under General set ID to rate-limit-every-route. Once it is created, open its Plugins tab and add real-ip and limit-count, each with its settings from the JSON below.
{
"id": "rate-limit-every-route",
"plugins": {
"real-ip": {
"source": "http_x_forwarded_for",
"trusted_addresses": [
"10.0.0.21",
"10.0.0.22"
]
},
"limit-count": {
"count": 1000,
"time_window": 60,
"key": "remote_addr",
"rejected_code": 429
}
}
}
What you will see
- The requests of every route are counted for each client, on a route with no plugins of its own as well: its answer carries
X-RateLimit-Limit: 1000. - Each client behind your load balancers has a count of its own: the first request of a second client also arrives with
X-RateLimit-Remaining: 999. - A request that no route takes is counted as well, and is still answered
404. - A route with a limit-count of its own keeps it, and that copy also counts each client by its own address. Its answers show the route's numbers,
X-RateLimit-Limit: 100for example, while each of those requests is still taken from the client's 1000. - The route itself is matched before any plugin runs, the global rule's included: with Client addresses that leave
203.0.113.8out, its request still reaches the route through your load balancer, and your backend receivesX-Real-IP: 203.0.113.8.
More scenarios
Ask for an API key on every route of the environment
Every route asks for the key from the moment key-auth is added here, routes meant to stay open included: give every client its consumer and key first, and take key-auth off the routes that carry their own.
Under General set ID to key-on-every-route. Once it is created, open its Plugins tab and add key-auth with its settings from the JSON below.
{
"id": "key-on-every-route",
"plugins": {
"key-auth": {
"header": "x-api-key",
"hide_credentials": true
}
}
}
What you will see
- A route with no plugins of its own answers
401with{"message":"Missing API key in request"}to a request without the key. - With the key of
mobile-appthe request passes, and your backend receivesX-Consumer-Username: mobile-app. - A request that no route takes is answered
401as well, instead of404 Route Not Found, unless it carries a valid key. - A route that still carries key-auth of its own answers
401even to a valid key: the global copy runs first and, with Hide credentials on, takes the key away before the route's copy looks for it.
Give each consumer 1000 requests a minute over every route that asks for its key
key-auth on the route names the consumer before a global rule's limit-count counts, so Key consumer_name gives each consumer a count of its own.
Under General set ID to each-consumer-on-every-route. Once it is created, open its Plugins tab and add limit-count with its settings from the JSON below.
{
"id": "each-consumer-on-every-route",
"plugins": {
"limit-count": {
"count": 1000,
"time_window": 60,
"key": "consumer_name",
"rejected_code": 429
}
}
}
What you will see
- Each consumer is counted under its own name on every route that asks for its key: once one consumer has used its count it is answered
429, while another consumer still passes on a count of its own. - A consumer's own limit-count does not replace the global one: a consumer whose own limit is higher is still answered
429once its global count is used.
Things to know
- Plugins — A plugin that refuses requests refuses them on every route the moment it is added. key-auth on a global rule answers
401to every request without a key, on routes meant to stay open as well. A request that no route takes is answered401too, instead of404 Route Not Found. - Plugins — key-auth on a global rule reads the key before a route's own key-auth does: with Hide credentials on, it takes the key away first, and every route that carries key-auth of its own answers
401even to a valid key. - Plugins — A route's key-auth names the consumer before a global limit-count counts, so a global limit-count with Key
consumer_namegives each consumer a count of its own over every route that asks for its key. - Plugins — A route's own limit-count does not replace the global one: both count each request, the route's answers show the route's numbers, and each of its requests is still taken from the client's global count.
- Plugins — A consumer's own limit-count does not replace the global one either: a consumer with a higher limit of its own is still refused with
429once it has used its global count. - The route is matched before any plugin runs, a global rule's included: with real-ip on a global rule, a route's Client addresses still see the load balancer's address.
- Plugins — A plugin can be in one global rule at a time: the picker greys out a plugin that another global rule carries, and you change it in that rule.
- Plugins — The prometheus plugin of a global rule steps aside on a route that runs its own copy.
- A plugin's Filter, among its execution settings, makes it run only on the requests where all of its conditions hold.
- Each gateway node keeps the count of a limit-count on its own unless its Policy points at Redis, so with two nodes a client can get up to 1000 on each.
- Deleting a global rule takes its plugins off every route at once.
- Analytics shows request counts only while a global rule runs the prometheus plugin or a route carries its own copy: leave the rule that runs it in place.
- AdviceTreat every plugin you add here as a change to every route at once: add one that can refuse requests only once every client of every route can pass it.
Settings
The fields as the console shows them, section by section.
General
idstring or integerRequiredLetters, digits, dots, hyphens and underscores, up to 64 characters. The ID cannot be changed later.
pattern
^[a-zA-Z0-9-_.]+$Plugins
Plugins on this global rule are managed in the Plugins tab once the global rule exists. They run on every route in the environment, before the route's own plugins of the same phase.
pluginsobjectRequiredThe plugins of this global rule, keyed by plugin name. The engine runs them by their priority, not by the order they are written in.