How to Configure Elasticsearch Indexing in OpenCTI: Complete Setup Guide

To configure Elasticsearch indexing in OpenCTI, modify the elasticsearch section in opencti-platform/opencti-graphql/config/default.json (or an overriding configuration file) to set the cluster URL, authentication credentials, index prefix, shard/replica counts, and rollover policies before starting the platform.

OpenCTI stores all STIX-compatible data in an Elasticsearch or OpenSearch cluster, making proper indexing configuration critical for performance, scalability, and data retention. This guide explains how to configure Elasticsearch indexing in OpenCTI based on the source code implementation in the OpenCTI-Platform/opencti repository.

Elasticsearch Indexing Configuration File Location

All Elasticsearch indexing settings are read from opencti-platform/opencti-graphql/config/default.json. You can override these defaults by providing a custom configuration file that merges with or replaces the default values.

Core Configuration Parameters

The following table lists the key parameters that control how OpenCTI configures Elasticsearch indexing:

Setting Description Default Value
elasticsearch:index_prefix Prefix for all OpenCTI indices (e.g., opencti-*) "opencti"
elasticsearch:url HTTP URL of the Elasticsearch node "http://localhost:9200"
elasticsearch:username Basic auth username null
elasticsearch:password Basic auth password null
elasticsearch:api_key API key for authentication null
elasticsearch:proxy HTTP proxy for the connection null
elasticsearch:ssl:ca Array of CA certificate paths []
elasticsearch:ssl:ca_plain Base64-encoded CA certificate null
elasticsearch:ssl:reject_unauthorized Reject self-signed certificates true
elasticsearch:index_creation_pattern Suffix for new indices (rollover) "-000001"
elasticsearch:number_of_shards Primary shards per index 1
elasticsearch:number_of_replicas Replica shards per index 1
elasticsearch:max_primary_shard_size Rollover trigger size "50gb"
elasticsearch:max_docs Rollover trigger document count 75000000
elasticsearch:max_result_window Maximum from+size pagination 100000
elasticsearch:max_bulk_operations Bulk request size limit 5000
elasticsearch:max_concurrency Concurrent request limit 4

These values are accessed via the conf helper throughout the engine implementation.

How to Configure the Elasticsearch Client Engine

When the platform starts, the searchEngineInit() function in src/database/engine.ts constructs the Elasticsearch client using your configuration.

Client Initialization Code

The engine builds the client configuration object as follows:

const elkSearchConfiguration = {
  node: conf.get('elasticsearch:url'),
  proxy: conf.get('elasticsearch:proxy') || null,
  auth: {
    username: conf.get('elasticsearch:username') || null,
    password: conf.get('elasticsearch:password') || null,
    apiKey: conf.get('elasticsearch:api_key') || null,
  },
  maxRetries: conf.get('elasticsearch:max_retries') || 3,
  requestTimeout: conf.get('elasticsearch:request_timeout') || 3600000,
  sniffOnStart: booleanConf('elasticsearch:sniff_on_start', false),
  ssl: { 
    ca, 
    rejectUnauthorized: booleanConf('elasticsearch:ssl:reject_unauthorized', true) 
  },
  tls: { 
    ca, 
    rejectUnauthorized: booleanConf('elasticsearch:ssl:reject_unauthorized', true) 
  },
};
engine = new ElkClient(elkSearchConfiguration);

If engine_selector is set to opensearch, the platform instantiates an OpenSearch client instead. The resulting engine instance is stored as a module-level variable and reused by all CRUD helpers such as elRawIndex, elRawSearch, and elCreateIndex.

Index Templates and Lifecycle Management

OpenCTI uses index templates and Index Lifecycle Management (ILM) policies to ensure consistent mappings and automated rollover.

Component Template: opencti-core-settings

The updateCoreSettings() function in src/database/engine.ts creates a component template named opencti-core-settings that defines:

  • max_result_window, number_of_shards, and number_of_replicas
  • A string_normalizer for keyword fields

Index Template Generation

The engineMappingGenerator() function generates the full index template (opencti-index-template) from schema attribute definitions. This template is applied to every new index and includes the rollover alias for platforms newer than version 5.9.

ILM Policy and Rollover Configuration

The elCreateLifecyclePolicy() function creates the opencti-ilm-policy with a hot phase that triggers rollover when either:

  • Primary shard size exceeds max_primary_shard_size (default 50 GB)
  • Document count exceeds max_docs (default 75,000,000)

Index Creation and Naming Conventions

When a new entity type requires storage, OpenCTI calls elCreateIndex(index, mappingProperties) in src/database/engine.ts. This function:

  1. Ensures the component and index templates exist via elCreateIndexTemplate
  2. Appends elasticsearch:index_creation_pattern (default "-000001") to the index name
  3. Executes a PUT request to Elasticsearch via engine.indices.create

