Merge pull request #28708 from drodil/backend_rate_limit

Backend rate limit
This commit is contained in:
Fredrik Adelöw
2025-06-16 21:01:37 +02:00
committed by GitHub
15 changed files with 514 additions and 9 deletions
@@ -68,6 +68,60 @@ For those routes you will also have to specify `allowLimitedAccess: true` when
using the [`auth`](./auth.md) and [`httpAuth`](./http-auth.md) services to
access the incoming credentials.
## Rate limiting
Rate limiting allows you to limit the amount of requests users can send to you backend.
This is useful for blocking various network attacks, such as DDOS.
To enable rate limiting, add the following to your config:
```yaml
backend:
rateLimit: true
```
You can additionally configure the rate limiting parameters, also by plugin:
```yaml
backend:
rateLimit:
global: true # Enables or disables rate limit for all plugins
window: 6s # Time window for rate limiting for single client
incomingRequestLimit: 100 # Number of requests to accept from one client during time window
ipAllowList: ['127.0.0.1'] # IPs to bypass rate limiting
skipSuccesfulRequests: false # Rate limit successful requests
skipFailedRequests: false # Rate limit failed requests
plugin:
# Plugin specific rate limiting
catalog:
window: 3s
incomingRequestLimit: 50
```
By default, the rate limiting is per instance and the request counts are stored into memory.
If you want to share this information across all your backstage instances, you have to configure
the rate limiting store:
```yaml
backend:
rateLimit:
global: true
store:
type: redis
connection: redis://127.0.0.1:16379
```
If your instance is working behind a proxy, you have to configure the backend to trust the proxy
for the rate limiting being able to distinguish clients.
```yaml
backend:
trustProxy: true
```
For more information about the trust proxy configuration and available options,
please refer to [express documentation](https://expressjs.com/en/guide/behind-proxies.html).
## Configuring the service
For more advanced customization, there are several APIs from the `@backstage/backend-defaults/httpRouter` package that allow you to customize the implementation of the config service. The default implementation uses all of the middleware exported from `@backstage/backend-defaults/httpRouter`, including `createLifecycleMiddleware`, `createAuthIntegrationRouter`, `createCredentialsBarrier` and `createCookieAuthRefreshMiddleware`. You can use these to create your own `httpRouter` service implementation, for example - here's how you would add a custom health check route to all plugins:
@@ -78,6 +132,7 @@ import {
createCookieAuthRefreshMiddleware,
createCredentialsBarrier,
createAuthIntegrationRouter,
createRateLimitMiddleware,
} from '@backstage/backend-defaults/httpRouter';
import { createServiceFactory } from '@backstage/backend-plugin-api';
@@ -105,6 +160,11 @@ backend.add(
}) {
const router = PromiseRouter();
// Optional rate limiting middleware
router.use(
createRateLimitMiddleware({ pluginId: plugin.getId(), config }),
);
rootHttpRouter.use(`/api/${plugin.getId()}`, router);
const credentialsBarrier = createCredentialsBarrier({
@@ -40,6 +40,10 @@ createBackendPlugin({
});
```
## Rate limiting
Please refer to the [HTTP Router documentation](./http-router.md#rate-limiting).
## Configuring the service
### Via `app-config.yaml`
@@ -121,6 +125,11 @@ backend.add(
app.use(middleware.cors());
app.use(middleware.compression());
// Optional rate limiting middleware
app.use(middleware.rateLimit());
// If you are using rate limiting behind a proxy, you should set the `trust proxy` setting to true
app.set('trust proxy', true);
app.use(healthRouter);
// you can add you your own middleware in here