Reference · Tools
Cortex
Run analyzers on observables and execute responders on TheHive entities using Cortex SOAR engine.
The Cortex node connects BusyBot to TheHive Project's Cortex engine so you can run threat-intelligence analyzers on observables and trigger automated response actions on TheHive entities. Use it to build a pipeline that takes a suspicious IP from an alert, runs an analyzer against it, waits for the verdict, and fires a responder to isolate a case — all without leaving your workflow.
- Node type
- Action (binary)
- Parameters
- 17
- Outputs
- Output, Error
- Credentials
- Cortex API
Cortex
Run Cortex analyzers and responders for threat intelligence and automated response
Overview
The Cortex tool interacts with TheHive Project’s Cortex analysis and response engine. It supports three resources: Analyzer — execute analyzers on observables (IPs, domains, hashes, URLs, files) to produce threat intelligence reports; Job — retrieve job details and analysis reports; and Responder — execute automated response actions on TheHive entities (cases, alerts, artifacts, tasks, task logs). File observables are uploaded as multipart form data. Analyzer runs can optionally wait for the finished report via the timeout parameter.
Category: Utility
Tool Name: cortex
Version: 1
Appearance: Icon: lucide-Brain | Color: #FF6D00
Node Type
Action (Binary) — handles file/binary data operations
Input / Output
| Direction | Port(s) |
|---|---|
| Input | Input |
| Output | Output, Error |
Credentials
This tool requires Cortex API credentials. See the Credentials Guide for setup instructions.
Resources
| Resource | Value |
|---|---|
| Analyzer | analyzer |
| Job | job |
| Responder | responder |
Operations
| Operation | Value | Description |
|---|---|---|
| Execute | execute | Run an analyzer on an observable, or execute a responder on a TheHive entity |
| Get | get | Get job details |
| Report | report | Get job analysis report |
Execute is offered by the analyzer and responder resources; Get and Report belong to the job resource.
Parameters
Analyzer: Execute
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Analyzer | string | Yes | — | ID of the analyzer to run. Use composite format “id::name” or just the analyzer ID. Obtain from Cortex UI or POST /api/analyzer/_search?range=all. Supports expressions. |
| Observable Type | options | Yes | ip | The type of observable to analyze. Must be supported by the selected analyzer. |
Options: domain, file, filename, fqdn, hash, ip, mail, mail_subject, other, regexp, registry, uri_path, url, user-agent | ||||
| Observable Value | string | Yes | — | The observable value to analyze (e.g., an IP address, domain name, hash, URL). Supports expressions like {{ $json.ip }}. (hidden when Observable Type is file) |
| Binary Property | string | Yes | data | Name of the binary property on the input item containing the file to analyze. Names are case-sensitive — see the upstream node’s Binary Data panel for the exact names to use. (shown when Observable Type is file) |
| TLP | options | No | 2 | Traffic Light Protocol level for the analyzed observable. |
Options: 0 (White), 1 (Green), 2 (Amber), 3 (Red) | ||||
| Additional Fields | collection | No | {} | Optional settings for the analyzer run. |
| — Force | boolean | No | false | Whether to bypass the analyzer cache and force a new analysis. |
| — Timeout (Seconds) | number | No | 3 | Seconds to wait for the analysis report. If set, the tool polls for the report. If omitted, the raw job object is returned immediately. |
Job: Get
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Job ID | string | Yes | — | The ID of the job to retrieve. Supports expressions like {{ $json.id }}. |
Job: Report
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Job ID | string | Yes | — | The ID of the job to retrieve. Supports expressions like {{ $json.id }}. |
Responder: Execute
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Responder | string | Yes | — | ID of the responder to run. Use composite format “id::name” or just the responder ID. Obtain from Cortex UI or GET /api/responder. Supports expressions. |
| Entity Type | options | Yes | case | The type of TheHive entity to pass to the responder. |
Options: case, alert, case_artifact, case_task, case_task_log | ||||
| JSON Parameters | boolean | No | false | Whether to provide the entity as a raw JSON object instead of structured attributes. |
| Entity Object (JSON) | string | Yes | — | The complete entity object as a JSON string. Fields like tlp, pap, and message are extracted automatically. Supports expressions. (shown when JSON Parameters is true) |
| Entity Parameters | json | No | {} | Structured entity attributes as JSON. For “case”: { title, description, severity, startDate, owner, flag, tags, tlp }. For “alert”: { title, description, severity, date, source, sourceRef, status, type, tags, tlp, follow, artifacts: { artifactValues: [{ dataType, data, binaryProperty, message, tags }] } }. For “case_artifact”: { dataType, data, binaryPropertyName, ioc, message, startDate, status, tlp }. For “case_task”: { title, status, flag }. For “case_task_log”: { message, startDate, status }. Supports expressions. (shown when JSON Parameters is false) |
All Operations
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Max Concurrency | number | No | 5 | Maximum number of items to process concurrently. Keep low since Cortex analyzers may be resource-intensive. |
Output Data
One output item per input item. The Cortex response is merged into the item JSON at the top level, so the incoming fields stay addressable alongside it. Binary data on the input item is forwarded unchanged, on error items too, so a retry branch still has the file.
What the response contains depends on the operation:
| Operation | Merged onto the item |
|---|---|
Analyzer execute, no Timeout set | The Cortex job record created by the run, including the job id you can feed into a later Job operation. The analysis is still running at this point. |
Analyzer execute, Timeout set | The finished report — the node submits the run, then waits up to the Timeout for the analyzer to complete and merges the report instead of the job stub. |
Job get | The job record: its status, the analyzer it ran, the observable it ran against, and the timestamps. |
Job report | The analyzer’s report for that job — the summary taxonomies and the full artifact-level findings the analyzer produced. |
Responder execute | The responder action record Cortex returns for the run, including its own job identifier and status. |
Two shapes exist for a reason: an analyzer run is asynchronous. Set Timeout when you want the answer on the same item, and leave it unset when you would rather record the job and collect the report later with a job/report node.
Because the merge happens at the top level, an incoming item field whose name collides with a Cortex response key is overwritten. Rename such fields upstream if you need both.
Usage Examples
- Analyze an IP address with VirusTotal analyzer
- Upload a suspicious file for malware analysis
- Get the analysis report for a completed job
- Execute a responder to close a TheHive case
- Scan a domain with multiple Cortex analyzers
Example Configuration
Analyze an IP address and wait up to a minute for the report:
{
"type": "cortex",
"parameters": {
"resource": "analyzer",
"operation": "execute",
"analyzer": "VirusTotal_GetReport_3_0",
"observableType": "ip",
"observableValue": "{{ $json.ip }}",
"tlp": 2,
"additionalFields": {
"timeout": 60
}
}
}
Submit a suspicious file for malware analysis, bypassing the cache:
{
"type": "cortex",
"parameters": {
"resource": "analyzer",
"operation": "execute",
"analyzer": "Yara_2_0",
"observableType": "file",
"binaryPropertyName": "data",
"tlp": 3,
"additionalFields": {
"force": true,
"timeout": 600
}
}
}
Collect the report for a job submitted earlier:
{
"type": "cortex",
"parameters": {
"resource": "job",
"operation": "report",
"jobId": "{{ $json.id }}"
}
}
Run a responder against a case, describing the case with structured attributes:
{
"type": "cortex",
"parameters": {
"resource": "responder",
"operation": "execute",
"responder": "MISP_2_1",
"entityType": "case",
"jsonObject": false,
"entityParameters": "{ \"title\": \"{{ $json.title }}\", \"description\": \"{{ $json.summary }}\", \"severity\": 3, \"owner\": \"analyst@company.com\", \"tlp\": 2, \"tags\": \"apt,campaign\" }"
}
}
Run a responder by passing the entity through as raw JSON:
{
"type": "cortex",
"parameters": {
"resource": "responder",
"operation": "execute",
"responder": "MISP_2_1",
"entityType": "alert",
"jsonObject": true,
"objectData": "{{ $json.alert }}"
}
}
Error Handling
| Mode | Behavior |
|---|---|
| stop | Halts workflow on first error |
| continue | Skips failed items, passes successful ones through |
| errorPort | Routes failed items to Error output port |
Tips
Run Cortex analyzers on observables (IPs, domains, files) and execute responders on TheHive entities for security orchestration.
- The
id::namecomposite is accepted. Paste the value straight out of the Cortex UI — everything before::is used as the analyzer or responder ID. - The item can supply the values. When Analyzer, Observable Type, Observable Value, Job ID, Responder, Entity Type or Entity Object is left empty, the node falls back to a field of the same name on the incoming item, so an upstream node can drive the run.
- File observables take the binary route. Set Observable Type to
fileand the node uploads the named binary property as multipart form data; Observable Value disappears because it no longer applies. - Timeout turns an async run into a synchronous one. Without it you get the job stub back immediately; with it the node waits that many seconds for the report and errors if the analyzer has not finished.
- Force skips the cache. Cortex reuses a recent identical analysis by default, which is usually what you want; turn Force on when you need a fresh verdict.
- The observable type must be one the analyzer accepts. Each analyzer declares its supported data types in Cortex; sending an unsupported one fails the run.
- Two ways to describe a responder entity. Leave JSON Parameters off to build the entity from structured attributes, or turn it on to pass a complete entity object through — in that mode
tlp,papandmessageare read out of the object itself and default to Amber when absent. - Alert artifacts and case artifacts can carry files. In structured mode, an artifact with
dataType: "file"reads the binary property you name on it and attaches the file to the entity. - Keep Max Concurrency low. Analyzers can be slow and resource-intensive, and a Cortex instance is easy to overwhelm.
Frequently asked questions
Do I get the finished analysis report back, or just a job ID?
By default you get a job stub immediately and the analysis runs asynchronously in Cortex. If you need the actual report in the same workflow run, set the Timeout parameter to the number of seconds the node should wait. If the analyzer hasn't finished within that window, the node routes to the Error output instead.
How do I analyze a file instead of a text observable like an IP or domain?
Set Observable Type to `file`. The node switches to a multipart form upload and reads the binary from the property name you specify on the incoming item — the Observable Value field disappears because it doesn't apply to files. Make sure an upstream node has already put the binary on the item before this node runs.
The analyzer keeps returning a cached result from a previous run. How do I force a fresh analysis?
Cortex reuses a recent identical analysis by default to save time and resources. Enable the Force parameter to bypass the cache and trigger a new run. Leave it off when freshness doesn't matter, since repeated identical analyses can slow down a shared Cortex instance.
What's the difference between leaving the Responder field empty versus filling it in?
When Analyzer, Responder, Entity Type, or several other parameters are left blank, the node falls back to a field of the same name on the incoming item. This means an upstream node — for example, one that fetches a list of TheHive cases — can drive which responder runs and on which entity without you hardcoding anything in the node itself.
What credential does this node require, and how should I configure it?
The node requires a Cortex API credential (type `cortexApi`). You'll need the base URL of your Cortex instance and an API key generated from the Cortex UI. The node does not support username/password authentication.
Build with the Cortex node
Drop it into a workflow, wire it to an agent, or call it on a schedule. You'll need Cortex API credentials first.
Open BusyBotLast updated . Spotted something wrong? Tell us.