Skip to content

Commit 9e1df1b

Browse files
committed
rate limit plugin
1 parent 50e5a99 commit 9e1df1b

File tree

4 files changed

+216
-0
lines changed

4 files changed

+216
-0
lines changed

docs/plugins/overview.mdx

+1
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@ Pre-route plugins are executed at the very beginning of request handling, **befo
4343
- [Allowlist](/plugins/allowlist/index.mdx)
4444
- [Caching](/plugins/caching/index.mdx)
4545
- [RESTified Endpoints](/plugins/restified-endpoints/index.mdx)
46+
- [Rate Limiting](/plugins/rate-limit/index.mdx)
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"label": "Rate Limit Plugin",
3+
"position": 7
4+
}

docs/plugins/rate-limit/how-to.mdx

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
---
2+
title: How to Configure the Rate Limit Plugin
3+
sidebar_position: 2
4+
description: "Learn how to configure the Rate Limit Plugin for Hasura DDN."
5+
keywords:
6+
- hasura plugins
7+
- rate limit plugin
8+
- plugins architecture
9+
- engine plugins
10+
- how-to
11+
- guide
12+
---
13+
14+
# How to Configure the Rate Limit Plugin
15+
16+
## Introduction
17+
18+
The [rate limit plugin](https://github.com/hasura/engine-plugin-rate-limit) adds the ability to limit the number of
19+
requests that can be made to DDN in a given time period.
20+
21+
## Setting up for local development
22+
23+
We can set up everything we need for local development through Docker. Add the following entries to your `compose.yaml`
24+
file:
25+
26+
```yaml
27+
redis:
28+
image: redis:latest
29+
ports:
30+
- 6379:6379
31+
32+
rate-limit:
33+
build:
34+
context: https://github.com/hasura/engine-plugin-rate-limit.git
35+
ports:
36+
- "3001:3001"
37+
environment:
38+
- PORT=3001
39+
- DEBUG=rate-limit*
40+
- OTEL_EXPORTER_OTLP_ENDPOINT=https://gateway.otlp.hasura.io:443/v1/traces
41+
- OTEL_EXPORTER_PAT=your-pat-here
42+
- HASURA_DDN_PLUGIN_CONFIG_PATH=plugin_config
43+
depends_on:
44+
redis:
45+
condition: service_healthy
46+
healthcheck:
47+
test: ["CMD", "curl", "-f", "http://localhost:3001/health"]
48+
interval: 30s
49+
timeout: 10s
50+
retries: 3
51+
volumes:
52+
- ./rate_limit_config:/app/plugin_config
53+
```
54+
55+
Here, we've added a Redis instance to our Docker Compose project, as well as an instance of the rate limit plugin. The
56+
rate limit plugin expects a config directory (which we've said here is saved in `./rate_limit_config`, though the path
57+
is up to you). Here's an example config directory:
58+
59+
```
60+
rate_limit_config/
61+
├── configuration.json
62+
└── rate-limit.json
63+
```
64+
65+
The `configuration.json` file is used to configure the plugin, and the `rate-limit.json` file is used to configure the
66+
rate limit.
67+
68+
The `configuration.json` file should look like this:
69+
70+
```json
71+
{
72+
"headers": {
73+
"hasura-m-auth": "your-auth-token"
74+
}
75+
}
76+
```
77+
78+
Please replace `your-auth-token` with a strong, random string.
79+
80+
The `rate-limit.json` file should look like this:
81+
82+
```json
83+
{
84+
"redis_url": "redis://redis:6379",
85+
"rate_limit": {
86+
"default_limit": 10,
87+
"time_window": 60,
88+
"excluded_roles": [],
89+
"key_config": {
90+
"from_headers": [],
91+
"from_session_variables": [],
92+
"from_role": true
93+
},
94+
"unavailable_behavior": {
95+
"fallback_mode": "deny"
96+
},
97+
"role_based_limits": [
98+
{
99+
"role": "user",
100+
"limit": 11
101+
}
102+
]
103+
}
104+
}
105+
```
106+
107+
The rate limiting configuration includes:
108+
109+
- `redis_url`: Redis connection URL
110+
- `rate_limit`: Rate limiting configuration. The rate limiting can be configured using the following parameters:
111+
- `default_limit`: The default rate limit per window
112+
- `time_window`: The time window in seconds
113+
- `excluded_roles`: Roles that are excluded from rate limiting
114+
- `key_config`: Configuration for generating rate limit keys:
115+
- `from_headers`: Headers to include in the rate limit key (if header is not found in the request, it is skipped)
116+
- `from_session_variables`: Session variables to include in the rate limit key (if variable is not found in the
117+
request, it is skipped)
118+
- `from_role`: Whether to include the role in the rate limit key
119+
- `unavailable_behavior`: Behavior when Redis is unavailable
120+
- `role_based_limits`: Role-based rate limits (this takes precedence over the default limit)
121+
122+
## Adding the plugin to your project
123+
124+
Once we've configured the plugin, running `ddn run docker-start` should work happily. Now, we just need to configure
125+
Hasura to use the plugin. Add a new metadata file (say `rate-limit.hml`) to your `globals` subgraph's metadata
126+
directory:
127+
128+
```yaml
129+
kind: LifecyclePluginHook
130+
version: v1
131+
definition:
132+
pre: parse
133+
name: rate-limit
134+
url:
135+
valueFromEnv: RATE_LIMIT_PLUGIN_URL
136+
config:
137+
request:
138+
headers:
139+
additional:
140+
hasura-m-auth:
141+
valueFromEnv: RATE_LIMIT_PLUGIN_AUTH_TOKEN
142+
session: {}
143+
rawRequest:
144+
query: {}
145+
variables: {}
146+
```
147+
148+
:::info Using environment variables
149+
150+
We've used `valueFromEnv` so that we can dynamically and securely add values from our environment variables. You can add
151+
these values to your root-level `.env` and then map them in the `globals` subgraph.yaml file. Alternatively, you can
152+
include raw strings here using `value` instead of `valueFromEnv` and passing the keys.
153+
154+
For local development, `RATE_LIMIT_PLUGIN_URL` should be `http://local.hasura.dev:3001/rate-limit`, and
155+
`RATE_LIMIT_PLUGIN_AUTH_TOKEN` should be the value you set in the `configuration.json` file.
156+
157+
:::
158+
159+
## Running the project
160+
161+
At this point, we can create a build of our project and start local development:
162+
163+
```bash
164+
ddn supergraph build local
165+
ddn run docker-start
166+
```
167+
168+
You can now test the rate limit plugin by making requests to your supergraph. You should see the rate limit plugin
169+
enforce the rate limit you've configured (10 requests per minute for all other roles and 11 requests per minute for the
170+
`user` role).
171+
172+
## Deploying the plugin
173+
174+
The connector can be deployed as a regular HTTP service, anywhere an Express server can be deployed. When deployed, make
175+
sure to set the `RATE_LIMIT_PLUGIN_URL` and `RATE_LIMIT_PLUGIN_AUTH_TOKEN` to appropriate values in `.cloud.env`. Note
176+
that the plugin must be visible from your Hasura deployment: if hosting in the Hasura Cloud, the plugin must be publicly
177+
visible.

