OpenCTI → ThreatConnect
OpenCTI ↔ ThreatConnect: integration to migration path.
OpenCTI runs as a parallel graph alongside ThreatConnect first — a bidirectional connector mirrors TC into it while net-new sources land directly in OpenCTI — then it takes over analyst authoring and downstream reads one phase at a time. No flag-day cutover of a graph holding years of analyst annotation, and every step rolls back in minutes.
Where it stops is an honest decision, not a foregone conclusion. ThreatConnect's CAL cross-customer prevalence has no OSS substitute — for most orgs the terminal state keeps OpenCTI as the graph of record and TC as a CAL lookup. We decide that from your data, not the slug.
The idea
Make OpenCTI the graph of record. Keep TC for what only CAL does.
Both systems are STIX-2.1-native knowledge graphs with analyst workbenches, so the integration surface is unusually clean — the only real question is which side owns the graph of record. The ThreatConnect connector polls TC, normalises it into STIX 2.1, and writes through OpenCTI's GraphQL, while OpenCTI's TAXII collection registers back in TC as a feed source. New sources, sightings and analyst authoring move onto OpenCTI in sequence, each reversible — and only after downstream reads are off TC do you decide whether CAL is load-bearing enough to keep ThreatConnect as a prevalence service or retire it entirely.
The phases
Seven steps. Each one reversible.
Baseline & inventory
We document indicator and group counts by type, association edges, your source catalogue, every Playbook with its trigger, your TLP marking distribution and every downstream consumer. Read-only — ThreatConnect stays the only graph.
OpenCTI goes live behind TC
OpenCTI deploys HA (Elasticsearch, Redis, RabbitMQ, MinIO, Postgres + replicas) and the ThreatConnect connector mirrors TC into it, scoped to one low-volume source first. Score mapping is analyst-tuned, not auto-piloted. Analysts get view-only access.
New sources land on OpenCTI
Net-new feeds — new ISAC TAXII collections, community feeds, internal sensor pipelines — integrate directly into OpenCTI. SIEM sightings dual-write to both graphs; missing sightings are unacceptable, double-counted ones are fine. TC stays the analyst UI of record.
Analyst authoring moves to OpenCTI
Team by team, analysts train on the OpenCTI Workbench, active investigations are exported from TC as STIX 2.1 and re-confirmed in OpenCTI, and workflow-gating Playbooks are re-implemented as Live Stream consumers in code. SIEM and SOAR read primary from OpenCTI; TC stays a 30-day fallback.
Cut downstream reads off TC
SIEM, SOAR and EDR read indicator feeds exclusively from OpenCTI. ThreatConnect is touched only for CAL prevalence lookups on alert and residual commercial-feed pass-through. This is the terminal state if you keep CAL.
Decision point: keep CAL or retire it
We measure how often CAL prevalence drives analyst triage from the SOAR audit log and price direct-to-OpenCTI delivery for any TC-bundled feeds. If CAL is load-bearing you stop here; if not, and the SaaS line must come off the books, you proceed.
Retire ThreatConnect (only if you proceed)
TC is deactivated, commercial feeds reconnect directly to OpenCTI, and CAL enrichment is removed or replaced with a documented best-effort proxy that is explicitly not equivalent. A final 30-day read-only window precedes contract termination.
Feature parity
Where OpenCTI matches TC, and where it honestly does not.
| Capability | OpenCTI | ThreatConnect | Parity |
|---|---|---|---|
| IoC storage / model | STIX 2.1 knowledge graph (SDO/SCO/SRO + x_opencti_* extensions) | Group + Indicator + Association + Tag + Attribute model | At parity |
| STIX 2.1 round-trip fidelity | First-class — the internal model is STIX 2.1 | TI Ops imports/exports STIX 2.1 but Threat Assess / CAL lose fidelity on round-trip | Partial |
| Feed ingestion | 200+ community connectors; EXTERNAL_IMPORT + TAXII 2.1 | Vendor connector catalogue (~80) + Playbook-built integrations | At parity |
| Enrichment | INTERNAL_ENRICHMENT connectors (VirusTotal, AbuseIPDB, Shodan) | Vendor-bundled connectors + Playbook actions | At parity |
| Analyst-curated / prevalence scoring | confidence (0–100) + x_opencti_score (0–100), self-curated | CAL cross-customer prevalence + threatAssessRating 0–5 (vendor-curated) | SaaS only |
| Sightings / feedback | GraphQL sightingAdd keyed on observable + sensor; sighting SRO | /v3/indicators/{id}/observations feeding CAL prevalence math | At parity |
| Detection content | YARA/Sigma as indicator SDO with pattern_type yara/sigma | Group Signature holding YARA/Sigma content | At parity |
| Automation / playbooks | STREAM Live Stream + downstream worker (as code) | TI Ops Playbooks (no-code, vendor templates) | Partial |
| API surface | Full GraphQL with subscriptions + arbitrary-depth traversal | REST v3 (/v3/indicators, /v3/groups); N requests for N hops | Partial |
| TLP enforcement | marking-definition enforced at GraphQL field level by RBAC | TLP per-Owner/Source; cross-system propagation depends on connector | Partial |
| Source-reliability catalogue | Maintain Admiralty A–F yourself | Threat Assess vendor-managed auto-updating source ratings | SaaS only |
| Retention / decay | STIX valid_from / valid_until + OpenCTI decay rules | Indicator lastObserved / dateAdded-driven | At parity |
| Deployment & HA | Self-host Elasticsearch + Redis + RabbitMQ + MinIO + Postgres + workers | Vendor-managed SaaS | SaaS only |
| Cost model | Self-hosted infra + ops; per-seat lower at >5 analysts / >3 feeds | Per-seat + per-feed + CAL access tier | Partial |
| On-screen overlay | None | Polarity overlay (if licensed) | SaaS only |
What we're honest about
The caveats most vendors leave out.
CAL prevalence has no OSS equivalent
ThreatConnect's Collective Analytics Layer answers "have others seen this?" across its whole customer base — impossible without being multi-tenant SaaS. We quantify CAL usage from your SOAR audit log first; if it is load-bearing you keep TC as a CAL lookup service rather than pretend an OSS proxy matches it.
Playbook templates and Threat Assess move to code
TC's no-code Playbooks and its vendor-maintained source-reliability catalogue disappear on full cutover. Live Stream consumers give equivalent automation power as code, not drag-and-drop, and you maintain Admiralty A–F ratings yourself. We budget engineering time per Playbook rather than promise a free port.
The connector is lossy — sync is one canonical graph
Association-to-SRO heuristics can misclassify edges, score domains differ (TC's 0–5 versus OpenCTI's 0–100), and AMBER+STRICT can degrade to AMBER across the hop. We pin the connector version, audit the mapping per release with a deliberate TLP test object, and designate OpenCTI as canonical from Phase 3 so the lossiness has a single direction.
Self-hosting OpenCTI is five stateful services
OpenCTI is Elasticsearch, Redis, RabbitMQ, MinIO and Postgres plus workers — a real operational surface, and Postgres-only is not viable. We pre-commit to a runbook and a DR exercise before Phase 3, with an SRE familiar with each component, so owning the graph does not mean owning an outage.
Why this beats a flag day
Reversible in minutes; nothing cancelled until it has soaked.
Every integration phase rolls back in under 15 minutes — revert a source to TC-only, re-flip a team to TC-primary while its Playbooks run in parallel, or re-enable dual-read in the SIEM — because ThreatConnect stays live the whole way through. ThreatConnect is never retired until OpenCTI has carried downstream reads for at least 30 days and a documented Phase 5 decision is signed off, followed by a 30-day read-only evidence window before the contract ends. A knowledge graph with years of annotation never deserves a big-bang cutover.
See whether your threat-intel graph migrates cleanly.
A 30-minute call with a senior threat-intel engineer. We size your graph, audit your CAL dependency and Playbook library, and tell you honestly whether the terminal state is OpenCTI-primary with CAL retained or a full ThreatConnect retirement.
Map my migration →