> ## 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.

# Changelog

> Product updates and release notes for ThreatLab.

<Update label="June 10, 2026" tags={["feature"]}>
  ## Per-section QRadar log sources gate exercise start, redo, and shipping

  Per-section QRadar log sources are now enforced at runtime, not just at publish. Exercise start, redo, and **Ship logs to SIEM** are blocked until every section has a ready log source, so analysts can't begin investigating events that would land under the wrong identity.

  ### New features

  * **Runtime readiness gate** — When **Provision log source** is enabled, ThreatLab checks every section's QRadar log source before each start, redo, and push. A section is ready only when it has a `provisioned` status, a QRadar log source ID, and no pending QRadar deploy. If any section is not ready, the operation fails fast with an error that names each blocking section and the reason — missing, failed, or deploy required. See [Per-section log sources](/concepts/siem-integrations#per-section-log-sources).
  * **Offense cleanup dedup across sections** — Session wipe and redo now close offenses tied to every provisioned section log source for the exercise — plus any legacy exercise-level log source — and deduplicate offenses linked to more than one section's log source so the cleanup summary stays clean. See [Offense cleanup across sections](/concepts/siem-integrations#offense-cleanup-across-sections).

  ### Updates

  * **Legacy fallback preserved** — Exercises with no per-section QRadar rows continue to use the legacy exercise-level log source, so older content keeps working unchanged.
  * **SIEM errors troubleshooting** — A new entry covers the `QRadar section log sources are not ready` error and walks through the fix for missing, failed, and deploy-required cases. See [SIEM errors](/troubleshooting/siem-errors).
</Update>

