sigmaforge
Honest Sigma-rule backtest harness. Measures detection rules against real log
corpora and reports two numbers per rule — recall (does it catch attacks of its
ATT&CK sub-technique?) and precision / false-positives (does it fire on benign
activity?) — with honesty gates that return unmeasured instead of a fake 0 or a
tautological 1.0 when the data can't support a number.
[!NOTE] Learning / portfolio project, built by directing AI coding agents. Christian Huhn (photography → SOC career change) designed, reviewed, and gated the work; the implementation was AI-pair-programmed. It is an honest measurement harness, not a polished product — see Status below for exactly what works and what doesn't yet.
What problem it solves
Every SOC ships dozens to hundreds of detection rules and rarely measures them. sigmaforge answers two questions with reproducible evidence:
- Which rules are noise generators? (high false-positives on legitimate activity)
- Which rules catch nothing? (zero recall against real attacks of their technique)
Example finding from a real run: Suspicious Windows Service Tampering produced 66 false-positives on a benign corpus — every one a Ninite / TeamViewer installer, not an attack.
How it actually works
flowchart LR
R[SigmaHQ rules] -->|partition high/critical| C[compile to one Zircolite ruleset]
C --> E[Zircolite engine]
A[(attack corpus<br/>sub-technique-labeled)] --> E
B[(benign corpus<br/>Nextron + OpTC)] --> E
E --> S[score: recall per technique<br/>+ precision/FP label-aware]
S --> G[honesty gates<br/>floor · positive-control · no-self-review]
G --> O[report.md + manifest]
The pipeline is one module (sigmaforge.pipeline); the CLI and the
scripts/run*_backtest.py runs call the same code — there is no weaker shipped
path. Two verbs, split by honesty (you cannot compute recall/precision without labels):
# pip-runnable: rules x ARBITRARY logs -> hits only (no labels -> precision/recall = unmeasured).
# Needs only the engine, no corpora.
sigmaforge hunt --rules my_rules/ --logs /path/to/logs
# the real measurement: rules x LABELED corpora -> per-technique recall + label-aware
# precision + honesty gates + report.md + manifest.json. Needs the corpora (else it
# prints a teaching error and points you at `hunt`).
sigmaforge backtest --rules my_rules/ --config sigmaforge.yaml
--rules takes a single .yml or a directory (auto-compiled). The engine + corpora
are not bundled (see Reproduce a backtest); the committed reports/run*.md are
inspectable without running anything.
Status
| Area | State |
|---|---|
| Recall (per sub-technique, no sibling dilution) | Working — 338/609 rules measurable, 70 fire (run5) |
| Precision / false-positives (label-aware, gated) | Working — 7/609 measurable on current benign corpus (run6) |
| Honesty gates (floor, positive-control, no-self-review) | Working |
| Reproducible manifest (run_hash, corpus SHAs, provenance) | Working |
One-command CLI (sigmaforge backtest + hunt) |
Working — same pipeline as the scripts (extracted to sigmaforge.pipeline); hunt is pip-runnable without corpora |
| Self-generated benign corpus | Kit ready (scripts/selfgen/), needs a Windows VM run |
[!IMPORTANT] The log corpora are not shipped. They are large, separately licensed, and gitignored.
pip install sigmaforgeinstalls the harness code, not the data — a full end-to-end backtest needs the corpora and a local Zircolite checkout (also not bundled). The package is useful as a library / reference; the runnable pipeline needs the local setup documented inscripts/.
Install
pip install sigmaforge
Installs the harness package and the sigmaforge CLI. The detection engine
(Zircolite) and the log corpora are obtained
separately (see above).
Corpora used (all verified, portfolio-safe licenses)
| Corpus | Role | License |
|---|---|---|
| splunk/attack_data | recall (sub-technique-labeled attacks) | Apache-2.0 |
| DARPA OpTC | precision (real enterprise benign week) | Public domain |
| NextronSystems/evtx-baseline | precision (goodware baseline) | Apache-2.0 |
Self-generated (scripts/selfgen/) |
precision (targeted admin/LOLBin noise) | your own lab |
Reproduce a backtest from a clone
The pip package is the library/CLI; a full end-to-end backtest needs the engine and corpora, which are not bundled (engine = large third-party tool; corpora = large and separately licensed). To go from a fresh clone to a runnable backtest:
uv sync --group backtest # script deps (pyyaml, evtx, gdown)
bash scripts/setup_engine.sh # fetch Zircolite 3.7.6 + its runtime deps
Then obtain the corpora (see the table above) into ~/sigmaforge-v0/ and build the
combined samples with the scripts/build_*_benign.py / scripts/build_*_corpus.py
helpers, compile the ruleset, and run a backtest:
uv run python scripts/compile_loaded_ruleset.py # SigmaHQ rules -> one Zircolite ruleset
uv run python scripts/run7_backtest.py # -> reports/run7.md (+ manifest)
Run scripts from the repo root (the engine working dir defaults to the current
directory; override with SIGMAFORGE_HOME if you keep Zircolite/ elsewhere). The
reports/run*.md + *_manifest.json are committed so the results are inspectable
without re-running.
Development
Built with the Shipwright dev framework.
uv sync --dev
uv run pytest # 113 tests (engine-dependent tests skip without Zircolite)
uv run ruff check .
License
MIT © Christian Huhn. Corpus data retains its upstream license (see table above).
Metadata
Release files for sigmaforge 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| sigmaforge-0.4.0.tar.gz | 53.8 kB | With provenance | Details for sigmaforge-0.4.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| sigmaforge-0.4.0-py3-none-any.whl | Python 3 | none | any | Details for sigmaforge-0.4.0-py3-none-any.whl |
Total release size: 93.7 kB
Release files / sigmaforge-0.4.0.tar.gz
| Download URL | sigmaforge-0.4.0.tar.gz |
|---|---|
| Size | 53.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
881ac92697381b4820d8a793cf4d9fffa78f7c106938f9b3b026431b8e1b799d
|
|
BLAKE2b-256 checksum How to use checksums |
28bd17db4b6e25edabebe8976421bd1cf671a92aa79593225e2a61ed28e9221e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 Jun 23, 2026.
Transparency logRelease files / sigmaforge-0.4.0-py3-none-any.whl
| Download URL | sigmaforge-0.4.0-py3-none-any.whl |
|---|---|
| Size | 39.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
01d08b8c5f10dcfaee46f3c6ad9968658f4fbe3b035f16968bbe336c97160a6d
|
|
BLAKE2b-256 checksum How to use checksums |
10e34b66557324ae95c9ebd916750f15ee78399524c7af259df92dfd1a90ec9a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 Jun 23, 2026.
Transparency logSecurity for sigmaforge 0.4.0
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for sigmaforge-0.4.0.tar.gz
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 Jun 23, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.