<!-- BusyBot node reference — https://busybot.net/tools/cortex/ -->

> Node: Cortex (`cortex`) · Action (binary) · v1
> Category: Utility · Credentials: Cortex API (`cortexApi`)
> Updated: 2026-08-16

# 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](https://busybot.net/credentials/cortex-api/) 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:

```json
{
  "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:

```json
{
  "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:

```json
{
  "type": "cortex",
  "parameters": {
    "resource": "job",
    "operation": "report",
    "jobId": "{{ $json.id }}"
  }
}
```

Run a responder against a case, describing the case with structured attributes:

```json
{
  "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:

```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::name` composite 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 `file` and 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`, `pap` and `message` are 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.