Zion Boggan
repos/detection-as-code

detection-as-code

Detection rules kept the way code is kept: written once in Sigma, version-controlled, linted and tested in CI, and compiled to whatever SIEM is in front of me. I spend my day tuning rules in Sentinel and Splunk by hand; this is that work done as a pipeline instead of a console...

5 commits First commit May 29, 2026 Last commit Jun 22, 2026 (43 minutes ago)
YAML 59.5%Python 22.8%Markdown 17.6%
Files 19 entries
README.md

Detection-as-Code

Detection rules kept the way code is kept: written once in Sigma, version-controlled, linted and tested in CI, and compiled to whatever SIEM is in front of me. I spend my day tuning rules in Sentinel and Splunk by hand; this is that work done as a pipeline instead of a console click.

Every rule here converts cleanly to Splunk SPL, Elastic ES|QL, and Microsoft Sentinel / Defender KQL, and is tagged to MITRE ATT&CK so coverage is something you can measure instead of guess at.

One Sigma rule compiled to three SIEMs

Why

A detection written in one SIEM's query language is stranded there. Writing it in Sigma once and compiling it means the same logic ships to Splunk, Elastic, and Sentinel without re-deriving it - and the rule gets reviewed, diffed, and tested like any other code. The goal is fewer false positives and provable coverage, not more dashboards.

Layout

rules/
  windows/   credential-access, execution, persistence, defense-evasion, initial-access
  linux/     credential-access, execution, persistence
tools/convert.py        compile every rule to Splunk / Elastic / Sentinel
tests/test_rules.py     schema, ATT&CK tagging, unique IDs, correlation references
.github/workflows/      lint -> test -> convert on every push
dist/                   generated queries (CI artifact; gitignored)

The rules

Ten detections across both platforms, each mapped to ATT&CK and tuned past the naive version (e.g. LSASS access filtered to the granted-access masks tooling actually uses, not the broad 0x1010). Full table in docs/coverage.md.

Technique Detection Platform
T1003.001 Suspicious LSASS process access Windows
T1059.001 PowerShell EncodedCommand Windows
T1566 / T1059.001 Office spawns scripting host / LOLBin Windows
T1218.011 Suspicious rundll32 Windows
T1543.003 New service installed Windows
T1053.005 Scheduled task created Windows
T1110 SSH brute force (correlation) Linux
T1059.004 Reverse shell one-liner Linux
T1543.002 Systemd persistence Linux

Use it

pip install -r requirements.txt
sigma check rules/            # lint
pytest -q                     # schema + ATT&CK validation
python tools/convert.py       # compile to dist/{splunk,esql,kusto}/

Convert a single rule on the fly:

sigma convert -t splunk -p sysmon rules/windows/credential-access/T1003.001_lsass_memory_access.yml
sigma convert -t kusto  -p sysmon rules/windows/credential-access/T1003.001_lsass_memory_access.yml

convert.py picks the right processing pipeline per rule from its logsource (Sysmon for process/file telemetry, Windows-audit for Security/System channels). Correlation rules like the SSH brute force are compiled together with the base rule they reference - make correlations does that, since they need their referenced rule in the same collection.

Validation

CI lints with sigma check, runs the schema/ATT&CK test suite, and compiles all rules to the three backends, failing on any conversion error. The rules themselves are validated behaviourally in the companion purple-team lab - Atomic Red Team fires each technique and the matching detection is confirmed in the Wazuh SIEM before a rule is promoted here. The Wazuh-native versions of several of these live in the SOC automation lab.