pySigma SQLite Backend
Converts Sigma rules into SQLite queries. The
package sigma.backends.sqlite provides sqliteBackend, registered as the
sigma-cli target sqlite. It is the converter behind
Zircolite, and its output runs on any
SQLite table of flattened events.
Maintained by wagga.
Install
pip install pysigma-backend-sqlite
Requires Python 3.11+ and pySigma 2.x. Backend 2.0.0 is the last release for pySigma 1.5. Correlation output needs SQLite 3.38 or newer.
Quick start
from sigma.collection import SigmaCollection
from sigma.backends.sqlite import sqliteBackend
rules = SigmaCollection.from_yaml(r"""
title: Whoami execution
status: test
logsource:
category: process_creation
product: windows
detection:
selection:
Image|endswith: '\whoami.exe'
condition: selection
""")
print(sqliteBackend().convert(rules)[0])
# SELECT * FROM logs WHERE Image LIKE '%\\whoami.exe' ESCAPE '\'
Processing pipelines map a logsource to concrete fields. With
sqliteBackend(sysmon_pipeline() + windows_logsource_pipeline()) the same rule becomes:
SELECT * FROM logs WHERE Channel='Microsoft-Windows-Sysmon/Operational' AND (EventID=1 AND Image LIKE '%\\whoami.exe' ESCAPE '\')
Those pipeline packages still declare pysigma<2; until they are updated, install
them with pip install --no-deps pysigma-pipeline-sysmon pysigma-pipeline-windows.
With sigma-cli:
sigma convert -t sqlite -f zircolite -p sysmon -p windows-logsources rules/
sigma-cli 3.1 still requires pySigma 1.x, so it installs backend 2.0.0.
Output formats
| Format | Output |
|---|---|
default |
One SELECT * FROM logs WHERE ... statement per rule |
zircolite |
A JSON list with one entry per rule: Sigma metadata, the SQL, and what a consumer needs to run it. See output format |
Options
Pass options as constructor keywords, or from sigma-cli with -O name=value.
Options are read at construction; assigning attributes later skips validation
and does not change the timestamp expression.
| Option | Default | Purpose |
|---|---|---|
table |
logs |
Table to query. A pipeline setState on table takes precedence |
collate_nocase |
false |
Emit field='value' COLLATE NOCASE for tables without NOCASE columns |
max_flat_operands |
100 |
Longer AND/OR chains are nested to stay under SQLite's expression depth limit |
fulltext_field |
none | Column of searchable event text; enables keyword search |
timestamp_field |
timestamp |
Event time column used by correlations |
timestamp_format |
iso |
iso, unix, unix_ms or unix_us |
timestamp_seconds_expression |
ISO parser | SQL turning {field} into Unix seconds; overrides timestamp_format |
event_id_field |
rowid |
Non-NULL, per-table unique event identifier for correlation evidence |
observation_end |
latest event | Unix seconds up to which absence windows can expire |
Generated SQL
| Modifier | SQL |
|---|---|
contains, startswith, endswith |
LIKE '%value%' ESCAPE '\' and its prefix/suffix forms |
all |
AND of the values |
re |
REGEXP (needs a registered function, see Limitations) |
cidr |
= or LIKE prefixes of the expanded network |
cased |
GLOB; literal *, ?, [ become [*], [?], [[] |
fieldref |
field1=field2, or LIKE with the second field's % and _ escaped |
exists |
IS NOT NULL / IS NULL |
gt, gte, lt, lte, neq |
>, >=, <, <=, negated equality |
minute, hour, day, week, month, year |
strftime() part |
base64, base64offset, wide, utf16*, windash |
Expanded by pySigma into ordinary matches |
The SQL keeps Sigma's meaning without help from the caller:
- Negation. Sigma reads a condition on a missing field as false; SQLite reads
it as
NULL, andNOT NULLdrops the row. EveryNOTtherefore wraps its operand:EventID=1 AND (NOT COALESCE((CommandLine LIKE '%foo%' ESCAPE '\'), 0)). - Case.
LIKEignores case.=does only onNOCASEcolumns, which is how Zircolite builds its table; otherwise setcollate_nocase.casedusesGLOB. - Booleans.
Flag: truematches text or integer storage:(Flag='true' OR Flag=1). - Long lists. Chains above
max_flat_operandsare regrouped, so rules with thousands of values don't fail with "Expression tree is too large". - Field names. SQLite keywords and names with characters other than letters,
digits and
_are quoted with backticks.field: nullbecomesfield IS NULL.
Correlations
All Sigma correlation types run in SQLite: event_count, value_count,
value_sum, value_avg, value_median, value_percentile, temporal and
temporal_ordered, including chains, aliases and extended temporal conditions.
Each result row is one alert occurrence with its window, metric and contributing
event IDs. Semantics are described in correlations;
upgrading from backend 1.x is covered in the migration guide.
Keyword search
Keyword (fieldless) selections need a column of searchable event text:
sqliteBackend(fulltext_field="_sigma_fulltext"). Without it, keyword rules raise
an error rather than guess. See keyword search.
Limitations
- REGEXP. SQLite has no built-in
REGEXP. Register one that is false forNULL:connection.create_function("regexp", 2, lambda p, v: v is not None and re.search(p, str(v)) is not None). pySigma 2 validates|repatterns with RE2, so rules with lookarounds or backreferences are rejected when parsed. - CIDR. SQLite has no network type. Prefix patterns match IPv6 addresses only in the spellings pySigma expands to.
- Case folding (
NOCASE,LIKE) is ASCII only. - Timestamp parts use
strftime()and need ISO-8601 text; a numeric epoch is read as a Julian day.%Wcan return week 0. - Field existence. SQL
NULLcannot tell a missing field from an explicit null. - Multi-field
value_count(a list incondition.field) is rejected. - Unknown columns. A query naming a column the table lacks fails to prepare.
Add missing columns as
NULLfirst; see output format.
Development
poetry install
poetry run pytest
SQLITE_MIN_BINARY=/path/to/sqlite-3.38 poetry run pytest tests/test_sqlite_minimum.py
tools/audit_corpus.py converts and prepares a SigmaHQ checkout per profile
(coverage, not detection accuracy). tools/benchmark_correlations.py times
sparse and dense correlation windows.
Metadata
Release files for pySigma-backend-sqlite 2.1.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 | |
|---|---|---|---|
| pysigma_backend_sqlite-2.1.0.tar.gz | 30.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pysigma_backend_sqlite-2.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 61.4 kB
Release files / pysigma_backend_sqlite-2.1.0.tar.gz
| Download URL | pysigma_backend_sqlite-2.1.0.tar.gz |
|---|---|
| Size | 30.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
eba5d117212bd1b3a6a4ae51b527fba891c5dbe13e44bbaf3c1b3b2701b09eb6
|
|
BLAKE2b-256 checksum How to use checksums |
ee91284a42292daff137de86c827cd07d032831e220b3239a12b528648cb1031
|
| 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 Oct 10, 2026.
Transparency logRelease files / pysigma_backend_sqlite-2.1.0-py3-none-any.whl
| Download URL | pysigma_backend_sqlite-2.1.0-py3-none-any.whl |
|---|---|
| Size | 30.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dbb8c0724413e33f8049c8d2cef7c02cee7fb124a9d4d71ff442d31bb49b2f50
|
|
BLAKE2b-256 checksum How to use checksums |
b5cabfe71d25c7789de8c029185bf3dc118aa38ae1f599856604e95316fc35a0
|
| 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 Oct 10, 2026.
Transparency log