# How to Configure Rate Limiting Protection in OpenCTI: A Complete Guide

> Learn how to configure rate limiting protection in OpenCTI using JSON files or environment variables. Secure your GraphQL API with this comprehensive guide.

- Repository: [OpenCTI Platform/opencti](https://github.com/opencti-platform/opencti)
- Tags: how-to-guide
- Published: 2026-02-19

---

**OpenCTI applies Express rate-limit middleware to protect its GraphQL API, configurable via JSON files or environment variables using `app:rate_protection` settings.**

To configure rate limiting protection in OpenCTI, you modify the `rate_protection` object within the platform's hierarchical configuration system. The OpenCTI-Platform/opencti repository implements this protection using the `express-rate-limit` package, reading window duration and request thresholds from the `nconf` configuration layer.

## Understanding OpenCTI's Rate Limiting Implementation

OpenCTI embeds rate limiting directly into its HTTP platform initialization. The protection activates automatically when the server starts, applying a global limit to all incoming API requests.

### Core Middleware Configuration

In [`src/http/httpPlatform.js`](https://github.com/OpenCTI-Platform/opencti/blob/main/src/http/httpPlatform.js) (lines 102-107), OpenCTI instantiates the rate limiter using values from the configuration store:

```javascript
const limiter = rateLimit({
  windowMs: nconf.get('app:rate_protection:time_window') * 1000, // seconds
  limit: nconf.get('app:rate_protection:max_requests'),
  handler: (req, res) => {
    res.status(429).send({ message: 'Too many requests, please try again later.' });
  },
});
app.use(limiter);

```

The middleware intercepts every request and tracks client IPs. When requests exceed the configured threshold within the time window, the server responds with **HTTP 429** and a JSON error message.

### Default Configuration Values

The baseline settings reside in [`config/default.json`](https://github.com/OpenCTI-Platform/opencti/blob/main/config/default.json) (lines 101-104):

```json
"rate_protection": {
  "time_window": 1,
  "max_requests": 10000
}

```

By default, OpenCTI permits **10,000 requests per second**. This high threshold accommodates bulk ingestion operations but should be reduced for production deployments exposed to untrusted networks.

## Configuration Methods for Rate Limiting Protection

OpenCTI uses `nconf` to merge configuration sources hierarchically: command-line arguments override environment variables, which override JSON files. You can configure rate limiting through three primary methods.

### JSON Configuration Files

Create or modify environment-specific JSON files (e.g., [`production.json`](https://github.com/OpenCTI-Platform/opencti/blob/main/production.json)) to set permanent limits:

```json
{
  "app": {
    "rate_protection": {
      "time_window": 60,
      "max_requests": 500
    }
  }
}

```

Load the custom configuration using the `-c` flag:

```bash
node build/index.js -c config/production.json

```

### Environment Variables

OpenCTI maps hierarchical configuration keys to environment variables using double underscores (`__`) as separators. The configuration loader in [`src/config/conf.js`](https://github.com/OpenCTI-Platform/opencti/blob/main/src/config/conf.js) processes these with `lowerCase: true`.

Set rate limiting via environment variables:

```bash
export APP__RATE_PROTECTION__TIME_WINDOW=60
export APP__RATE_PROTECTION__MAX_REQUESTS=300

```

Environment variables take precedence over JSON file values, making them ideal for containerized deployments where configuration changes frequently.

### Command Line Options

While the `-c` flag specifies which configuration file to load, individual configuration overrides can be passed via environment variables when starting the platform. For Docker deployments, pass variables directly to the container.

## Practical Configuration Examples

### Docker Deployment with Custom Limits

Mount a custom configuration file when running the OpenCTI platform container:

```bash
docker run --rm \
  -e NODE_ENV=production \
  -v $(pwd)/custom-rate-limit.json:/app/config/custom.json \
  opencti/platform:latest \
  -c config/custom.json

```

Contents of [`custom-rate-limit.json`](https://github.com/OpenCTI-Platform/opencti/blob/main/custom-rate-limit.json):

```json
{
  "app": {
    "rate_protection": {
      "time_window": 30,
      "max_requests": 200
    }
  }
}

```

### Docker Compose Configuration

Define rate limiting in your [`docker-compose.yml`](https://github.com/OpenCTI-Platform/opencti/blob/main/docker-compose.yml) for persistent deployments:

```yaml
services:
  opencti:
    image: opencti/platform:latest
    environment:
      - APP__RATE_PROTECTION__TIME_WINDOW=60
      - APP__RATE_PROTECTION__MAX_REQUESTS=500
      - NODE_ENV=production
    ports:
      - "8080:8080"

```

### Programmatic Verification

Test your configuration by simulating high request volume:

```bash

# Send 150 requests in parallel (adjust based on your limit)

for i in {1..150}; do
  curl -s -o /dev/null -w "%{http_code}\n" \
    http://localhost:8080/graphql \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{"query":"{ about { version } }"}' &
done
wait

```

If configured correctly, requests exceeding your `max_requests` threshold should return `429` status codes.

## How the Rate Limiter Works

When a client connects to the OpenCTI API, the **Express rate-limit middleware** maintains an in-memory store tracking request counts per IP address. The middleware compares the current request count against the `max_requests` value within the rolling `time_window` (converted to milliseconds).

If the threshold is exceeded, the `handler` function executes immediately, sending **HTTP 429 Too Many Requests** with a JSON error body. Successful requests continue to the GraphQL resolver chain. The limiter applies **globally** to all routes in the default implementation, protecting both authentication endpoints and data ingestion APIs equally.

## Summary

- OpenCTI implements rate limiting via `express-rate-limit` middleware in [`src/http/httpPlatform.js`](https://github.com/OpenCTI-Platform/opencti/blob/main/src/http/httpPlatform.js), reading configuration from the `nconf` hierarchy.
- Default settings allow 10,000 requests per second (`time_window: 1`, `max_requests: 10000`), defined in [`config/default.json`](https://github.com/OpenCTI-Platform/opencti/blob/main/config/default.json).
- Configure limits via JSON files (`app.rate_protection` object), environment variables (`APP__RATE_PROTECTION__TIME_WINDOW` and `APP__RATE_PROTECTION__MAX_REQUESTS`), or Docker environment settings.
- Exceeding the configured threshold returns HTTP 429 with the message "Too many requests, please try again later."

## Frequently Asked Questions

### What are the default rate limiting values in OpenCTI?

By default, OpenCTI permits **10,000 requests per 1-second window**. These values are hardcoded in [`config/default.json`](https://github.com/OpenCTI-Platform/opencti/blob/main/config/default.json) under the `rate_protection` key, with `time_window` set to `1` (second) and `max_requests` set to `10000`. This generous default accommodates high-volume data ingestion but should be reduced for production environments facing the public internet.

### How do I completely disable rate limiting in OpenCTI?

While OpenCTI does not provide an explicit "disable" flag, you can effectively disable rate limiting by setting the `max_requests` value to an extremely high number (e.g., `999999999`) or by setting the `time_window` to a very large value. Alternatively, since the middleware is applied conditionally based on configuration, setting `max_requests` to `0` may disable the limiter depending on the `express-rate-limit` version, though this is not officially documented and should be tested in a non-production environment first.

### Can I configure different rate limits for different API endpoints?

The default implementation in [`src/http/httpPlatform.js`](https://github.com/OpenCTI-Platform/opencti/blob/main/src/http/httpPlatform.js) applies a **global rate limiter** to all routes via `app.use(limiter)`. To implement endpoint-specific limits, you would need to modify the source code to create multiple `rateLimit` instances with different configurations and apply them to specific route patterns (e.g., `app.use('/graphql', strictLimiter)` vs `app.use('/health', permissiveLimiter)`). This requires maintaining a fork or custom build of the platform, as the standard distribution does not expose per-route rate limiting through configuration files.

### Why is my OpenCTI instance returning HTTP 429 errors?

HTTP 429 errors indicate that the client has exceeded the configured rate limits defined by `app:rate_protection:max_requests` within the `app:rate_protection:time_window` period. This commonly occurs during bulk import operations, automated scanning, or when multiple users share the same egress IP address. To resolve this, either reduce the request frequency from the client side, or increase the `max_requests` value (or expand the `time_window`) in your OpenCTI configuration via environment variables or JSON config files. Check the server logs to confirm which specific limit is being triggered.