Set up rate limits for APIs
Before you begin
Complete the guide to set up credential management for APIs by using API keys or an OAuth client.
Step 1: Set up a default rate limit for an API
You can enforce basic rate limits for an API that automatically applies to all subscriptions to that API. The following example walks you through how to set up a default rate limit for the tracks API.
Create a RateLimitConfig to limit requests to 5 per minute.
kubectl apply -f- <<EOF apiVersion: ratelimit.solo.io/v1alpha1 kind: RateLimitConfig metadata: name: tracks-rl namespace: gloo-system spec: raw: setDescriptors: - simpleDescriptors: - key: generic_key value: counter rateLimit: requestsPerUnit: 5 unit: MINUTE rateLimits: - setActions: - genericKey: descriptorValue: counter EOF
Add the RateLimitConfig to the same RouteOption resource that you used when you set up credential management for an API.
kubectl apply -f- <<EOF apiVersion: gateway.solo.io/v1 kind: RouteOption metadata: name: tracks namespace: gloo-system spec: options: extauth: configRef: name: tracks-auth namespace: gloo-system rateLimitConfigs: refs: - name: tracks-rl namespace: gloo-system cors: allowCredentials: true allowHeaders: - "*" allowMethods: - GET allowOriginRegex: - ".*" EOF
Verify that the rate limit is applied. For example, Portal users can follow the steps in Test API access to send multiple requests to the tracks API via the frontend app. If you have a valid API key or ID token, you can also use the following curl requests. Verify that you are rate limited after 5 successful requests and that a 429 HTTP response code is returned.
- API key:
for i in {1..6}; do curl -I https://tracks.example.com/tracks -H "api-key: <apikey>"; done
- ID token:
for i in {1..6}; do curl -vik https://tracks.example.com/tracks -H "Authorization: Bearer <id_token>"; done
Example output:
HTTP/2 200 x-powered-by: tinyhttp access-control-allow-origin: * access-control-allow-methods: GET, HEAD, PUT, PATCH, POST, DELETE access-control-allow-headers: content-type content-type: text/html; charset=utf-8 etag: W/"627-v25siNUZqtFMwVFrEcJ5PHKH9xk" date: Thu, 12 Dec 2024 16:25:53 GMT x-envoy-upstream-service-time: 3 server: envoy HTTP/2 200 x-powered-by: tinyhttp access-control-allow-origin: * access-control-allow-methods: GET, HEAD, PUT, PATCH, POST, DELETE access-control-allow-headers: content-type content-type: text/html; charset=utf-8 etag: W/"627-v25siNUZqtFMwVFrEcJ5PHKH9xk" date: Thu, 12 Dec 2024 16:25:54 GMT x-envoy-upstream-service-time: 2 server: envoy HTTP/2 200 x-powered-by: tinyhttp access-control-allow-origin: * access-control-allow-methods: GET, HEAD, PUT, PATCH, POST, DELETE access-control-allow-headers: content-type content-type: text/html; charset=utf-8 etag: W/"627-v25siNUZqtFMwVFrEcJ5PHKH9xk" date: Thu, 12 Dec 2024 16:25:54 GMT x-envoy-upstream-service-time: 1 server: envoy HTTP/2 200 x-powered-by: tinyhttp access-control-allow-origin: * access-control-allow-methods: GET, HEAD, PUT, PATCH, POST, DELETE access-control-allow-headers: content-type content-type: text/html; charset=utf-8 etag: W/"627-v25siNUZqtFMwVFrEcJ5PHKH9xk" date: Thu, 12 Dec 2024 16:25:54 GMT x-envoy-upstream-service-time: 1 server: envoy HTTP/2 200 x-powered-by: tinyhttp access-control-allow-origin: * access-control-allow-methods: GET, HEAD, PUT, PATCH, POST, DELETE access-control-allow-headers: content-type content-type: text/html; charset=utf-8 etag: W/"627-v25siNUZqtFMwVFrEcJ5PHKH9xk" date: Thu, 12 Dec 2024 16:25:54 GMT x-envoy-upstream-service-time: 2 server: envoy HTTP/2 429 x-envoy-ratelimited: true date: Thu, 12 Dec 2024 16:25:54 GMT server: envoy
Step 2: Allow overwriting default rate limits via the frontend app
You might want to customize the rate limiting settings for a particular team or app and not use the default rate limiting settings that you applied earlier. With Gloo Portal, you can use the dynamicMetadata
feature in a RateLimitConfig to overwrite any default rate limits with the limits that were configured via the Portal frontend app for a particular API subscription. If no custom rate limit exists for an API subscription, the default rate limits are still enforced.
Update the RateLimitConfig that you created earlier to add the
dynamicMetadata
feature. In this example, you instruct Gloo Portal to overwrite the default rate limit settings with the settings for a particular API subscription. For Gloo Portal to identify an API subscription, you must add a key that maps to the name of theportalAuth
spec in the AuthConfig that you used when you set up credential management for the API. This way, Portal automatically handles all the dynamic metadata that is required to enforce rate limiting for a particular API subscription.kubectl apply -f- <<EOF apiVersion: ratelimit.solo.io/v1alpha1 kind: RateLimitConfig metadata: name: tracks-rl namespace: gloo-system spec: raw: setDescriptors: - simpleDescriptors: - key: generic_key value: counter rateLimit: requestsPerUnit: 5 unit: MINUTE rateLimits: - setActions: - genericKey: descriptorValue: counter limit: dynamicMetadata: metadataKey: key: "envoy.filters.http.ext_authz" path: - key: "tracksAuth" - key: "rateLimit" EOF
Log in to the portal frontend app by using an admin user.
In the frontend app, go to Subscriptions and find the subscription for which you want to rate limit requests.
Click Edit Rate Limit.
Select the number of requests that you want to allow in the Requests Per Unit field and the Unit. For example, you might want to allow a maximum of 5 requests per minute.
Click Save to save your settings.
Verify that the rate limit is applied. For example, Portal users can follow the steps in Test API access to send multiple requests to the tracks API via the frontend app. If you have a valid API key or ID token, you can also use the following curl requests. Verify that you are rate limited after 2 successful requests and that a 429 HTTP response code is returned.
- API key:
for i in {1..3}; do curl -I https://tracks.example.com/tracks -H "api-key: <apikey>"; done
- ID token:
for i in {1..3}; do curl -vik https://tracks.example.com/tracks -H "Authorization: Bearer <id_token>"; done
Example output:
HTTP/2 200 x-powered-by: tinyhttp access-control-allow-origin: * access-control-allow-methods: GET, HEAD, PUT, PATCH, POST, DELETE access-control-allow-headers: content-type content-type: text/html; charset=utf-8 etag: W/"627-v25siNUZqtFMwVFrEcJ5PHKH9xk" date: Thu, 12 Dec 2024 16:30:39 GMT x-envoy-upstream-service-time: 3 server: envoy HTTP/2 200 x-powered-by: tinyhttp access-control-allow-origin: * access-control-allow-methods: GET, HEAD, PUT, PATCH, POST, DELETE access-control-allow-headers: content-type content-type: text/html; charset=utf-8 etag: W/"627-v25siNUZqtFMwVFrEcJ5PHKH9xk" date: Thu, 12 Dec 2024 16:30:40 GMT x-envoy-upstream-service-time: 2 server: envoy HTTP/2 429 x-envoy-ratelimited: true date: Thu, 12 Dec 2024 16:30:39 GMT server: envoy