docs/plugins/rate-limit/index.mdx

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
title: Rate Limit Plugin
3+
sidebar_position: 1
4+
description: "Learn more about the Rate Limit Plugin for Hasura DDN."
5+
keywords:
6+
- hasura plugins
7+
- rate limit plugin
8+
- plugins architecture
9+
- engine plugins
10+
---
11+
12+
# Rate Limit Plugin
13+
14+
## Introduction
15+
16+
The [Rate Limit Plugin](https://github.com/hasura/engine-plugin-rate-limit) allows you to add rate limiting to your
17+
supergraph, ensuring that the supergraph is not overloaded with requests. This can be useful for preventing abuse or
18+
denial-of-service attacks.
19+
20+
The plugin integrates with Hasura DDN as a **pre-parse plugin**. It uses Redis for keeping track of the number of
21+
requests made to the supergraph.
22+
23+
Key benefits of the rate limit plugin include:
24+
25+
- **Enhanced security:** Prevent abuse or denial-of-service attacks.
26+
- **Flexibility:** Supports dynamic configuration including using roles, headers (can be used for IP-based rate
27+
limiting) and session variables.
28+
- **Integration:** Works as a pre-parse plugin, ensuring easy integration with Hasura DDN.
29+
30+
## Next steps
31+
32+
To get started with configuring and deploying the Rate Limit Plugin, refer to the
33+
[guide](/plugins/rate-limit/how-to.mdx), which walks you through the process of setting up, configuring, and deploying
34+
the plugin.

0 commit comments

Comments
 (0)