Tools Used in DevSecOps · Wazuh

Wazuh

Wazuh is a free, Apache-2.0-licensed SIEM and XDR platform: a small agent runs on every host you care about, a central manager decodes and correlates whatever that agent ships back, and the result lands in a search-and-dashboard layer built on OpenSearch. It began life in 2015 as a fork of OSSEC — the host-based intrusion detection system Daniel Cid started in 2004, later acquired by Trend Micro — built by a team led by Santiago Bassett who wanted OSSEC's detection engine paired with a REST API, a real UI, and active development, without waiting on a vendor's roadmap. By the end of this page you should be able to explain what each of Wazuh's four components actually does, read and write a decoder and a correlation rule in its native XML, configure file-integrity monitoring with and without whodata, wire up an automated active response, and say precisely what you're trading away by running Wazuh instead of writing a check to Splunk or Microsoft Sentinel.

☺ Explain it like I'm 10

Picture a school with one hall monitor stationed by every single classroom door, each one radioing back to a principal's office the instant something worth noting happens — a door propped open, the same kid trying three different lockers. The principal doesn't personally watch four hundred doors; the monitors are Wazuh's agents, the principal's office is the manager deciding what each radio call actually means and how loud to make the alarm, and the filing cabinet where every report gets logged for later is the indexer and dashboard. The whole system is free to build yourself, rather than hiring an outside security firm to do the same job.

🦊Your host for this topic: Foxy — she's the one who goes back through the logs after something's already happened to find out what actually occurred, and Wazuh is where most of the logs she digs through actually live.

What Wazuh is, and the problem it solves

☺ Like you're 10: it's one small watcher installed on every machine, reporting to one central brain that decides what's normal and what isn't — and none of it costs anything to run.

Precisely, Wazuh is three things bundled around one shared agent: a host-based intrusion detection system (HIDS) doing log analysis, file-integrity monitoring, and rootkit detection; a security configuration assessment (SCA) engine running CIS-benchmark-style policy checks; and a SIEM/XDR layer correlating everything across a fleet into one searchable, dashboarded stream. That breadth is also why it shows up by name in Detection Engineering & Security Observability as the concrete, self-hosted walkthrough of that page's six-stage collect-normalize-enrich-correlate-alert pipeline — this page is that walkthrough, one tool deep.

The gap it fills is specifically the one a smaller team feels first: commercial SIEMs price on ingestion volume or host count, which turns "watch everything" into a budget conversation before it's ever a technical one. Wazuh's entire stack — agent, manager, indexer, dashboard — is open source under Apache 2.0, with no feature gated behind a paid tier. That's a deliberate, structural difference from Elastic Security, whose underlying Elastic Stack moved to the Server Side Public License in 2021 — the same license change that pushed AWS to fork Elasticsearch and Kibana into OpenSearch and OpenSearch Dashboards, which is exactly what Wazuh's own indexer and dashboard are built on today. Confirm current licensing terms against each project's own page before treating any of this as legal advice; licenses change, and this course isn't the authority on them.

What it's deliberately not, worth stating plainly before the rest of this page goes deep: it's not a network IDS/IPS like Suricata or Snort, though it can ingest and correlate their alerts as just another log source. It's not primarily a kernel-level runtime sensor the way Falco is — Falco watches syscalls inside a running container in real time with microsecond granularity; Wazuh watches an entire fleet's logs, file changes, and configuration drift with a coarser but much broader lens, and the two pair naturally rather than compete (see Container Runtime Security for where that boundary sits). And it's not a full SOAR platform — active response, covered later on this page, automates a specific scripted reaction to a specific rule match, which is a meaningfully smaller job than orchestrating a multi-step incident playbook.

◆ Key idea

Wazuh's whole pitch compresses to one sentence: the detection-engineering discipline this course argues for — decoders and rules as reviewable code, correlation instead of single-event noise, a documented severity scale — running on a stack a team can stand up on its own infrastructure, in an afternoon, without a purchase order. What you give up for that is covered honestly in this page's last section, not glossed over.

