Summary
The current reference docker-compose.yml exposes the OpenCTI platform directly on a host port (${OPENCTI_PORT}:8080) with no reverse proxy in front of it. While the OpenCTI documentation has a dedicated section on deploying behind a reverse proxy (including an Nginx config snippet with WebSocket support), the sample Docker Compose does not include one.
Additionally, there is no guidance in the compose file for TLS configuration or custom CA trust — which is critical for multi-host deployments where components communicate across the network.
This creates a gap where users following the reference compose as their starting point deploy OpenCTI with:
- No TLS termination
- No WebSocket proxy handling
- No path toward production-grade network security
- No guidance for internal PKI / custom CA trust on workers and connectors
Problem
1. No Reverse Proxy in the Reference Compose
The current compose exposes OpenCTI directly:
opencti:
ports:
- "${OPENCTI_PORT}:8080"
This means:
- No TLS termination
- No WebSocket upgrade handling at the proxy layer
- No connection management (keepalive, buffering control)
- No path to horizontal scaling (multiple frontends behind a load balancer)
The documentation recommends a reverse proxy and provides an Nginx config snippet, but the compose file — which is what most users actually copy — doesn't include one.
2. No TLS / Custom CA Guidance for Multi-Host Deployments
When customers deploy OpenCTI across multiple hosts (common in production), traffic between components crosses the network. This requires:
- TLS on inter-component connections (platform → Elasticsearch, Redis, RabbitMQ, MinIO)
- HTTPS for worker/connector → platform API communication
- Custom CA trust when using internal PKI (non-public CAs)
The compose file has no commented-out examples or documentation for:
| Component |
Language |
CA Bundle Env Var |
TLS Enable Var |
| Workers |
Python |
REQUESTS_CA_BUNDLE |
Use https:// in OPENCTI_URL |
| Connectors |
Python |
REQUESTS_CA_BUNDLE |
Use https:// in OPENCTI_URL |
| XTM Composer |
Go |
SSL_CERT_FILE |
Use https:// in OPENCTI__URL |
| Platform (Node.js) |
Node.js |
NODE_EXTRA_CA_CERTS |
Per-service TLS vars (see below) |
Platform-to-infrastructure TLS vars:
ELASTICSEARCH__URL — switch to https://
REDIS__USE_SSL=true
RABBITMQ__USE_SSL=true
MINIO__USE_SSL=true
Proposal
A. Add an Nginx reverse proxy service to the compose file
nginx:
image: nginx:1.27-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
# Uncomment for TLS:
# - ./certs/cert.pem:/etc/nginx/ssl/cert.pem:ro
# - ./certs/key.pem:/etc/nginx/ssl/key.pem:ro
depends_on:
opencti:
condition: service_healthy
restart: always
With a reference nginx.conf that includes:
- WebSocket upgrade headers (required by OpenCTI)
- Proxy buffering/caching disabled (required for SSE/streaming)
client_max_body_size 5G (for large STIX bundle uploads)
- TLS configuration (commented out, ready to enable)
X-Forwarded-* headers for client IP preservation
And remove the direct port mapping from the opencti service:
# Before:
ports:
- "${OPENCTI_PORT}:8080"
# After: (no ports — accessed via nginx)
B. Add commented-out TLS/CA blocks to workers, connectors, and platform services
Example for Python-based services (workers, connectors):
environment:
# ── TLS: Internal PKI / Custom CA (uncomment for multi-host) ──
# - REQUESTS_CA_BUNDLE=/etc/ssl/custom/ca-bundle.crt
# - SSL_CERT_FILE=/etc/ssl/custom/ca-bundle.crt
# volumes:
# - ./certs/ca-bundle.crt:/etc/ssl/custom/ca-bundle.crt:ro
Example for Node.js platform services:
environment:
# ── TLS: Internal PKI / Custom CA (uncomment for multi-host) ──
# - NODE_EXTRA_CA_CERTS=/etc/ssl/custom/ca-bundle.crt
# ── TLS: Backend connections (uncomment for multi-host) ──
# - REDIS__USE_SSL=true
# - RABBITMQ__USE_SSL=true
# - MINIO__USE_SSL=true
C. Add a nginx.conf reference file to the repo
worker_processes auto;
events {
worker_connections 1024;
}
http {
upstream opencti {
server opencti:8080;
}
keepalive_timeout 65;
client_max_body_size 5G;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
server {
listen 80;
# listen 443 ssl;
# ssl_certificate /etc/nginx/ssl/cert.pem;
# ssl_certificate_key /etc/nginx/ssl/key.pem;
# ssl_protocols TLSv1.2 TLSv1.3;
server_name _;
location / {
proxy_pass http://opencti;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache off;
proxy_buffering off;
chunked_transfer_encoding off;
}
}
}
Impact
| Scenario |
Current State |
With This Change |
| New user follows quickstart |
Bare HTTP on a port, no proxy |
Production-ready with Nginx, TLS-ready |
| Multi-host Docker deployment |
No guidance on inter-component TLS |
Commented-out blocks ready to enable |
| Internal PKI / non-public CA |
Workers/connectors fail with SSL_VERIFY_FAILED |
CA bundle mount pattern documented |
| Horizontal scaling (multiple frontends) |
No load balancer pattern |
Nginx upstream block ready for multiple backends |
References
Summary
The current reference
docker-compose.ymlexposes the OpenCTI platform directly on a host port (${OPENCTI_PORT}:8080) with no reverse proxy in front of it. While the OpenCTI documentation has a dedicated section on deploying behind a reverse proxy (including an Nginx config snippet with WebSocket support), the sample Docker Compose does not include one.Additionally, there is no guidance in the compose file for TLS configuration or custom CA trust — which is critical for multi-host deployments where components communicate across the network.
This creates a gap where users following the reference compose as their starting point deploy OpenCTI with:
Problem
1. No Reverse Proxy in the Reference Compose
The current compose exposes OpenCTI directly:
This means:
The documentation recommends a reverse proxy and provides an Nginx config snippet, but the compose file — which is what most users actually copy — doesn't include one.
2. No TLS / Custom CA Guidance for Multi-Host Deployments
When customers deploy OpenCTI across multiple hosts (common in production), traffic between components crosses the network. This requires:
The compose file has no commented-out examples or documentation for:
REQUESTS_CA_BUNDLEhttps://inOPENCTI_URLREQUESTS_CA_BUNDLEhttps://inOPENCTI_URLSSL_CERT_FILEhttps://inOPENCTI__URLNODE_EXTRA_CA_CERTSPlatform-to-infrastructure TLS vars:
ELASTICSEARCH__URL— switch tohttps://REDIS__USE_SSL=trueRABBITMQ__USE_SSL=trueMINIO__USE_SSL=trueProposal
A. Add an Nginx reverse proxy service to the compose file
With a reference
nginx.confthat includes:client_max_body_size 5G(for large STIX bundle uploads)X-Forwarded-*headers for client IP preservationAnd remove the direct port mapping from the
openctiservice:B. Add commented-out TLS/CA blocks to workers, connectors, and platform services
Example for Python-based services (workers, connectors):
Example for Node.js platform services:
C. Add a
nginx.confreference file to the repoImpact
SSL_VERIFY_FAILEDReferences
FiligranHQ/csm-lab#67