Docker deployment for the eXtended Threat Management (XTM) stack, combining OpenCTI, OpenAEV and XTM One into a unified threat intelligence, adversary emulation and AI-assisted analysis platform.
This repository provides a complete Docker Compose setup for running:
- OpenCTI — Open Cyber Threat Intelligence Platform
- OpenAEV — Open Adversary Emulation & Validation Platform
- XTM One — AI-powered assistant connecting OpenCTI and OpenAEV
- XTM Composer — Unified connector/collector management
- Shared Infrastructure — Elasticsearch, Silo (S3 object storage), RabbitMQ, Redis, PostgreSQL + pgvector (one database each for OpenAEV and XTM One)
- Docker Engine 20.10+
- Docker Compose v2.0+
- Minimum 16GB RAM (recommended 32GB for production)
- At least 50GB available disk space
graph TB
OpenCTI["OpenCTI<br/>:8080"]
OpenAEV["OpenAEV<br/>:8081"]
XTMOne["XTM One<br/>:8090"]
Composer["XTM Composer"]
Worker["OpenCTI Worker"]
XTMOneWorker["XTM One Worker"]
OpenCTI <--> Composer
Composer <--> OpenAEV
OpenCTI <--> XTMOne
XTMOne <--> OpenAEV
Worker --> OpenCTI
XTMOneWorker --> XTMOne
subgraph Shared["Shared Infrastructure"]
ES[("Elasticsearch")]
Silo[("Silo (S3)")]
RabbitMQ[("RabbitMQ")]
Redis[("Redis")]
PG[("PostgreSQL + pgvector")]
end
OpenCTI --> ES
OpenCTI --> Silo
OpenCTI --> RabbitMQ
OpenCTI --> Redis
OpenAEV --> ES
OpenAEV --> Silo
OpenAEV --> RabbitMQ
OpenAEV --> PG
XTMOne --> Silo
XTMOne --> Redis
XTMOne --> PG
git clone https://github.com/FiligranHQ/xtm-docker.git
cd xtm-dockerCreate a .env file with the required configuration. An example is available in .env.sample.
# PostgreSQL (superuser of the shared instance, used by OpenAEV)
POSTGRES_USER=openaev
POSTGRES_PASSWORD=<generate-strong-password>
# Silo (S3 object storage, the variables keep their MINIO_ prefix)
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=<generate-strong-password>
# RabbitMQ
RABBITMQ_DEFAULT_USER=guest
RABBITMQ_DEFAULT_PASS=<generate-strong-password>
# OpenCTI
OPENCTI_EXTERNAL_SCHEME=http
OPENCTI_HOST=localhost
OPENCTI_PORT=8080
OPENCTI_ADMIN_EMAIL=admin@filigran.io
OPENCTI_ADMIN_PASSWORD=<generate-strong-password>
OPENCTI_ADMIN_TOKEN=<generate-uuid-v4>
OPENCTI_HEALTHCHECK_ACCESS_KEY=<generate-uuid-v4>
# OpenAEV
OPENAEV_EXTERNAL_SCHEME=http
OPENAEV_HOST=localhost
OPENAEV_PORT=8081
OPENAEV_ADMIN_EMAIL=admin@filigran.io
OPENAEV_ADMIN_PASSWORD=<generate-strong-password>
OPENAEV_ADMIN_TOKEN=<generate-uuid-v4>
OPENAEV_HEALTHCHECK_KEY=<generate-uuid-v4>
# SMTP (mandatory)
SMTP_HOST=localhost
SMTP_PORT=25
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_AUTH=false
SMTP_SSL_ENABLE=false
SMTP_STARTTLS_ENABLE=false
# IMAP (optional)
OPENAEV_MAIL_IMAP_ENABLED=false
IMAP_HOST=
IMAP_PORT=993
IMAP_USERNAME=
IMAP_PASSWORD=
IMAP_AUTH=true
IMAP_SSL_ENABLE=true
IMAP_STARTTLS_ENABLE=falseTip: Generate UUIDs using
uuidgen.OPENCTI_ENCRYPTION_KEYmust be a 32-byte base64 string produced withopenssl rand -base64 32, not a UUID.XTM_ONE_SECRET_KEYandPLATFORM_REGISTRATION_TOKENcan be any long random string (e.g.openssl rand -hex 32).The full XTM One configuration (admin credentials, image tag, the credentials of its PostgreSQL role, S3 bucket, license) lives at the bottom of .env.sample.
PLATFORM_REGISTRATION_TOKENis the shared secret that lets OpenCTI and OpenAEV register themselves with XTM One — it MUST be identical for the three platforms.
docker compose up -dOnce all services are healthy (this may take a few minutes on first start):
- OpenCTI: http://localhost:8080
- OpenAEV: http://localhost:8081
- XTM One: http://localhost:8090
- RabbitMQ Management: http://localhost:15672
Public and internal URLs: the URLs above (built from
OPENCTI_HOST,OPENAEV_HOST,XTM_ONE_HOST, their ports and their*_EXTERNAL_SCHEME: set the scheme tohttpstogether with the host when you publish them over TLS) are also the identity each product signs its requests to the others with, so they are set on both XTM One containers (BASE_URL). Inside the stack the containers reach each other on their service names (http://opencti:8080,http://openaev:8080,http://xtm-one:4000), so the public host names do not need to resolve inside Docker. This needs XTM One, OpenCTI and OpenAEV releases that include XTM-One-Platform/xtm-one#4883, OpenCTI-Platform/opencti#18585 and OpenAEV-Platform/openaev#8143.
| Connector | Description |
|---|---|
| Export File STIX | Export data in STIX 2.1 format |
| Export File CSV | Export data in CSV format |
| Export File TXT | Export data in plain text format |
| Import File STIX | Import STIX 2.1 bundles |
| Import Document | Import and analyze PDF, HTML, and text documents |
| Import File YARA | Import YARA rules |
| Analysis | Document analysis connector |
| Import External Reference | Import external references |
| OpenCTI Datasets | Default marking definitions and identities |
| MITRE ATT&CK | MITRE ATT&CK framework data |
| Collector | Description |
|---|---|
| MITRE ATT&CK | Attack techniques and procedures |
| OpenAEV Datasets | Default datasets and configurations |
| Atomic Red Team | Red Canary's Atomic Red Team tests |
| NVD NIST CVE | CVE data from NVD (requires API key) |
| Injector | Description |
|---|---|
| Nmap | Network scanning capabilities |
| Nuclei | Vulnerability scanning with Nuclei |
Adjust ELASTIC_MEMORY_SIZE based on your available RAM:
| Total RAM | Recommended Setting |
|---|---|
| 16GB | 2G |
| 32GB | 4G |
| 64GB+ | 8G |
Modify the worker replicas in docker-compose.yml:
worker:
deploy:
mode: replicated
replicas: 3 # Increase for higher throughputTo expose the platforms externally (behind reverse-proxy for instance), update the environment variables:
OPENCTI_EXTERNAL_SCHEME=https
OPENCTI_HOST=opencti.yourdomain.com
OPENCTI_PORT=443
OPENAEV_EXTERNAL_SCHEME=https
OPENAEV_HOST=openaev.yourdomain.com
OPENAEV_PORT=443# All services
docker compose logs -f
# Specific service
docker compose logs -f opencti
docker compose logs -f openaevdocker compose psdocker compose downdocker compose down -vEarlier versions of this stack ran two PostgreSQL containers: pgsql for OpenAEV and pgsql-xtm-one for XTM One. OpenAEV and XTM One now share one pgvector instance, on a new pgsqlshareddata volume, and the old volumes are left untouched. To keep your data, dump both databases before you pull the new version:
docker compose stop openaev xtm-one xtm-one-worker
docker compose exec -T pgsql sh -c 'pg_dump -U "$POSTGRES_USER" -Fc openaev' > openaev.dump
docker compose exec -T pgsql-xtm-one sh -c 'pg_dump -U "$POSTGRES_USER" -Fc xtm_one' > xtm_one.dump
docker compose downThen pull the new version, prepare the shared instance (the xtm-one-db-init service creates the XTM One role, its database and the pgvector extension), restore both databases and start the stack:
git pull
docker compose run --rm xtm-one-db-init
docker compose exec -T pgsql sh -c 'pg_restore -U "$POSTGRES_USER" -d openaev' < openaev.dump
docker compose exec -T pgsql sh -c 'pg_restore -U "$POSTGRES_USER" -d xtm_one' < xtm_one.dump
docker compose up -dOnce both platforms show their data, remove the old volumes (their prefix is your COMPOSE_PROJECT_NAME):
docker volume rm xtm_pgsqldata xtm_pgsqlxtmonedataIf you started the new version before dumping, your data is still in the old volumes. The xtm_pgsqlshareddata volume then holds the databases the platforms created on that start, with everything written to them since, and removing it deletes those writes for good: if you need any of them, dump both databases from pgsql first, with the same pg_dump commands. Then run docker compose down, remove the xtm_pgsqlshareddata volume, check out the previous version of this repository, and follow the steps above.
-
Check if Elasticsearch has enough virtual memory:
sudo sysctl -w vm.max_map_count=262144
-
Verify all environment variables are set in
.env -
Check logs for specific errors:
docker compose logs <service-name>
- Ensure all dependency services are healthy
- Verify tokens match between services
- Check network connectivity within Docker network
If you wish to report bugs or request new features:
- OpenCTI: GitHub Issues
- OpenAEV: GitHub Issues
For support or discussions about the XTM stack, join us on our Slack channel or email us at contact@filigran.io.
XTM is a product suite designed and developed by Filigran.
