Quick Start🔗
This page gets you from a fresh install to a fired detection in five minutes. We will write one Sigma rule, evaluate it against a JSON event, then run RSigma as a streaming daemon that hot-reloads when the rule changes.
If you have not installed RSigma yet, follow Installation first.
1. Write your first rule🔗
Create a directory for rules and a single rule file:
mkdir -p rules
cat > rules/whoami.yml <<'EOF'
title: Suspicious whoami invocation
id: 8b1d8c97-5b3a-4d77-9b48-7c5f7c8b1a2a
status: experimental
description: Flags any process that runs the whoami binary.
logsource:
product: windows
category: process_creation
detection:
selection:
CommandLine|contains: 'whoami'
condition: selection
level: medium
tags:
- attack.discovery
- attack.t1033
EOF
This is the minimum useful Sigma rule. selection matches the CommandLine field with a case-insensitive substring; condition: selection activates that selection.
New to Sigma?
SigmaHQ maintains the canonical documentation for writing rules. Start with the Getting Started guide, then deep-dive into rule structure, field modifiers, condition expressions, and log sources. The full Sigma v2.1.0 specification is the authoritative reference. Everything you write against the spec works in RSigma.
2. Evaluate a single event🔗
RSigma writes detection matches to stdout as JSON, and progress messages to stderr as plain text. Run:
You should see a MatchResult like this on stdout:
{
"rule_title": "Suspicious whoami invocation",
"rule_id": "8b1d8c97-5b3a-4d77-9b48-7c5f7c8b1a2a",
"level": "medium",
"tags": [
"attack.discovery",
"attack.t1033"
],
"matched_selections": [
"selection"
],
"matched_fields": [
{
"field": "CommandLine",
"value": "cmd /c whoami"
}
]
}
Stderr is just Loaded 1 rules from rules/. The event field of MatchResult is only populated when --include-event is set; every other field is always present.
--pretty is great while you are exploring. Drop it to get the compact one-line form used in production:
{"rule_title":"Suspicious whoami invocation","rule_id":"8b1d8c97-5b3a-4d77-9b48-7c5f7c8b1a2a","level":"medium","tags":["attack.discovery","attack.t1033"],"matched_selections":["selection"],"matched_fields":[{"field":"CommandLine","value":"cmd /c whoami"}]}
A non-matching event writes nothing to stdout, prints No matches. to stderr, and exits 0:
3. Stream events from stdin🔗
The same command reads NDJSON from stdin when --event is omitted. Each line is parsed as a JSON object and evaluated independently.
cat <<'EOF' | rsigma engine eval -r rules/
{"CommandLine": "cmd /c whoami"}
{"CommandLine": "dir C:\\Users"}
{"CommandLine": "whoami /all"}
EOF
Two of the three lines match. RSigma emits one JSON line per match on stdout, dropping the non-matching line silently so the output stays safe for direct piping into downstream tools:
{"rule_title":"Suspicious whoami invocation","rule_id":"8b1d8c97-5b3a-4d77-9b48-7c5f7c8b1a2a","level":"medium","tags":["attack.discovery","attack.t1033"],"matched_selections":["selection"],"matched_fields":[{"field":"CommandLine","value":"cmd /c whoami"}]}
{"rule_title":"Suspicious whoami invocation","rule_id":"8b1d8c97-5b3a-4d77-9b48-7c5f7c8b1a2a","level":"medium","tags":["attack.discovery","attack.t1033"],"matched_selections":["selection"],"matched_fields":[{"field":"CommandLine","value":"whoami /all"}]}
Stderr closes with a Processed 3 events, 2 matches. summary.
4. Lint and validate the rule🔗
rule lint checks the rule against 66 Sigma spec checks. By default, only a summary line is printed:
────────────────────────────────────────────────────────────
Checked 1 file(s): 1 passed, 0 failed (0 error(s), 0 warning(s), 1 info(s))
--verbose shows each finding with its rule ID and location, useful when investigating informational findings or copy-pasting a path:
rules/whoami.yml
info[missing_author]: missing recommended field 'author'
--> /author
────────────────────────────────────────────────────────────
Checked 1 file(s): 1 passed, 0 failed (0 error(s), 0 warning(s), 1 info(s))
rule validate parses, compiles, and reports counts without running matchers, which is the safest gate for CI:
Parsed 1 documents from rules/
Detection rules: 1
Correlation rules: 0
Filter rules: 0
Parse errors: 0
Compiled OK: 1
Compile errors: 0
Both commands return structured exit codes so they slot into CI without parsing stdout. lint --fix will apply safe auto-fixes for 13 of the 66 rules.
5. Run as a streaming daemon🔗
For continuous detection with hot-reload, metrics, and a management API, run RSigma as a daemon. With --input http, the daemon accepts NDJSON events over an HTTP endpoint instead of reading stdin:
Loopback (127.0.0.0/8, ::1) keeps plaintext for local development. When you move to a production bind such as --api-addr 0.0.0.0:9090, the daemon (built with the daemon-tls feature) refuses to start without either --tls-cert/--tls-key or an explicit --allow-plaintext. See TLS termination for the full story.
The daemon logs structured JSON to stderr while it starts. Detections are written to stdout as they fire. In another terminal (or after & returns control), send an event:
curl -sS -X POST http://127.0.0.1:9090/api/v1/events \
-H 'Content-Type: application/x-ndjson' \
--data '{"CommandLine":"whoami /priv"}'
curl reports {"accepted":1}, and a matching detection appears on the daemon's stdout almost immediately:
{"rule_title":"Suspicious whoami invocation","rule_id":"8b1d8c97-5b3a-4d77-9b48-7c5f7c8b1a2a","level":"medium","tags":["attack.discovery","attack.t1033"],"matched_selections":["selection"],"matched_fields":[{"field":"CommandLine","value":"whoami /priv"}]}
While the daemon is running, edit rules/whoami.yml. The file watcher reloads rules within 500 ms and re-emits detections against subsequent events. The management endpoints expose health, status, and Prometheus metrics:
{"status":"running","detection_rules":1,"correlation_rules":0,"correlation_state_entries":0,"events_processed":1,"detection_matches":1,"correlation_matches":0,"uptime_seconds":0.57}
# HELP rsigma_back_pressure_events_total Times a source was blocked on a full event channel
# TYPE rsigma_back_pressure_events_total counter
rsigma_back_pressure_events_total 0
# HELP rsigma_batch_size Number of events processed per batch
# TYPE rsigma_batch_size histogram
The metrics endpoint exposes 27 labeled counters, gauges, and histograms covering input, detection, correlation, and dynamic sources. Per-rule labels make Grafana alerting straightforward:
See Prometheus metrics for the full catalog and the streaming detection guide for hot-reload internals, state persistence, and the rest of the HTTP API.
When you are done, stop the backgrounded daemon with kill %1 (or your shell's job-control equivalent). It catches SIGINT and SIGTERM and shuts down cleanly after draining the in-flight events.
6. Convert the rule to PostgreSQL🔗
rsigma backend convert turns the same rule into a backend-native query for historical hunting:
Five PostgreSQL output formats are available (default, view, timescaledb, continuous_aggregate, sliding_window), and a lynxdb target is also shipped. Drop the SQL into psql, a view definition, or a TimescaleDB continuous aggregate without further translation. The rule conversion guide walks through every format.
What next🔗
You have used RSigma in three modes:
- One-shot evaluation with
engine eval. - Continuous streaming detection with
engine daemon. - Query generation with
backend convert.
From here, pick the path that matches your work:
- Detection engineers: linting rules, CI/CD, processing pipelines.
- Platform engineers: streaming detection, NATS, OTLP integration.
- Threat hunters: evaluating rules, input formats, EVTX files.
- Library users: embedding the crates.
If anything in this quick start did not work, run the quick-verification checklist (log filter targets, /healthz / /readyz, /metrics smoke check) or open an issue.