Architecture: agent, manager, indexer, dashboard

☺ Like you're 10: four separate jobs, each done by a separate piece — one to watch, one to decide, one to store, and one to show a human what was found.

Four components, and every one of them is a separate, independently scalable piece of software. The agent is a lightweight process installed on each monitored host, running several sub-modules at once: logcollector tails log files and Windows Event Channels, syscheckd does file-integrity monitoring, the SCA module runs its policy checks, and a set of wodles (Wazuh modules) handle everything from Docker container inspection to pulling AWS CloudTrail or Azure activity logs directly — that last capability means cloud audit trails don't need a per-resource agent at all, just a wodle configured on the manager or on one collector host with the right credentials. The manager receives everything over an encrypted channel on port 1514, and inside it analysisd does the actual work covered in the next two sections: decoding raw events into structured fields, then evaluating them against the loaded ruleset. The Wazuh indexer, built on OpenSearch, is where Filebeat ships every alert the manager produces, and the Wazuh dashboard — OpenSearch Dashboards under Wazuh's own branding — is where a human actually looks. A fifth piece, the Wazuh API, listens on port 55000 for RESTful management calls the dashboard itself uses, and that any script or pipeline can call directly.

Agent logcollector syscheckd (FIM) SCA module wodles (cloud/docker) one per host 1514, encrypted Manager: analysisd Decoders normalize: raw line → fields Rules correlate, if_sid chaining, assign level 0–15 active response (scripted, local) Wazuh API — :55000 dashboard + scripts, JWT auth Filebeat Wazuh indexer built on OpenSearch stores every alert Wazuh dashboard a human looks here Every arrow is a separately scalable hop — a manager cluster and an indexer cluster grow independently of each other.

For a quick evaluation or a single-team footprint, Wazuh's own wazuh-install.sh -a quickstart script puts all four components on one host in under fifteen minutes — a genuinely fast way to see the whole pipeline work end to end. Production sizing is a different conversation: the indexer specifically wants an odd-numbered cluster of three or more nodes for the same quorum reasons any OpenSearch or Elasticsearch deployment does, and the manager can run as a cluster of its own (one master, several workers, coordinated by a shared cluster key) once agent count outgrows a single box's ingest capacity. Treat the all-in-one script as a lab and evaluation path, not a production topology, once real host counts and retention requirements enter the picture.

The agent-based host visibility model

☺ Like you're 10: every watched machine gets its own name tag and its own key before it's allowed to radio anything back to the principal's office.

Agents install from a per-OS package — .deb, .rpm, .msi, .pkg, or an APK for a handful of network appliances — and each one needs exactly two things before it's useful: a unique key shared with the manager, and an ossec.conf pointing at that manager's address. The key exchange happens through authd, a manager-side enrollment service on port 1515: an agent requests registration, authd issues a unique key, and both sides now share a secret neither had to be typed in by hand. The dashboard's enrollment wizard, and the legacy manage_agents CLI covered later on this page, both wrap that same underlying exchange.

# /var/ossec/etc/ossec.conf — the agent side. Same filename as the manager's own
# config, a holdover from this project's OSSEC lineage.
<client>
  <server>
    <address>wazuh-manager.acme.internal</address>
    <port>1514</port>
    <protocol>tcp</protocol>
  </server>
  <enrollment>
    <enabled>yes</enabled>
    <manager_address>wazuh-manager.acme.internal</manager_address>
  </enrollment>
</client>

Agents are organized into groups so a fleet doesn't need per-host configuration — a group carries a shared agent.conf the manager pushes down, covering which log paths to watch, which directories syscheck should cover, and which SCA policies apply, so "every web server gets this FIM scope" is one file, not four hundred. Each agent reports one of a small set of connection states — active, disconnected (missed its last keepalive), pending (registered, never yet connected), or never connected — visible in the dashboard's Agents view or via a GET /agents?status=disconnected call against the API, and a disconnected agent is itself worth alerting on: silence from a host that should be reporting is exactly the kind of signal a tamper attempt would produce.

