# wazuh-ai-triage

Companion files for the lesson **AI-Assisted Triage for Wazuh Findings**.

Lesson: https://maheshtata.com/wazuh/wazuh-ai-triage/

Tested against: Wazuh 5.0 (beta5 documentation, September 2026), Ubuntu 24.04.
Wazuh 5.0 had not reached general availability when these files were written.

These are **skeletons**, not a drop-in product. They encode the shape of a safe
triage layer: a fixed context envelope, a schema the model must fill, and a set of
checks that run in your automation platform rather than in the prompt. Nothing here
is captured model output, and no example finding in these files is real data.

## Files

| File | What it is |
|---|---|
| `context-envelope.template.json` | The package assembled for each finding, after enrichment and before the model call. Every value is a `<PLACEHOLDER>`. Field names under `finding` are Wazuh Common Schema names from the 5.0-beta documentation. |
| `triage-system-prompt.md` | A system prompt skeleton, the user-message shape that keeps event data separated from instruction, and the platform-side checks that run on the response. |
| `verdict.schema.json` | JSON Schema for the only response the model is allowed to return. Validate every response against it; discard anything that fails. |

## Where this sits

```
detector -> finding -> Alerting monitor -> Notifications webhook channel
                                                  |
                                         automation platform
                                                  |
                            1. enrich (asset, history, prior decisions)
                            2. assemble context-envelope.template.json
                            3. call the model with triage-system-prompt.md
                            4. validate against verdict.schema.json
                            5. apply policy, act, attach everything to the case
```

The model is a classifier with an explanation. The platform holds the credentials and
makes the changes, based on a policy you wrote, applied to a verdict the model proposed.

## Non-negotiables encoded in these files

- Nothing at **high or critical** severity is closed by this pipeline. There is no
  confidence threshold that unlocks it.
- No proposed action touches an endpoint. Active response in Wazuh 5.x runs through an
  Alerting monitor writing to the `wazuh-active-responses` data stream, and that path
  stays free of model output.
- Every field originating from an event, `event.original` above all, is treated as
  adversarial input and delivered inside a delimited data block.
- A verdict with no field-backed evidence is rejected before a human sees it.
- `insufficient_context` is a valid, cheap answer. Without it the model guesses.

## Before you start

Tune the deployment first. A triage layer placed on top of an untuned queue hides the
problem instead of solving it, and makes the noise more expensive. See
https://maheshtata.com/wazuh/wazuh-false-positives/

Then run in shadow mode: produce verdicts, attach them to cases, let analysts work as
before. Two or three weeks of that gives you a labelled set to measure against at no
risk.

## Data governance

Findings carry hostnames, usernames, IP addresses, file paths and raw log text. Decide
what may leave your deployment before you send anything. Wazuh 5.0's own dashboard AI
Assistant supports a field policy that anonymises or excludes named fields before data
reaches a provider, and a privacy mode that can be enforced across the cluster; apply
an equivalent filter to whatever you build here.

## Sources

- https://documentation.wazuh.com/5.0-beta/user-manual/wazuh-dashboard/wazuh-dashboard-configurations.html
- https://documentation.wazuh.com/5.0-beta/user-manual/wazuh-indexer/modules/alerting.html
- https://documentation.wazuh.com/5.0-beta/user-manual/data-analysis/findings.html