<Update label="June 10, 2026" tags={["feature"]}>
  ## QRadar log-source preflight gates exercise publish

  Publishing an exercise now provisions a QRadar log source for each section before the exercise is marked **Active**, so staged section release lines up with QRadar deploy state instead of failing silently after analysts start.

  ### New features

  * **Per-section QRadar log-source provisioning at publish** — When at least one enabled `syslog_tcp` destination has **Provision log source** turned on, toggling an exercise to **Active** runs a QRadar preflight that ensures a log source exists in QRadar for every section. See [QRadar log-source preflight](/guides/authoring-exercises#qradar-log-source-preflight).
  * **Publish blocked on QRadar deploy required** — If QRadar accepted the log source but still needs **Deploy Changes** to be run in the QRadar console, the exercise is saved as **Draft** with an inline warning naming the destination and section. Run **Deploy Changes** in QRadar, then publish again. Cached log sources with `requires_deploy` are re-checked live against QRadar, so no manual cache reset is needed.
  * **Publish blocked on provisioning errors** — If QRadar returns an error during provisioning, the exercise is saved as **Draft** and the underlying error is surfaced inline so authors can fix credentials, log source type, or protocol settings without leaving the form.

  ### Updates

  * **Author publish flow** — The create and edit forms now route post-save based on the server-confirmed publish result rather than the client **Active** toggle. When QRadar preflight blocks activation, the edit form syncs its local active/draft state back from the server so the toggle accurately reflects what actually shipped.
  * **SIEM integrations reference** — The [QRadar API management](/concepts/siem-integrations#qradar-api-management) section now documents per-section log-source provisioning and the publish-time preflight behaviour.
</Update>

<Update label="June 10, 2026" tags={["feature"]}>
  ## Per-section QRadar log source provisioning

  QRadar log source provisioning now runs per exercise section instead of once per exercise. Sectioned exercises get one QRadar log source per section on every enabled QRadar `syslog_tcp` destination, so each section's events land on its own log source.

  ### New features

  * **One QRadar log source per section** — When **Provision log source** is enabled, ThreatLab creates a log source per section, keyed by exercise and section so log sources are never reused across exercises. Reruns are idempotent: already-provisioned sections return their existing log source. See [QRadar API management](/concepts/siem-integrations#qradar-api-management).
  * **Per-section success and failure** — Provisioning reports a result for each section and destination pair, so a single section failing on one destination does not block the rest. Sectionless exercises continue to provision a single log source per exercise.
</Update>

<Update label="June 10, 2026" tags={["weekly"]}>
  ## This week in ThreatLab

  A quick roundup of everything that shipped in ThreatLab's first full week. Detailed entries follow below.

  ### New features

  * **Staged section release** — Hold later evidence back until analysts make real progress, with delay timers, artifact gates, and a per-section shipment status panel. See [Staged section release](/guides/authoring-exercises#staged-section-release).
  * **ECS as a first-class archive format** — Author exercises with ECS alongside LEEF, with per-row format badges and automatic LEEF↔ECS pairing via SyslogCanon. See [Archive formats](/concepts/exercises#archive-formats).
  * **Draft autosave for exercise authoring** — Exercises now save as you work, with live status in the cmdbar. Start with just a title and come back later. See [Draft autosave](/guides/authoring-exercises#draft-autosave).
  * **Per-archive index routing for noise jobs** — Send each noise archive to its own SIEM index, with automatic provisioning on Splunk and Elasticsearch. See [Per-archive index routing](/guides/noise-logs#per-archive-index-routing).
  * **QRadar REST API management** — `syslog_tcp` destinations can now provision per-exercise QRadar log sources and close offenses on completion. See [QRadar API management](/admin/siem-resources#qradar-api-management).

  ### Updates

  * **Format-aware publish validation** — Publishing an exercise now verifies every section has a complete archive in each format your enabled destinations require, with per-SIEM, per-format errors. See [Publish-time readiness](/concepts/siem-integrations#publish-time-readiness).
  * **Stricter SIEM shipping for sectioned exercises** — Section archives are the single source of truth; no silent fallback to legacy bundles. See [SIEM integrations](/concepts/siem-integrations).
  * **Publish-time deadlock check** — Toggling to **Active** blocks publishes where no section can release at start, or a section is gated by an artifact that lives in its own logs, with an explicit override. See [Publish-time deadlock check](/guides/authoring-exercises#publish-time-deadlock-check).

  ### Bug fixes

  * **Incomplete archive sets caught at save time** — Saving or publishing a staged exercise now validates section archives against every enabled SIEM destination's payload format up front, instead of failing later at exercise start.
</Update>

<Update label="June 9, 2026" tags={["feature"]}>
  ## QRadar API management for syslog destinations

  QRadar destinations on the `syslog_tcp` driver can now use the QRadar REST API for two console-side tasks alongside event delivery.

  ### New features

  * **Close offenses on completion** — When an analyst finishes an exercise attempt, ThreatLab closes the QRadar offenses linked to the exercise log source that were opened during the attempt window. Cleanup runs after scoring and never blocks completion; failures are recorded for administrators with `ok`, `partial`, or `failed` status. See [Close offenses on completion](/admin/siem-resources#close-offenses-on-completion).
  * **Provision log source** — Optional toggle that creates a per-exercise QRadar log source on first ship so events route to a dedicated log source. See [QRadar API management](/admin/siem-resources#qradar-api-management).
  * **API credentials on the destination form** — Add the QRadar console host, an authorized service token, log source type, protocol, and event collector ID directly on the `syslog_tcp` destination. Event delivery still flows over syslog/LEEF.
</Update>

<Update label="June 9, 2026" tags={["feature"]}>
  ## QRadar log source provisioning for exercises

  Syslog TCP destinations that target QRadar can now provision a dedicated per-exercise log source through the QRadar REST API, so every event you investigate is tied back to a single exercise run.

  ### New features

  * **Per-exercise QRadar log sources** — When **Enable log source provisioning** is on, ThreatLab creates or reuses a QRadar log source with a deterministic `threatlab-{exercise}-{siem}` identifier at exercise start, and tags every outgoing syslog frame with that identity. See [QRadar log source provisioning](/concepts/siem-integrations#qradar-log-source-provisioning).
  * **QRadar API destination fields** — `syslog_tcp` destinations gained QRadar API host, token, event collector ID, log source type, and log source protocol fields, plus toggles for log source provisioning and offense cleanup. See [Adding a SIEM destination](/admin/siem-resources#adding-a-siem-destination).
  * **`syslogSourceIdentity` on session start** — `POST /api/sessions/start` accepts an optional `syslogSourceIdentity` that forces synthesized syslog headers with that value as the source host. See [POST /api/sessions/start](/api/sessions-start#request-body).

  ### Updates

  * **Provisioning failures abort start** — If the QRadar API is unreachable or the configured event collector cannot be resolved, exercise start now fails fast with a clear error instead of shipping events to an unprovisioned log source.
</Update>

<Update label="June 9, 2026" tags={["feature"]}>
  ## Staged section release for exercise log shipping

  Exercise sections can now ship to the SIEM in stages during a live attempt — hold later evidence back until analysts have made real progress, instead of dropping every log at exercise start.

  ### New features

  * **Staged section release** — Each archive section has an optional release block with a delay (in minutes), linked artifact gates, a gate mode (`all` or `any`), and a release condition: `delay_only`, `artifacts_only`, `delay_and_artifacts`, or `delay_or_artifacts`. Sections with no rules ship immediately, exactly like before. See [Staged section release](/guides/authoring-exercises#staged-section-release) and [Section Release Rules](/concepts/exercises#section-release-rules).
  * **Section shipment status panel** — When an exercise uses staged shipping, the exercise detail page shows a per-section panel with one of five states: `not_due`, `waiting_on_artifact`, `shipping`, `shipped`, or `failed`. Sections stuck on **Waiting on artifact** spell out exactly which expected artifacts are still missing. See [Section shipment status](/guides/running-exercises#section-shipment-status).
  * **Explicit reasons from Ship logs to SIEM** — The **Ship logs to SIEM** action now returns one of eight explicit per-section reasons (`shipped`, `partial`, `already_shipped`, `not_due`, `waiting_on_artifacts`, `shipping`, `cooldown_skipped`, `failed`) so analysts and authors can tell at a glance why a section did or did not ship. See the [reason table](/guides/running-exercises#section-shipment-status).

  ### Updates

  * **Publish-time deadlock check** — Toggling an exercise to **Active** now analyses the section release plan and blocks publish in two situations: no section can release at start (the analyst would begin with no logs in their SIEM), or a section is gated by an artifact that almost certainly lives in its own logs. The timeline panel surfaces the specific issue and an **override** checkbox for intentional deadlocks; the override is persisted with the exercise. See [Publish-time deadlock check](/guides/authoring-exercises#publish-time-deadlock-check).
  * **Two documented shipping models** — Immediate vs. staged shipping are now first-class concepts in the SIEM integrations reference, including per-attempt shipment snapshots so each analyst's section state is tracked independently. See [Shipping models](/concepts/siem-integrations#shipping-models).
</Update>

<Update label="June 9, 2026" tags={["feature"]}>
  ## ECS support and format-aware archive validation

  ECS is now a first-class author-time archive format alongside LEEF, and publish-time validation knows exactly which format each enabled SIEM destination needs.

  ### New features

  * **ECS as a fully supported format** — Author exercises with ECS-formatted archives directly. ThreatLab detects ECS as JSON or NDJSON containing `@timestamp` plus at least one ECS-like field (`event.*`, `host.*`, `source.*`, `destination.*`, `log.*`, `process.*`, `user.*`, or a non-empty `message`). See [Archive formats](/concepts/exercises#archive-formats).
  * **Per-row format badges in the section editor** — Every archive row in the section editor now shows a **LEEF**, **ECS**, or **syslog/unknown** badge, and a source-aware notice spells out what your enabled SIEM destinations require. See [Authoring exercises](/guides/authoring-exercises#creating-an-exercise).
  * **SyslogCanon LEEF↔ECS pairing** — When **Convert to LEEF** is enabled, SyslogCanon produces both the LEEF and matching ECS payloads in the same publish, so a single section can ship to LEEF and ECS destinations without double-authoring. See the **Convert to LEEF** step in [Authoring exercises](/guides/authoring-exercises#creating-an-exercise).

  ### Updates

  * **Format-aware validation** — Unknown raw archives are no longer silently labelled as LEEF. Rows are classified as LEEF, ECS, or unknown, and unknown content fails closed with an actionable error telling you what to fix. See [Format-aware validation](/guides/authoring-exercises#format-aware-validation).
  * **Publish-time readiness check** — Toggling an exercise to **Active** now derives the required formats from your enabled destinations and assigned SIEM, then verifies every section has a complete archive in each required format. Errors name the SIEM destination and the format (LEEF or ECS) that is missing. See [Publishing as Active](/guides/authoring-exercises#publishing-as-active) and [Publish-time readiness](/concepts/siem-integrations#publish-time-readiness).
  * **Clearer rules for when SyslogCanon is required** — SyslogCanon now kicks in when **Convert to LEEF** is on, when an ECS row needs to reach a LEEF destination (Splunk HEC, syslog TCP), when a LEEF row needs to reach an ECS destination (Elasticsearch Bulk), or when any row is unknown. If SyslogCanon can't produce the missing side, publish is blocked with a per-SIEM, per-format error. See [When SyslogCanon is required](/concepts/siem-integrations#when-syslogcanon-is-required).
</Update>

<Update label="June 9, 2026" tags={["feature"]}>
  ## Draft autosave for exercise authoring

  Exercises now save as you work. Draft is a real working state — start with just a title, leave the editor, and come back later to keep building.

  ### New features

  * **Server-backed autosave** — The cmdbar shows live status (waiting, unsaved, saving, saved, paused, error) so you always know whether your changes are persisted. Drafts only require a title to save.
  * **Draft vs publish validation** — Drafts skip the heavier checks so you can iterate quickly. LEEF/ECS archive readiness and step-deadlock checks run at publish, and any validation errors scroll into view and focus the offending field. See [Draft vs publish validation](/guides/authoring-exercises#draft-vs-publish-validation).

  ### Updates

  * **What drafts skip** — Saving a draft does not upload archives, finalize live TCP intake, or provision SIEM indexes. Those steps run when you publish. See [Draft autosave](/guides/authoring-exercises#draft-autosave).
  * **Create exercise permission** — The **Create exercise** action is gated on the `manage_exercises` capability. See [Authoring exercises](/guides/authoring-exercises).
  * **Lifecycle clarifications** — The exercise [Draft and Active states](/concepts/exercises) now reflect autosave behaviour and link directly to the relevant authoring sections.
</Update>

<Update label="June 9, 2026" tags={["feature"]}>
  ## Per-archive index routing for noise jobs

  Noise log archives can now be shipped to their own SIEM indexes, so different traffic types stay separated inside the same destination.

  ### New features

  * **Choose an index per archive** — When creating or editing a noise job, each archive can ship to the destination's default index, an existing index already known to ThreatLab, or a brand-new index (name limit **120 characters**). The Noise Jobs table summarises the routing choice for each job at a glance.
  * **Automatic provisioning on Splunk and Elasticsearch** — ThreatLab creates any required custom indexes on save. At run time, events are grouped per archive and shipped with the right routing.
  * **LEEF `threatlabIndex=` extension** — Syslog TCP destinations receive an extra `threatlabIndex=` field on every LEEF line so downstream collectors can route the event without changing the rest of the payload.

  ### Updates

  * **Syslog TCP requires manual index setup** — ThreatLab cannot create indexes on syslog TCP targets. When a job references a custom index on a syslog TCP destination, the save toast surfaces a warning telling you exactly which index to create on the collector before the next run.
  * **Wipe propagation covers custom indexes** — With **Propagate on wipe** enabled, wiping a SIEM session also clears non-default custom indexes referenced by a job's archives on Splunk and Elasticsearch before the job re-fires, so training data stays in sync with the default index.

  See [Per-archive index routing](/guides/noise-logs#per-archive-index-routing) in the noise logs guide for the full walkthrough.
</Update>

<Update label="June 9, 2026" tags={["update"]}>
  ## Stricter SIEM shipping for sectioned exercises

  Section archives are now the single source of truth for sectioned exercises — no silent fallback to legacy bundles.

  ### Updates

  * **Section archives are authoritative** — When an exercise has section rows, every section must carry an archive in the payload format your SIEM destination expects (LEEF or ECS). ThreatLab no longer falls back to a legacy per-exercise archive or legacy exercise columns when section rows are present.
  * **Clearer shipping errors** — If any section is missing an archive in the requested format, shipping fails fast with an error that names the SIEM destination and the affected sections.
  * **Legacy fallback scoped to non-sectioned exercises** — The legacy resolution order still applies to exercises with no section rows, so older content keeps working unchanged.

  ### Bug fixes

  * **Publish-time guardrail** — Saving or publishing a staged exercise now validates section archives against every enabled SIEM destination's payload format. Incomplete archive sets are caught at save time instead of failing later at exercise start.

  See [SIEM integrations](/concepts/siem-integrations) for the full resolution order and guardrail details.
</Update>

<Update label="June 8, 2026" tags={["launch"]}>
  ## ThreatLab is live

  Welcome to the first ThreatLab release. This week we shipped the operator console for SOC training — from exercise authoring through analyst investigations to platform monitoring.

  ### New features

  * **Exercise authoring and catalog** — Create realistic investigation scenarios with ordered steps, expected artifacts, MITRE ATT\&CK tagging, and section-aware LEEF or ECS log archives. Upload archives as `.zip`, `.tar.gz`, `.tgz`, paste plain text, or stream over live TCP intake. See [Exercises](/concepts/exercises) and [Authoring exercises](/guides/authoring-exercises).
  * **Learning paths** — Sequence exercises into guided curricula with position-based unlock logic, per-analyst progress tracking, and dedicated onboarding flows. Inactive exercises are skipped automatically so analysts are never blocked. See [Learning paths](/concepts/learning-paths).
  * **Analyst workspace** — Launch exercises, submit step artifacts, and track completion streaks and leaderboard points from a single interface. Get going in five steps with the [Quickstart](/quickstart).
  * **SIEM integrations** — Ship exercise logs directly to your SIEM via Splunk HEC, syslog TCP (RFC 3164 / RFC 5424) for QRadar and others, or the Elasticsearch Bulk API. See [SIEM integrations](/concepts/siem-integrations).
  * **Noise log dispatcher** — Schedule recurring background LEEF jobs to keep your SIEM populated with realistic baseline traffic so exercise events don't stick out. See [Noise logs](/guides/noise-logs).
  * **Encrypted direct messages** — One-to-one messaging with AES-256-GCM encryption at rest, real-time delivery, and unread badges. Even administrators cannot read DM contents. See [Direct messages](/guides/direct-messages).
  * **Live platform status** — Icinga 2 host and service health is surfaced on the dashboard and a full status page, streamed in real time over SSE. See [Platform status](/guides/platform-status).
  * **Entra ID SSO** — Sign in with email and password or with your organization's Microsoft Entra ID. See the [Quickstart](/quickstart).
  * **Role-based access control** — Capability-driven roles let administrators grant exactly the permissions each user needs. See [Roles and capabilities](/concepts/roles-capabilities) and [Managing roles](/admin/roles).

  ### Administration

  * **User management** — Invite users, assign roles, and manage org membership from the admin console. See [User management](/admin/user-management).
  * **SIEM resources** — Configure and test Splunk, syslog, and Elasticsearch destinations in one place. See [SIEM resources](/admin/siem-resources).
  * **Bootstrapping** — Stand up a new instance with the documented [Bootstrapping](/admin/bootstrapping) flow.

  ### Public API

  The first version of the ThreatLab API is available. Endpoints include session start and wipe, noise job runs, platform status SSE, and health checks. See the [API overview](/api/overview) and [authentication](/api/authentication) to get started.
</Update>