Not everything can run an agent. For network gear, some appliances, and other devices where installing one isn't an option, Wazuh offers an agentless mode that polls a target over SSH on a schedule rather than receiving a continuous push — lower fidelity, no real-time FIM or syscall visibility, but still better than no coverage at all. In practice, most teams reach for syslog forwarding into a Wazuh localfile collector on the manager for that same class of device today, and treat true agentless SSH polling as the fallback for the handful of targets that don't even support forwarding.

Log collection and the decoder pipeline

☺ Like you're 10: before any rule can decide "this is suspicious," something first has to turn a messy line of text into a set of labeled boxes — that's the decoder's whole job.

A raw log line is just text — Failed password for admin from 203.0.113.9 port 51558 ssh2 — and a rule can't meaningfully match against unstructured text at scale. Decoders are what turn that line into fields a rule can actually reference. A pre-decoder runs first and strips off the common syslog-style envelope — timestamp, hostname, program name — that most log formats share, and then a specific decoder, selected by matching that program name, extracts whatever's left using a regex with named capture groups.

# Modeled closely on Wazuh's own bundled sshd decoder — exact regex and field
# names shift release to release; check ruleset/decoders/0025-sshd_decoders.xml
# in your installed version for the current wording.
<decoder name="sshd">
  <prematch>^sshd\[</prematch>
</decoder>

<decoder name="sshd-failed">
  <parent>sshd</parent>
  <regex>^Failed \S+ for (\S+) from (\S+) port </regex>
  <order>srcuser, srcip</order>
</decoder>

Notice the <parent> reference: decoders chain, so a broad decoder identifies "this is an sshd line" and a narrower child decoder handles one specific message shape within it, extracting srcuser and srcip as named fields any rule downstream can now reference directly instead of re-parsing the raw string itself. Base decoders ship read-only with the product; a custom decoder for an application's own log format goes in a local decoder file the manager loads after the base set, the same append-don't-fork pattern Falco's rules use for its own extension mechanism. On the agent side, logcollector is configured with <localfile> blocks naming which paths, Windows Event Channels, or command outputs to tail — decoding itself always happens on the manager, not the agent, which keeps every agent lightweight and keeps the ruleset centrally auditable in one place.

Rules: the correlation engine

☺ Like you're 10: one rule says "this one thing happening is worth a five out of sixteen." A second rule says "but eight of those in two minutes from the same place is worth a ten" — and that second rule is the one that actually catches a real attack instead of one lucky guess.

A Wazuh rule is an XML block with an id, a severity level from 0 (ignored entirely) through 15, a match condition, and a description. The match condition can reference decoded fields directly, or — critically — reference another rule's ID via <if_sid> or <if_matched_sid>, which is how a low-severity single-event rule becomes the building block for a higher-severity composite one, exactly the "count and combine" mechanic Detection Engineering & Security Observability already introduced as Sigma's correlation block's XML-native cousin.

# Modeled closely on Wazuh's own bundled sshd rules — exact IDs shift release
# to release; check ruleset/rules/0095-sshd_rules.xml in your installed version.
<rule id="5710" level="5">
  <decoded_as>sshd-failed</decoded_as>
  <description>sshd: authentication failed.</description>
  <mitre>
    <id>T1110</id>
  </mitre>
  <group>authentication_failed,</group>
</rule>

# custom rule — local IDs must start at 100000+, reserved so a future
# upstream release never collides with a rule ID you already picked
<rule id="100100" level="10" frequency="8" timeframe="120">
  <if_matched_sid>5710</if_matched_sid>
  <same_source_ip />
  <description>Multiple failed SSH logins from the same source — possible brute force.</description>
  <mitre>
    <id>T1110</id>
  </mitre>
  <group>authentication_failures,pci_dss_11.4,</group>
</rule>

Read the composite rule as a sentence: fire at level 10 when rule 5710 matches at least 8 times within a 120-second window, grouped by the same source IP. That's a single failed login, level 5, background noise — versus eight in two minutes from one address, level 10, an active brute-force attempt worth paging on. The <mitre> block tags the rule with an ATT&CK technique ID, which is exactly the hook that lets an ATT&CK Navigator layer, built the way that same detection-engineering page describes, mark this specific cell "tested" rather than merely "a data source exists." Before any custom rule reaches production, wazuh-logtest — an interactive CLI at /var/ossec/bin/wazuh-logtest — lets you feed it a raw log line and watch the decoder and rule pipeline evaluate it live, without waiting for a real event or restarting the manager, the same fast local-feedback-loop discipline this course argues for everywhere else.

⚠ Stay above 100000

Local rule and decoder IDs must start at 100000 — Wazuh reserves everything below that for its own bundled ruleset. Pick an ID under that line and a future Wazuh upgrade that happens to ship a new rule at the same number will silently shadow or conflict with yours the moment you update. It costs nothing to start your team's local rules at 100000 and keep a shared spreadsheet of what's taken; it costs a confusing outage to find out the hard way during an upgrade.

File integrity monitoring: syscheck and whodata

☺ Like you're 10: a smoke detector that only checks the kitchen once a day is fine for a slow-burning problem. One wired to notice the instant smoke appears — and to say whose cigarette it was — is a completely different level of useful.

The syscheck module hashes every file in a configured set of directories, stores that baseline, and reports whenever a file's checksum, permissions, ownership, or size changes. Two very different operating modes hide behind that one description. The default is a scheduled scan, walking the whole configured tree on an interval (12 hours by default, historically) — cheap, but a change made and reverted between scans is invisible, and even a real change waits up to that interval before anyone's told. Real-time mode (realtime="yes") instead hooks the OS's own file-change notification API — inotify on Linux, ReadDirectoryChangesW on Windows — so a change is reported within seconds, at the cost of a small continuous overhead on whatever directory it's watching.

# /var/ossec/etc/ossec.conf — agent side
<syscheck>
  <directories check_all="yes" report_changes="yes" realtime="yes" whodata="yes">/etc,/usr/bin,/usr/sbin</directories>
  <directories check_all="yes">/home</directories>
  <!-- registry monitoring is Windows-only, and uses the same whodata attribution -->
  <windows_registry check_all="yes">HKEY_LOCAL_MACHINE\Software\Classes\batfile</windows_registry>
</syscheck>

The third layer, whodata, is what separates "a file changed" from "a file changed, and here's exactly who did it." Enabling it on Linux has Wazuh automatically add rules to the kernel's audit subsystem (auditd) for the watched paths; on Windows it configures the equivalent SACL entries and reads Event ID 4663. Either way, the resulting alert carries the process name, the user, and the parent process behind the change — not just what changed, but who changed it and how, which is precisely the attribution a scheduled hash-only scan can never provide. report_changes="yes" adds one more layer for text files specifically: a stored diff of the actual content change, not just a hash mismatch.

⚠ Watch out — whodata is not free

whodata's audit-subsystem hook adds real CPU and log volume, and it scales with how busy the watched path is — a build server's temp directory or an application's own log folder can generate enough audit events to noticeably load the host and flood the manager with low-value noise. Scope whodata narrowly to paths where attribution genuinely matters — /etc, binary directories, credential stores — and leave check_all without it on paths you merely want hash coverage for. Watching everything with whodata "just to be safe" is how a FIM rollout gets blamed for a performance regression and quietly disabled everywhere, including the one path that actually needed it.

Active response, SCA, and the vulnerability detection module

☺ Like you're 10: three more jobs bolted onto the same agent — one that reacts automatically, one that checks against a known-good checklist, and one that watches for software everyone forgot to patch.

Active response is Wazuh's built-in, narrowly scoped automation layer: a manager-side block ties a script to a rule ID, and the moment that rule fires, the script runs on the named agent (or every agent) — blocking an IP with firewall-drop, disabling an account, or a custom script a team writes itself. It's a smaller, more targeted tool than a full SOAR playbook, and it's worth thinking of as the same category of automated reaction Falco Talon provides at the kernel level, just triggered off a correlated log-and-FIM rule instead of a live syscall.

# /var/ossec/etc/ossec.conf — manager side
<command>
  <name>firewall-drop</name>
  <executable>firewall-drop</executable>
  <timeout_allowed>yes</timeout_allowed>
</command>

<active-response>
  <command>firewall-drop</command>
  <location>local</location>
  <rules_id>100100</rules_id>
  <timeout>600</timeout>
</active-response>

That block wires the brute-force composite rule from the previous section straight into an automatic ten-minute IP block, with the same active-response mechanism automatically reversing the block once the timeout expires — no standing firewall rule left behind for someone to forget about six months later.

The SCA module runs YAML-defined policy checks against a host's actual configuration — file permissions, running services, kernel parameters — modeled on CIS Benchmark language, and reports a pass/fail per rule the same way OpenSCAP or InSpec do. It's genuinely lighter-weight than either — bundled into the same agent already running FIM and log collection, continuously rather than run as a separate scheduled audit job — but it's also less deep: a dedicated compliance-audit tool with a purpose-built profile format and a mature datastream ecosystem, the way OpenSCAP's SCAP profiles are, still earns its place for a formal, evidence-grade compliance attestation. Treat Wazuh's SCA as continuous configuration drift detection, and reach for OpenSCAP or InSpec when the deliverable is a signed audit report.

The vulnerability detection module closes the loop between "what's installed" and "what's known-bad": a syscollector wodle inventories every package on every agent, and the manager correlates that inventory against CVE feeds — the NVD, and OS-vendor-specific feeds for a more precise match than NVD's own CPE matching alone typically provides. A host running a package with a known CVE shows up as a finding in the dashboard without a separate scanner ever touching that host. See vulnerability management & triage for how that finding gets triaged and deduplicated alongside everything Trivy, Snyk, and DefectDojo already report from earlier in the pipeline — Wazuh's module is the one piece of that picture watching what's actually installed on a running host, after everything upstream already shipped.

Day-to-day commands

☺ Like you're 10: a handful of commands cover almost everything — check it's running, test a rule before it ships, and ask the API a question instead of clicking through the dashboard.

# service control — same binary name on manager and agent
$ /var/ossec/bin/wazuh-control status
$ /var/ossec/bin/wazuh-control restart      # required after editing rules, decoders, or ossec.conf

# interactive decoder + rule testing — feed it one raw log line, watch the full pipeline evaluate it
$ /var/ossec/bin/wazuh-logtest

# legacy agent management — add, remove, and extract a key by hand
$ /var/ossec/bin/manage_agents

# tail alerts as they're written, before Filebeat ever ships them
$ tail -f /var/ossec/logs/alerts/alerts.json | jq .

# the Wazuh API — authenticate, then ask a real question
$ TOKEN=$(curl -s -u wazuh-wui:'CHANGE_ME' -k \
    -X POST "https://wazuh-manager:55000/security/user/authenticate?raw=true")
$ curl -s -k -H "Authorization: Bearer $TOKEN" \
    "https://wazuh-manager:55000/agents?status=disconnected&pretty=true"
$ curl -s -k -H "Authorization: Bearer $TOKEN" -X PUT \
    "https://wazuh-manager:55000/agents/group?group_id=webservers" \
    -d '{"agents_list":["003","004"]}' -H "Content-Type: application/json"

The reflex worth building early: never push a new rule or decoder file straight to a production manager restart. Run it through wazuh-logtest against a representative sample of real log lines first — including ones that shouldn't match — the same "prove it before it can page anyone" discipline the detection-engineering page argues for with Sigma's shadow-mode deploy stage.

Gotchas and failure modes

☺ Like you're 10: most surprises trace back to one of three things — a broken rule file, an agent older or newer than it should be, or a disk that quietly filled up.

🦊 Foxy's view

"I don't care how clever a rule looks in the XML — I care whether I can pull up the exact decoded fields, the exact rule ID, and the exact timestamp six months later when someone asks 'how do you know that's what happened.' A SIEM that can't answer that under pressure isn't a SIEM, it's a very expensive log file. Wazuh earns its keep the day I need that answer, not the day the dashboard looks nice."

Wazuh vs. Splunk, Elastic Security, Microsoft Sentinel, and Graylog

☺ Like you're 10: every alternative trades Wazuh's "free, self-hosted, host-agent-first" position for something specific — a bigger app ecosystem, a managed cloud service, or a smaller footprint focused purely on logs.

PlatformModelStrengthTrade-off
WazuhSelf-hosted, Apache-2.0, agent-first (log analysis + FIM + SCA + vuln detection in one agent)No ingestion-volume bill, no gated feature tier, deep host-level visibility out of the boxYou operate and scale the indexer and manager yourself; smaller third-party app/integration ecosystem than Splunk's
SplunkCommercial, priced on ingestion volume or by workloadBest-in-class search language (SPL) and dashboarding; enormous app and integration marketplaceCost scales directly with log volume, which is exactly the constraint that makes teams start dropping sources to save money
Elastic SecurityOpen core on the Elastic Stack; free and paid subscription tiersSame stack lineage Wazuh's own indexer forked from, tight Elastic Agent/Fleet integration, mature detection-rule toolingMeaningful detection and case-management features sit behind paid subscription tiers, not the free basic license
Microsoft SentinelCloud-native SaaS SIEM on Azure, consumption-based pricingZero infrastructure to operate yourself; deep native integration with Microsoft 365 and Azure signal sources; KQL is a capable query languageConsumption billing again ties cost directly to log volume, and it's the natural fit specifically for a Microsoft-centric estate
GraylogOpen-source log management and analysis, open core with a paid Enterprise tierSimple, purely log-centric mental model; lighter to operate than a full SIEM stackNo built-in host agent, FIM, or SCA the way Wazuh ships natively — it's a narrower tool doing one job well, not a HIDS-plus-SIEM bundle

The practical rule of thumb this page keeps coming back to: reach for Wazuh specifically when the requirement is genuine host-level visibility — log correlation, FIM, configuration drift, installed-package vulnerability tracking — bundled for free, self-hosted, without a data-volume invoice attached. Reach for Splunk or Sentinel when budget genuinely supports their bigger analytics ecosystems and app marketplaces, or when the organization is already deep enough into one cloud's own tooling that the native integration outweighs the licensing cost. A smaller team standing up its first real detection-engineering practice, the way Detection Engineering & Security Observability describes it, gets the entire workflow — decoders, correlation rules, MITRE-tagged findings, a dashboard a Tier 1 analyst can actually use — without a purchase order standing between them and turning it on.

🎬 At the Shift-Left Squad
🦊

Foxy: 2am login on the build box, admin account, source IP I don't recognize. Pulling the Wazuh alert now.

🐢

Timmy the Turtle: Did active response already do anything, or are we starting from zero?

🦊

Foxy: Eight failed passwords in ninety seconds, then a success — the composite rule fired, and firewall-drop already blocked the source IP for ten minutes. But the successful login happened before the block landed, so I still need to know what that session actually did.

🐘

Ellie the Elephant: I'm looking at the FIM diff on that box right now — a config file in /etc changed four minutes after that login, and the whodata attribution says the same account added a plaintext API key to it.

🦊

Foxy: That's the actual damage, then — not the login itself. Rotate that key before we do anything else.

🐿️

Nutty the Squirrel: While you're in there — rule ID, timestamp, the exact diff, all of it. I'm archiving this one with a date on it, because "we caught it" only counts as evidence if I can produce the alert that proves when.

🦉

Professor Owl: And that's the whole theory made concrete — decoders normalized the log, a correlation rule caught the pattern, FIM caught the aftermath, and active response bought Foxy ten minutes before the attacker could do more. None of it needed a vendor's invoice to exist.

✓ Checkpoint

1. Name Wazuh's four core components and state the one job each one does. 2. What's the difference between a decoder and a rule, and why does decoding always happen on the manager rather than the agent? 3. Walk through the brute-force rule example: what do if_matched_sid, frequency, and timeframe each contribute, and why is the composite rule's level higher than the base rule's? 4. What does whodata add on top of a plain check_all FIM scan, and name one concrete operational cost of turning it on broadly. 5. What does an active-response block actually automate, and how is that different from a full SOAR playbook? 6. Why must a local rule or decoder ID be 100000 or higher? 7. Name one thing Wazuh trades away against Splunk or Microsoft Sentinel, and one thing it trades away against Elastic Security specifically.

Check your answers
  1. The agent collects (logs, FIM, SCA, wodles) on each monitored host; the manager decodes and correlates everything it receives via analysisd; the indexer (built on OpenSearch) stores every resulting alert; the dashboard (OpenSearch Dashboards) is where a human actually views and searches them.
  2. A decoder turns an unstructured raw log line into structured, named fields (normalization); a rule evaluates those already-decoded fields against a match condition to decide whether — and how severely — to alert (correlation). Decoding happens on the manager so every agent stays lightweight and so the entire ruleset is centrally maintained and auditable in one place, rather than duplicated and potentially drifting across every host.
  3. if_matched_sid chains the composite rule to the base rule (5710, a single failed login) so it only evaluates matches of that specific rule; frequency="8" requires at least eight such matches; timeframe="120" requires them within a 120-second window, grouped by source IP via same_source_ip. The composite rule's level (10) is higher than the base rule's (5) because eight failed logins from one source in two minutes is a meaningfully stronger signal of an actual attack than any single failed login on its own.
  4. whodata adds attribution — the specific process, user, and parent process behind a file change — on top of the bare fact that a checksum changed, by hooking the OS's audit subsystem (Linux auditd) or SACL/Event ID 4663 (Windows). The concrete cost: it adds real CPU and log volume that scales with how busy the watched path is, so enabling it broadly on a write-heavy directory can noticeably load the host and flood the manager with low-value events.
  5. It ties a specific script to a specific rule ID so that script runs automatically on the named agent(s) the moment that rule fires — for example, blocking a source IP for a set timeout. That's a narrow, single-triggered scripted reaction, meaningfully smaller in scope than a SOAR platform's multi-step orchestrated playbook spanning several systems and decision points.
  6. Wazuh reserves every ID below 100000 for its own bundled ruleset. A local rule or decoder using an ID under that line risks a future Wazuh upgrade shipping a new base rule at the exact same number, silently shadowing or conflicting with the custom one the moment the upgrade lands.
  7. Against Splunk or Sentinel: Wazuh trades away their bigger analytics ecosystem, app marketplace, and (for Sentinel) zero-infrastructure managed operation, in exchange for no ingestion-volume bill and full control of the stack. Against Elastic Security specifically: Wazuh trades away Elastic's more mature paid-tier detection and case-management tooling in exchange for keeping every feature open source under Apache 2.0 with nothing gated behind a subscription.

Wazuh is the concrete answer to "how does a team actually run detection engineering without buying a SIEM" — see Detection Engineering & Security Observability for the Sigma, ATT&CK, and testing theory this page's rules and decoders put into practice, Incident Response & Forensics for what Foxy does with a Wazuh alert once it fires, and Compliance & Governance for how its SCA and FIM evidence feeds an audit trail. For the pieces this page deliberately left to their own dedicated coverage, see Falco for kernel-level runtime detection inside a container, OpenSCAP and InSpec for formal compliance auditing, and Vulnerability Management & Triage for what happens to a finding after Wazuh's vulnerability detection module surfaces it. Back on the tool landscape, Wazuh is the course's one dedicated SIEM entry — the aggregation layer every other tool on that page ultimately feeds.