SOC Automation Lab
An end-to-end SOC lab: Wazuh fires the alert, Shuffle enriches it, TheHive gets a pre-populated case. Hands off from rule match to analyst notification.

An end-to-end SOC lab: Wazuh fires the alert, Shuffle enriches it, TheHive gets a pre-populated case. Hands off from rule match to analyst notification.

Three things happened by hand on every alert: pull reputation data on the indicator, open a case in TheHive, ping the analyst channel. Doing that for every level-10-and-above rule match in a lab is tedious and slow; doing it in a real environment at volume is not sustainable. The playbook does all of it in the few seconds between Wazuh firing and an analyst opening TheHive.
The pipeline: telemetry from Windows and Linux endpoints reaches the Wazuh manager via agent. When a rule match clears the severity threshold, a Python integration posts the alert to a Shuffle webhook. Shuffle pulls VirusTotal and OTX reputation on the offending indicator, opens a TheHive case with the verdict attached, sets severity from the score, and drops a message in the analyst channel. Everything after the rule match is hands-off.
def build_payload(alert):
rule = alert.get("rule", {})
agent = alert.get("agent", {})
data = alert.get("data", {})
return {
"source": "wazuh",
"rule_id": rule.get("id"),
"rule_level": rule.get("level"),
"rule_description": rule.get("description"),
"mitre": rule.get("mitre", {}),
"agent_id": agent.get("id"),
"agent_name": agent.get("name"),
"agent_ip": agent.get("ip"),
"src_ip": data.get("srcip"),
"dst_ip": data.get("dstip"),
"full_log": alert.get("full_log"),
"timestamp": alert.get("timestamp"),
"raw": alert,
}
def post(hook_url, payload):
body = json.dumps(payload).encode("utf-8")
req = request.Request(
hook_url,
data=body,
headers={"Content-Type": "application/json"},
method="POST",
)
with request.urlopen(req, timeout=TIMEOUT) as response:
return response.status
The custom rules in local_rules.xml add detections on top of the Wazuh default ruleset for the cases I wanted automated:
AppData, Temp, ProgramData) via Sysmon Event ID 1cmd, powershell, wscript, mshta)Rules at level 10 and above hand off to the Shuffle integration. Everything below stays in the dashboard.

The full stack (Wazuh indexer, manager, dashboard, TheHive, Cassandra, Elasticsearch, and Cortex) comes up with ./scripts/deploy.sh after setting the indexer and TheHive passwords in .env. Shuffle runs as a separate compose stack so it survives a SIEM teardown.
Endpoints enroll via agent scripts for Windows and Linux. The Windows group ships a Sysmon-aware config so process-creation and network events arrive with enough context for the custom rules to be useful. This is a single-node lab build; Wazuh indexer and TheHive's Cassandra both want dedicated nodes and real headroom under production load.