Skip to main content

SigmaWarden

A linter for Sigma detection rules. Points sigmawarden lint at a folder and it flags the mistakes that don't show up until someone actually tries to deploy the rule — a logsource that doesn't match anything real, a condition referencing a selection you renamed and forgot to update, a falsepositives field nobody filled in, an ATT&CK technique tag with a digit transposed.

I built this after the third time I shipped a rule to my own detections page with an empty falsepositives list, because I'd written the detection logic, felt done, and closed the file. None of those mistakes break the YAML. They just mean the rule looks finished and isn't.

Install

pip install sigmawarden

Or from source:

git clone https://github.com/zephryxsec/SigmaWarden
cd SigmaWarden
pip install -e .

Python 3.9+, one runtime dependency (PyYAML). No network calls at lint time — the ATT&CK technique list and the logsource reference are both bundled.

Usage

sigmawarden lint ./rules
rules/dcsync.yml
  warning SW011  missing 'falsepositives'

rules/kerberoasting.yml
  error   SW010  condition 'selction and not 1 of filter_*' references 'selction', which isn't defined in 'detection'

rules/golden-ticket.yml
  warning SW016  tag 'attack.t1003.099' — T1003.099 isn't a current ATT&CK technique ID (typo, or it's been deprecated/revoked since this reference was last updated)

3 rule(s) across 3 file(s) — 1 error(s), 2 warning(s), 0 info

Exit code is 1 if anything at error severity turned up, 0 otherwise. Point it at a single file instead of a directory if that's all you want checked.

sigmawarden lint ./rules --strict            # also fail on warnings
sigmawarden lint ./rules --format json        # for CI / other tooling to consume
sigmawarden lint ./rules --ignore SW011,SW016 # skip specific checks
sigmawarden lint ./rules --min-severity error # only show what would fail --strict... plus this
sigmawarden new-id                            # print a fresh UUID for a rule's `id:` field

Custom taxonomy — internal log sources, a vendor product not in the bundled reference — won't trip false positives forever. Point --extra-logsource at a JSON file shaped like sigmawarden/data/logsource_reference.json (only the keys you need) and it's merged in.

Checks

Code Severity What it means
SW001 error missing title
SW002 error missing id
SW003 warning id isn't a UUID
SW004 error logsource missing, or none of product/category/service set
SW005 warning logsource.product isn't recognized
SW006 warning logsource.category isn't recognized
SW007 info logsource.service isn't recognized for that product
SW008 error detection missing or empty
SW009 error detection has no condition
SW010 error condition references a selection that isn't defined
SW011 warning falsepositives missing or empty
SW012 info falsepositives is just Unknown
SW013 warning level isn't one of Sigma's five values
SW014 warning status isn't one of Sigma's five values
SW015 error an attack.tXXXX tag is malformed
SW016 warning an attack.tXXXX tag isn't a known technique ID
SW017 error two rules in the scanned set share an id
SW018 error a correlation rule's correlation.rules is missing or empty

Correlation-type rules (a correlation: block instead of detection:) are recognized and skip the logsource/detection checks — they're a different Sigma object, not a malformed regular rule. Aggregation expressions after a | in a condition (selection | count() by field > 5) are parsed as what they are, not as undefined selections.

CI

- name: Lint Sigma rules
  run: |
    pip install sigmawarden
    sigmawarden lint ./rules --strict

On the bundled reference data

sigmawarden/data/attack_techniques.json is extracted from MITRE's attack-stix-data (Enterprise ATT&CK, revoked/deprecated techniques excluded) — regenerate it with python scripts/update_attack_data.py when a new ATT&CK release adds or retires techniques. sigmawarden/data/logsource_reference.json is curated from the SigmaHQ rule corpus, not a formal spec — logsource is an intentionally open taxonomy, so SW005–SW007 are warnings, not errors, and --extra-logsource exists for exactly this reason.

Contributing

Issues and PRs welcome. If you're adding a check, keep it in checks.py as an independent function that yields Findings — no shared state with the others — and add a fixture under tests/fixtures/ that would trip it.

License

MIT — see LICENSE.

Metadata

Release files for sigmawarden 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sigmawarden 0.1.0
File Size Uploaded
sigmawarden-0.1.0.tar.gz 24.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sigmawarden 0.1.0
File Interpreter ABI Platform
sigmawarden-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 48.2 kB

Release files / sigmawarden-0.1.0.tar.gz

Download URL sigmawarden-0.1.0.tar.gz
Size 24.7 kB
Tags Source
SHA-256 checksum
How to use checksums
2f1d59fbc02dd9f33da66a56d4ae3db8a0ff231b545aa9a30b9c418a27f725e0
BLAKE2b-256 checksum
How to use checksums
722c05351aba8f5a86a3cf76b0012a35f9e2176f4cd018ef9aa72425a1b4e4cc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 21, 2026.

Transparency log

Release files / sigmawarden-0.1.0-py3-none-any.whl

Download URL sigmawarden-0.1.0-py3-none-any.whl
Size 23.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1908de02f4412e3bb2fc343bd8ddf8e25e210795a0634b9f9eb477b74385215a
BLAKE2b-256 checksum
How to use checksums
0e9de91527ae42925e98123ecd579ecbfe57b23d5a334c1c4654b38b0f83a02f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 21, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page