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, andnumber_of_replicas- A
string_normalizerfor 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:
- Ensures the component and index templates exist via
elCreateIndexTemplate - Appends
elasticsearch:index_creation_pattern(default"-000001") to the index name - Executes a
PUTrequest to Elasticsearch viaengine.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:
- Regenerates the complete mapping via
engineMappingGenerator() - Retrieves existing indices using
elPlatformIndices() - Compares current mappings with expected mappings using
jsonpatch.compare - 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.jsonand are accessed via theconfhelper. - Client Initialization: The
searchEngineInit()function insrc/database/engine.tsconstructs the Elasticsearch client usingurl,auth, andsslparameters. - 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →