Skip to main content
The ChainPatrol OpenCTI connector is an external-import connector for OpenCTI. It imports the threats ChainPatrol investigates for your organization, and optionally the global blocklist, as indicators and observables your analysts can pivot on and your detection rules can threshold on. It is a pull connector: you run it inside your network, against your own OpenCTI. ChainPatrol never needs a route into your infrastructure.

Quick start

You need a running OpenCTI 7.261008.0 with Docker Compose, and a ChainPatrol API key. To install OpenCTI first, follow Filigran’s deployment guide.
1

Create a ChainPatrol API key

In the ChainPatrol dashboard, go to Settings → API Keys and create a key.
2

Add the connector to your OpenCTI docker-compose.yml

Add this service next to your existing OpenCTI services:
Then add CONNECTOR_CHAINPATROL_ID and CHAINPATROL_API_KEY to the .env file next to it.
3

Start it

Within a minute the log shows Polling the organization threat feed, then a summary such as Organization threats: 120 fetched, 118 converted. If a setting is wrong, the connector exits with a one-line message naming it, for example ChainPatrol rejected CHAINPATROL_API_KEY (401).
4

See your threats in OpenCTI

The connector appears under Integrations → Deployed. Your threats appear under Observations → Indicators, each labelled with its ChainPatrol status. The first sync imports your full history; OpenCTI’s workers can take several minutes to write it all, so scale them up for a large organization. After that the connector checks for changes every hour.
The example uses the admin token for brevity. For anything beyond a trial, run the connector as its own OpenCTI user: create one under Settings → Security → Users, add it to a group with the Connector role (OpenCTI ships one called Connectors), and set OPENCTI_TOKEN to its API token. Every imported entity then shows that user as its creator instead of admin, so ChainPatrol data is easy to filter, and gets that group’s confidence level instead of the admin’s.
The rest of this page explains what the connector imports, how to configure it, and how to investigate with it in OpenCTI.

What it imports

The connector has two feeds, configured independently. Most deployments only want the first.

Your organization’s threats (on by default)

Everything ChainPatrol has investigated on your behalf, from the moment a report is filed, not just once it is confirmed. Each asset carries labels describing where it is in its lifecycle: The labels are on both the indicator and the observable. The label names are chosen so the status sorts first. OpenCTI orders an entity’s labels alphabetically and its list views show only the first one, so the status is the label you see in every list.
Connector versions before October 2026 used chainpatrol:brand:* and chainpatrol:liveness:*. The first run after upgrading re-sends your organization’s threats once and replaces the old labels as it goes.
This feed is marked TLP:AMBER by default, because it names your brands and your open investigations.

The global blocklist (off by default)

Every asset on the ChainPatrol blocklist, roughly 500,000 entities, with no organization context: no brands, no reporting history, no takedown progress. Every asset is labelled chainpatrol:status:blocked. This feed is marked TLP:CLEAR by default. It is off by default because the first run imports the whole blocklist.
If you enable both feeds, an asset that is on the global blocklist and was reported for your organization carries both TLP:CLEAR and TLP:AMBER. That is deliberate: the fact that it is blocked is public, but the investigation context around it is not.

How each asset is modelled

Each asset becomes up to four kinds of OpenCTI object:
  • Indicator: a STIX pattern such as [url:value = 'https://…'], carrying the labels, the score and, for cleared assets, revoked: true.
  • Observable: the asset itself, carrying the same labels, score and summary as the indicator. The indicator is linked to it with a based-on relationship.
  • User-Account: for social media profiles, the handle, linked to the observable with related-to.
  • Notes: one per lifecycle transition (reported, escalated, blocked, takedown submitted…), each with a link to the asset’s page in ChainPatrol.
Crypto addresses (ADDRESS) and IP addresses are not imported yet. The indicator and the observable both carry a one-line summary of the asset, for example “Confirmed malicious and blocked by ChainPatrol on 2026-01-17. First reported 2026-01-17. Impersonates Jane Doe. Takedown completed. It was unreachable at the last check.”, and a link to the asset’s page in ChainPatrol. Whichever one an analyst lands on first, they have the story.

Validity and decay

An indicator’s valid from date is the time of the sync that sent it, not the date the asset was reported or blocked. OpenCTI starts its decay clock at that date, so a historical one would make most of your history arrive already expired: OpenCTI would revoke a phishing site blocked a year ago that ChainPatrol still blocks. The real dates are kept as the indicator’s original creation date and in its notes. The connector only re-sends assets that changed, so it also re-sends every blocked asset every 7 days (CHAINPATROL_REFRESH_INTERVAL_DAYS). That restarts their decay before OpenCTI’s shortest built-in lifetime runs out, so a blocked asset stays active for as long as ChainPatrol blocks it. Assets in any other state are left to decay normally. The global blocklist is too large to refresh this way. Its entries decay unless ChainPatrol updates them. If that matters to you, add a decay exclusion rule for them in OpenCTI.

Scores