All indices share the prefix defined by elasticsearch:index_prefix (default opencti), making it easy to identify platform indices using elPlatformIndices().

Updating Mappings and Schema Migrations

When the schema evolves, elUpdateIndicesMappings() executes automatically during startup or can be triggered manually. Located in src/database/engine.ts, this function:

  1. Regenerates the complete mapping via engineMappingGenerator()
  2. Retrieves existing indices using elPlatformIndices()
  3. Compares current mappings with expected mappings using jsonpatch.compare
  4. Sends add operations only (no replacements) to each index via indices.putMapping

This incremental approach ensures zero-downtime upgrades when adding new fields.

Practical Configuration Examples

Minimal Custom Configuration

Create a file named config/custom.json to override defaults:

{
  "elasticsearch": {
    "url": "https://es.mycorp.com:9200",
    "username": "opencti",
    "password": "MySecretPassword",
    "ssl": {
      "reject_unauthorized": false
    },
    "index_prefix": "myorg",
    "number_of_shards": 3,
    "number_of_replicas": 2,
    "max_primary_shard_size": "30gb",
    "max_docs": 50000000,
    "index_creation_pattern": "-000001"
  }
}

Start the platform with your custom configuration:

docker-compose -f docker-compose.yml -f custom-compose.yml up

All indices will be prefixed with myorg-* instead of the default opencti-*.

Force a Full Re-index After Schema Change


# 1. Validate the new schema mapping

node ./opencti-platform/opencti-graphql/script/script-generate-schema.js

# 2. Optional: Clean up stale relationships

node ./opencti-platform/opencti-graphql/script/script-clean-relations.js

# 3. Trigger the mapping update via GraphQL

curl -X POST http://localhost:4000/graphql \
  -H "Content-Type: application/json" \
  -d '{"query":"mutation { updateIndicesMappings }"}'

The updateIndicesMappings mutation invokes elUpdateIndicesMappings() and adds only missing fields without requiring downtime.

Delete All OpenCTI Indices (Fresh Install)

Use this TypeScript snippet to purge all OpenCTI indices:

import { elPlatformIndices, elDeleteIndex } from './src/database/engine';

async function deleteAll() {
  const indices = await elPlatformIndices();  // Lists all opencti-* indices
  for (const { index } of indices) {
    await elDeleteIndex(index);             // Drops alias and underlying index
    console.log(`Removed ${index}`);
  }
}

deleteAll();

Summary

  • Configuration Location: All Elasticsearch settings reside in opencti-platform/opencti-graphql/config/default.json and are accessed via the conf helper.
  • Client Initialization: The searchEngineInit() function in src/database/engine.ts constructs the Elasticsearch client using url, auth, and ssl parameters.
  • Index Management: OpenCTI uses component templates (opencti-core-settings), index templates (opencti-index-template), and ILM policies (opencti-ilm-policy) to manage shards, replicas, and rollover triggers.
  • Schema Evolution: The elUpdateIndicesMappings() function performs zero-downtime mapping updates by adding only new fields during platform upgrades.
  • Customization: Override index_prefix, number_of_shards, max_primary_shard_size, and other parameters to tailor indexing performance to your infrastructure.

Frequently Asked Questions

Where does OpenCTI store its Elasticsearch configuration?

OpenCTI stores Elasticsearch configuration in opencti-platform/opencti-graphql/config/default.json. The platform reads these settings at startup via the conf helper and uses them to initialize the client in src/database/engine.ts. You can override defaults by providing a custom configuration file that merges with or replaces the default JSON.

How do I change the index prefix in OpenCTI?

Set the elasticsearch:index_prefix value in your configuration file. For example, changing it from the default "opencti" to "myorg" causes all indices to be created as myorg-* instead of opencti-*. This is useful for multi-tenant environments or when running multiple OpenCTI instances against a single cluster.

What is the default rollover policy for OpenCTI indices?

The default ILM policy (opencti-ilm-policy) rolls over indices when the primary shard size exceeds 50 GB or when the document count exceeds 75,000,000. You can customize these thresholds via elasticsearch:max_primary_shard_size and elasticsearch:max_docs in the configuration file.

How do I update Elasticsearch mappings after upgrading OpenCTI?

OpenCTI automatically updates mappings during startup via the elUpdateIndicesMappings() function in src/database/engine.ts. This function compares current mappings with the expected schema and adds only missing fields using indices.putMapping. To manually trigger this process, execute the GraphQL mutation updateIndicesMappings against the platform API.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →