# How to Configure GraphQL Armor Protection in OpenCTI

> Learn how to configure GraphQL Armor protection in OpenCTI. Enable this crucial security feature to harden your Apollo Server against common exploits and ensure data integrity.

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

---

**OpenCTI uses the GraphQL-Armor library to enforce hardening rules on its Apollo Server, but this protection is disabled by default and must be explicitly enabled via configuration.**

GraphQL Armor protection in OpenCTI adds security layers like cost limiting, depth restrictions, and token counting to prevent malicious or expensive queries from overwhelming the platform. According to the OpenCTI-Platform/opencti source code, these protections are implemented as optional Apollo Server plugins that require manual activation through environment variables or JSON configuration files.

## How GraphQL Armor Works in OpenCTI

The platform integrates **GraphQL-Armor** by conditionally wrapping the Apollo Server instance with security plugins. When enabled, `ApolloArmor` injects validation rules that reject queries exceeding configured thresholds before they execute against the database.

### Configuration Source

In [`src/config/conf.js`](https://github.com/OpenCTI-Platform/opencti/blob/main/src/config/conf.js), the platform defines the `GRAPHQL_ARMOR_DISABLED` flag (line 518). This boolean defaults to `true`, meaning the armor plugins are bypassed unless you explicitly override the setting. The configuration follows the nested key `app:graphql:armor_protection:disabled`, which the configuration loader reads using the `conf.get` helper and `booleanConf` parser.

### Apollo Server Integration

The actual plugin instantiation occurs in [`src/graphql/graphql.js`](https://github.com/OpenCTI-Platform/opencti/blob/main/src/graphql/graphql.js) (lines 44‑62). The code checks `if (!GRAPHQL_ARMOR_DISABLED)` and, when the flag is false, creates an `ApolloArmor` instance with options derived from the central config object. The armor then provides `plugins` and `validationRules` arrays that the Apollo Server constructor merges into its setup.

## Available Protection Rules

When GraphQL Armor protection is active, OpenCTI enforces the following constraints. Each option maps to a specific configuration key under `app:graphql:armor_protection`:

- **Block Field Suggestion** (`block_field_suggestion`): Prevents the server from suggesting fields when it receives malformed queries. Default: `true`.
- **Cost Limit** (`cost_limit`): Sets a maximum complexity score for GraphQL documents. Default: `3000000`.
- **Max Depth** (`max_depth`): Limits how many levels deep queries can nest. Default: `20`.
- **Max Directives** (`max_directives`): Restricts the number of directive usages per document. Default: `20`.
- **Max Tokens** (`max_tokens`): Caps the total number of GraphQL tokens parsed in a request. Default: `100000`.
- **Max Aliases** (`max_aliases`): Controls alias count; OpenCTI disables this (`false`) because alias abuse is already handled by the `graphql-no-alias` package.

## How to Enable and Configure GraphQL Armor

### Step 1: Disable the Default Disabled Flag

Set the `APP_GRAPHQL_ARMOR_PROTECTION_DISABLED` environment variable to `false`:

```bash
export APP_GRAPHQL_ARMOR_PROTECTION_DISABLED=false

```

Alternatively, create or modify a JSON configuration file (e.g., [`config/production.json`](https://github.com/OpenCTI-Platform/opencti/blob/main/config/production.json)):

```json
{
  "app": {
    "graphql": {
      "armor_protection": {
        "disabled": false
      }
    }
  }
}

```

### Step 2: Tune Individual Limits (Optional)

Adjust thresholds using environment variables. The configuration loader converts colon-separated keys to double underscores internally:

```bash
export APP_GRAPHQL_ARMOR_PROTECTION_COST_LIMIT=2000000
export APP_GRAPHQL_ARMOR_PROTECTION_MAX_DEPTH=15
export APP_GRAPHQL_ARMOR_PROTECTION_MAX_TOKENS=50000
export APP_GRAPHQL_ARMOR_PROTECTION_BLOCK_FIELD_SUGGESTION=true

```

Or specify them in JSON format:

```json
{
  "app": {
    "graphql": {
      "armor_protection": {
        "disabled": false,
        "cost_limit": 2000000,
        "max_depth": 15,
        "max_directives": 10,
        "max_tokens": 50000,
        "block_field_suggestion": true
      }
    }
  }
}

```

### Step 3: Restart the Platform

Restart the OpenCTI platform container or process. The Apollo Server bootstrap in [`src/graphql/graphql.js`](https://github.com/OpenCTI-Platform/opencti/blob/main/src/graphql/graphql.js) will now instantiate `ApolloArmor` and register its plugins. Requests exceeding your configured limits will receive immediate GraphQL errors without hitting the database.

### Docker Compose Example

```yaml
services:
  opencti:
    image: opencti/platform:latest
    environment:
      - APP_GRAPHQL_ARMOR_PROTECTION_DISABLED=false
      - APP_GRAPHQL_ARMOR_PROTECTION_COST_LIMIT=2500000
      - APP_GRAPHQL_ARMOR_PROTECTION_MAX_DEPTH=18
      - APP_GRAPHQL_ARMOR_PROTECTION_MAX_DIRECTIVES=15

```

## Summary

- GraphQL Armor protection in OpenCTI is **disabled by default** via the `GRAPHQL_ARMOR_DISABLED` flag in [`src/config/conf.js`](https://github.com/OpenCTI-Platform/opencti/blob/main/src/config/conf.js).
- The protection rules are implemented in [`src/graphql/graphql.js`](https://github.com/OpenCTI-Platform/opencti/blob/main/src/graphql/graphql.js) using the `ApolloArmor` library.
- Key configurable limits include **cost limit** (default 3,000,000), **max depth** (default 20), and **max tokens** (default 100,000).
- Enable protection by setting `app:graphql:armor_protection:disabled` to `false` using environment variables or JSON configuration.
- Changes require a platform restart to take effect.

## Frequently Asked Questions

### Is GraphQL Armor enabled by default in OpenCTI?

No. The source code explicitly sets `GRAPHQL_ARMOR_DISABLED` to `true` by default (config key `app:graphql:armor_protection:disabled`). You must explicitly set this value to `false` to activate the protection rules.

### What happens when a query exceeds the armor limits?

When GraphQL Armor is active, any query exceeding the configured thresholds (such as cost limit or max depth) is rejected immediately with a GraphQL validation error. The request does not reach the resolver layer or database, protecting the platform from expensive or malicious payloads.

### Can I enable armor protection without restarting OpenCTI?

No. The `ApolloArmor` instance is created during the Apollo Server bootstrap in [`src/graphql/graphql.js`](https://github.com/OpenCTI-Platform/opencti/blob/main/src/graphql/graphql.js). Because this occurs at startup, you must restart the OpenCTI platform after changing any `armor_protection` configuration values for them to take effect.

### How do I calculate the right cost limit for my deployment?

Start with the default value of `3000000` and monitor your logs for rejected legitimate queries. If standard UI operations trigger cost limit errors, incrementally raise the value. For high-security environments, lower the limit gradually until you find the threshold that blocks complex abusive queries without impacting normal usage.