Every indicator carries an x_opencti_score reflecting how sure ChainPatrol is, so you can build detection rules on a threshold. Only blocked assets are marked for detection (x_opencti_detection: true). An open report is a claim, not a finding. You can change any of these scores. See Configuration.
OpenCTI’s built-in indicator decay rules revoke indicators whose score falls to 20 or below, and lower every score over time. Keep open reports above 20, or open investigations will be revoked as soon as they arrive. URL indicators decay fastest under the default rules, so if you want open URL reports to stay active for long, raise their score or adjust your decay rules in OpenCTI under Settings → Customization → Decay rules.

Configuration

Every setting is an environment variable. When running from source, the same settings can go in config.yml under chainpatrol:, using the lower-case name without the prefix (for example CHAINPATROL_ORG_FEED_TLP becomes org_feed_tlp). Environment variables win over the file. The connector checks its setup before it registers with OpenCTI. If something is wrong it exits with a one-line message naming the setting at fault, for example ChainPatrol rejected CHAINPATROL_API_KEY (401) or OpenCTI rejected OPENCTI_TOKEN. It checks that:
  • OPENCTI_URL, OPENCTI_TOKEN and CONNECTOR_ID are set, and CONNECTOR_ID is a UUID;
  • OpenCTI accepts OPENCTI_TOKEN and ChainPatrol accepts CHAINPATROL_API_KEY;
  • at least one feed is enabled, every TLP, page size and score is in range, and no state scores higher than blocked.
Check the connector’s logs with docker compose logs connector-chainpatrol if it does not appear in OpenCTI after a minute.

Polling

The first run is a full backfill: every threat in your history is imported. Later runs only fetch what changed since the previous run. Each run rewinds its starting point by CHAINPATROL_POLL_OVERLAP_MINUTES so that a change landing mid-run is never missed. Re-reading a few minutes is harmless, because every update is an upsert. If a run fails, the next one retries the same window instead of skipping it.
A full backfill of a large organization can produce well over a hundred thousand OpenCTI queue messages. Scale up your OpenCTI workers for the first sync.

Labels you add are safe

OpenCTI adds labels without removing old ones, so an asset that moved from investigating to blocked would otherwise carry both. Before each update the connector removes the outdated chainpatrol:status:*, chainpatrol:takedown:* and chainpatrol:uptime:* label. It never removes chainpatrol:target:* labels, since several brands can apply, and it never touches labels outside the chainpatrol: prefix, so your analysts’ labels and other connectors’ labels are left alone.

Investigating in OpenCTI

Once the first sync has run, the examples below work on any OpenCTI instance with the connector attached. The screenshots use made-up example data for a fictional brand, Acme Exchange.
Imported indicators, newest first, status label first

Find what is still live

Open Observations → Indicators, add a Label filter for chainpatrol:status:blocked, and a second one for chainpatrol:uptime:alive. What is left is every confirmed phishing site, fake profile or scam page that was still reachable at ChainPatrol’s last check. Those are the ones to block first or escalate. Save the filter to keep it as a standing work queue.
Indicators filtered to blocked and still reachable
The colour of the status label tells you the state at a glance: red for blocked, orange for escalated, yellow for investigating, grey for closed and green for allowed. On a narrow screen the label text can be cut off, but the colour still shows.

Check a domain, URL or handle from an alert

Paste the value from a SIEM alert, a reported email or a support ticket into OpenCTI’s global search. Every match shows its ChainPatrol status, and the Analyses column counts its lifecycle notes.
Global search for a suspicious domain
Open the observable to see the one-line summary, the score, the labels and a link to the asset in ChainPatrol. You don’t need to click through to the indicator.
An observable with its ChainPatrol summary and labels

Follow a case from report to takedown

Open the indicator. Its original creation date is when ChainPatrol first saw the asset. Valid from is the sync that sent it, which keeps OpenCTI’s decay running from today rather than from the first report. Detection is on only for blocked assets.
A blocked indicator
Scroll to Notes about this entity for the timeline, newest first: reported, escalated, blocked, takedown submitted and takedown completed. Each note links to the asset’s page in ChainPatrol, where the reports, evidence and takedown history live.
Lifecycle notes on an indicator

See everything impersonating one brand

Filter on chainpatrol:target:<your-brand> to scope a campaign. Brands and the people ChainPatrol protects for you, such as executives, each get their own label. Add a status or takedown label to narrow it further, for example everything targeting your brand that is still under investigation.
Indicators targeting one brand

Track takedowns

chainpatrol:takedown:completed, submitted, open and cancelled show where each removal stands. Use the export button on a filtered list for your own reporting.
Indicators with a completed takedown

Pivot from a social profile to the account

A social media profile becomes a URL observable linked to a User-Account holding the handle. Open the observable’s Knowledge tab to reach it, and use the handle to correlate across your other sources.
A social profile linked to its User-Account

Build detection on confirmed threats only

Point detection rules and exports at indicators with Detection = Yes, or a score of at least 90. That is exactly the blocked set. Open reports (score 25) and cleared false positives (score 0, revoked) stay out of your blocklists.

Support

For help with the connector, your data or your API key, contact support@chainpatrol.io.