> ## Documentation Index
> Fetch the complete documentation index at: https://docs.samschroeder.lu/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure SIEM Log Destinations and Delivery Resources

> Add Splunk, syslog TCP, and Elasticsearch destinations so ThreatLab can ship exercise log archives and analysts investigate real events in their SIEM.

SIEM destinations tell ThreatLab where to ship log archives when an analyst starts or redoes an exercise. You can configure one or more destinations under **Admin > Resources**, mix drivers to support different SIEM products in the same deployment, and enable or disable individual destinations without deleting them.

## Prerequisites

Configuring SIEM destinations requires the `manage_exercises` capability, which is included in the built-in `admin` role.

<Tip>
  Configure at least one SIEM destination before publishing exercises to analysts.
</Tip>

## Adding a SIEM Destination

<Steps>
  <Step title="Open the destination form">
    Navigate to **Admin > Resources > SIEMs** and click **Add Destination**.
  </Step>

  <Step title="Enter a SIEM name">
    Type a display name for this destination. This name is used in the UI, API calls, and noise job target lists — it is **case-sensitive**.
  </Step>

  <Step title="Choose a driver">
    Select the driver that matches your SIEM product. Each driver has its own required fields:

    <AccordionGroup>
      <Accordion title="splunk_hec — Splunk HTTP Event Collector">
        | Field               | Required | Notes                                                         |
        | ------------------- | -------- | ------------------------------------------------------------- |
        | Host                | Yes      | Splunk hostname or IP                                         |
        | HEC Token           | Yes      | HTTP Event Collector token                                    |
        | Index               | Yes      | Target Splunk index                                           |
        | Management port     | Yes      | Typically `8089`                                              |
        | Management protocol | Yes      | `https` (recommended) or `http`                               |
        | Admin password      | Yes      | Used by the management API to wipe the index on session reset |
      </Accordion>

      <Accordion title="syslog_tcp — Raw TCP Syslog">
        | Field                          | Required | Notes                                                                                                                                                                                                          |
        | ------------------------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
        | Host                           | Yes      | Syslog receiver hostname or IP                                                                                                                                                                                 |
        | Port                           | Yes      | TCP port                                                                                                                                                                                                       |
        | Header mode                    | No       | `preserve_raw`, `synthesize_if_missing`, or `force_synthesize`                                                                                                                                                 |
        | Header format                  | No       | `rfc3164` or `rfc5424`                                                                                                                                                                                         |
        | Source identity                | No       | Source host string inserted into the header                                                                                                                                                                    |
        | PRI                            | No       | Priority value 0–191                                                                                                                                                                                           |
        | App name                       | No       | Syslog APP-NAME field                                                                                                                                                                                          |
        | Process ID                     | No       | Syslog PROCID field                                                                                                                                                                                            |
        | Message ID                     | No       | Syslog MSGID field                                                                                                                                                                                             |
        | QRadar API host                | No       | QRadar console hostname or IP. Required when log source provisioning is enabled.                                                                                                                               |
        | QRadar API token               | No       | Bearer token for the QRadar REST API. Required when log source provisioning is enabled.                                                                                                                        |
        | QRadar event collector ID      | No       | Numeric ID of the event collector that receives the syslog feed. ThreatLab resolves a default collector if left blank.                                                                                         |
        | QRadar log source type         | No       | Display name of the QRadar log source type. Defaults to `Universal LEEF`.                                                                                                                                      |
        | QRadar log source protocol     | No       | Display name of the QRadar protocol type. Defaults to `Syslog`.                                                                                                                                                |
        | Enable log source provisioning | No       | When on, ThreatLab calls the QRadar REST API at exercise start to create or reuse a per-exercise log source. See [QRadar log source provisioning](/concepts/siem-integrations#qradar-log-source-provisioning). |
        | Enable offense cleanup         | No       | Reserved for closing QRadar offenses tied to an exercise's log source identity.                                                                                                                                |

        See [QRadar API management](#qradar-api-management) below to enable optional REST API features on a `syslog_tcp` destination that targets QRadar.
      </Accordion>

      <Accordion title="elastic_bulk — Elasticsearch Bulk API">
        | Field    | Required | Notes                        |
        | -------- | -------- | ---------------------------- |
        | Host     | Yes      | Elasticsearch hostname or IP |
        | Port     | Yes      | Typically `9200`             |
        | Username | Yes      | Elasticsearch username       |
        | Password | Yes      | Elasticsearch password       |
        | Index    | Yes      | Target index name            |
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Optional: configure QRadar API management">
    For `syslog_tcp` destinations only, expand **QRadar API management** to let ThreatLab call the QRadar REST API for log source provisioning and offense cleanup. Event delivery still uses syslog/LEEF — these settings only authorize follow-up management calls.

    | Field                | Required    | Notes                                                                                                              |
    | -------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------ |
    | Provision log source | No          | When enabled, ThreatLab can create or update the QRadar log source that receives this destination's syslog feed.   |
    | Close offenses       | No          | When enabled, ThreatLab can close offenses related to wiped sessions during cleanup.                               |
    | API host             | Conditional | QRadar console hostname (for example `qradar-console.example.com`). Required when either toggle above is on.       |
    | API token            | Conditional | QRadar Authorized Service token. Required when either toggle is on. On edit, leave blank to keep the stored token. |
    | Log source type      | No          | Defaults to `Universal LEEF`. Must match a log source type configured in QRadar.                                   |
    | Protocol             | No          | Defaults to `Syslog`. Must match a protocol name configured in QRadar.                                             |
    | Event collector ID   | No          | Positive integer. Leave blank to auto-select when QRadar has exactly one event collector.                          |

    <Note>
      QRadar API management is only available for the `syslog_tcp` driver. Switching a destination to another driver clears these settings.
    </Note>
  </Step>

  <Step title="Set the payload format">
    Choose the log format ThreatLab will ship to this destination:

    * **LEEF** — Default. Best for Splunk and syslog receivers.
    * **ECS** — Elastic Common Schema. Use this for Elasticsearch destinations.
  </Step>

  <Step title="Enable the destination">
    Toggle **Enabled** on. Disabled destinations are silently skipped when an exercise starts.
  </Step>

  <Step title="Save">
    Click **Save** to create the destination. It is immediately active for any new exercise sessions.
  </Step>
</Steps>

<Note>
  SIEM name is case-sensitive. It must match exactly in exercise start requests and noise job target lists.
</Note>

## QRadar API management

For QRadar destinations on the `syslog_tcp` driver, you can give ThreatLab REST API credentials so it can automate console tasks alongside event delivery. Event delivery still flows over syslog/LEEF — the API is only used for the management actions you opt into.

Expand the **qradar api management** section on a `syslog_tcp` destination to configure it.

| Field                | Required                     | Notes                                                                                                                                    |
| -------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| Provision log source | No                           | Toggle. When on, ThreatLab creates a per-exercise QRadar log source on first ship so events route to the right log source automatically. |
| Close offenses       | No                           | Toggle. When on, ThreatLab closes the QRadar offenses opened by an exercise attempt after the analyst completes it.                      |
| API host             | Yes (if either toggle is on) | QRadar console hostname (for example, `qradar-console.example.com`).                                                                     |
| API token            | Yes (if either toggle is on) | QRadar authorized service token. Leave blank when editing to keep the existing value.                                                    |
| Log source type      | No                           | QRadar log source type name. Defaults to `Universal LEEF`.                                                                               |
| Protocol             | No                           | QRadar log source protocol name. Defaults to `Syslog`.                                                                                   |
| Event collector ID   | No                           | Numeric event collector ID. Leave blank to auto-select when the console has exactly one collector.                                       |

<Info>
  Both toggles are scoped strictly to the destination's log source and the current exercise attempt window. ThreatLab will not touch offenses or log sources that belong to other destinations or attempts.
</Info>

### Close offenses on completion

When **Close offenses** is enabled, ThreatLab closes any **OPEN** QRadar offenses linked to the exercise log source that were opened during the analyst's attempt window. Cleanup runs after the attempt is scored and is **non-blocking**: if QRadar is unreachable or the API rejects a request, the analyst still gets a successful completion, and the failure is recorded for administrators to review.

Every cleanup attempt is recorded with the matched, closed, and failed offense IDs and one of three outcomes:

| Status    | Meaning                                                                                                         |
| --------- | --------------------------------------------------------------------------------------------------------------- |
| `ok`      | Every matched offense was closed (or no offenses were open).                                                    |
| `partial` | Some offenses closed; at least one failed. The last error message is stored alongside the failed IDs.           |
| `failed`  | Cleanup could not run (for example, missing credentials, no provisioned log source) or every close call failed. |

Cleanup is skipped — without an audit row — when the destination is disabled, uses a different driver, has the toggle off, or has no API credentials, and when the exercise has no provisioned QRadar log source for that destination yet.

## Enabling and Disabling Destinations

You can toggle a destination on or off from its detail page at any time. Disabled destinations are ignored at exercise start — no logs are shipped to them, and they do not block other destinations from receiving events.

## QRadar Log Source Provisioning

When a `syslog_tcp` destination targets QRadar and **Enable log source provisioning** is on, ThreatLab calls the QRadar REST API at exercise start to ensure a dedicated log source exists for that exercise. This lets you tie every event in QRadar back to a single exercise run.

To use provisioning:

1. Set the **QRadar API host** and **QRadar API token** on the destination.
2. Optionally pin the **QRadar event collector ID**, **log source type**, and **log source protocol**. ThreatLab uses sensible defaults (`Universal LEEF` over `Syslog`) and resolves the first available event collector if you leave them blank.
3. Toggle **Enable log source provisioning** on.
4. Make sure the QRadar API token has permission to read event collectors and log source types and to create log sources.

ThreatLab uses a deterministic identifier of `threatlab-{exercise}-{siem}` so the same exercise always reuses the same QRadar log source. Provisioning failures abort the exercise start so analysts never see a partially configured run — see [QRadar log source provisioning](/concepts/siem-integrations#qradar-log-source-provisioning) for the end-to-end behavior.

<Warning>
  Provisioning requires the QRadar API host and token to be reachable from the ThreatLab orchestrator. A misconfigured collector ID or an expired token blocks the session start with a clear error.
</Warning>

## Wipe Behavior on Session Reset

When an analyst resets their session (`DELETE /api/sessions`), ThreatLab wipes the SIEM index before re-shipping archives so the analyst starts with a clean dataset.

<CardGroup cols={3}>
  <Card title="Splunk HEC" icon="trash">
    Wipes the configured index via the Splunk management API using the admin credentials you provided.
  </Card>

  <Card title="Elasticsearch" icon="trash">
    Removes all documents in the target index using the `_delete_by_query` API.
  </Card>

  <Card title="Syslog TCP" icon="minus-circle">
    No wipe mechanism exists for raw TCP syslog. These destinations are skipped during the wipe phase.
  </Card>
</CardGroup>
