Rulezet is an open-source web platform for sharing, evaluating, improving and managing cybersecurity detection rules — YARA, Sigma, Suricata, Zeek, Wazuh, Snort-family (Sagan), CRS, Nova, NSE, Elastic, KQL, Splunk, Kunai, ATR, Plum. Security teams publish rules, test them, review each other's work and keep them in sync with their sources and their tools.
Rulezet is available as an online service at https://rulezet.org/.
| Layer | Technology |
|---|---|
| Backend | Python 3.12+ · Flask · Flask-Login · Flask-SQLAlchemy · Flask-Migrate · Flask-RESTX |
| Frontend | Vue.js 3 (UMD, no build step) · Bootstrap 5.3 · Font Awesome 6 · ECharts |
| Database | PostgreSQL (production / development) · SQLite (tests) |
| Background jobs | worker.py — its own process, polling the background_job table |
| Web server | gunicorn (behind nginx in production), optional Redis cache |
| Dependencies | uv — pyproject.toml + uv.lock, virtual environment in .venv/ |
| Similarity | TF-IDF + FAISS + rapidfuzz |
| AI (optional) | Ollama, Anthropic or OpenAI-compatible providers |
# 1. Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 2. Clone with the submodules (rule editor, tester, MISP / ATT&CK data…)
git clone --recurse-submodules https://github.com/rulezet/rulezet-core.git
cd rulezet-core
# 3. Install the dependencies (uv sync → .venv/) and initialise the database
python3 manage.py initinit prints the temporary administrator credentials: the first login asks for your own email and
password.
python3 manage.py start-dev # worker + gunicorn, reloads on code changesThe application runs on http://127.0.0.1:7009 by default.
Every operation goes through manage.py (python3 manage.py --help lists them all):
| Command | What it does |
|---|---|
init |
first-time setup: uv sync (creates .venv/) and the database |
start-dev |
local run (FLASKENV=development): worker.py + gunicorn, debug, auto-reload |
update |
after git pull: sync with origin, uv sync, Ollama, flask db upgrade |
start-prod / restart-prod |
production launch (backup, sync, deps, migrations, start) / just restart |
deploy |
full production deployment: backup → update → start-prod |
test |
the test suite (FLASKENV=testing) |
db |
Flask-Migrate (db, db migrate -m "…", db downgrade) |
db-init / db-reload |
create tables + admin user / drop and recreate everything |
backup / restore |
PostgreSQL dump to backup/dumps/ / interactive restore |
pivotick / pivograph |
rebuild the graph assets from their submodules |
config.py selects the environment with FLASKENV:
FLASKENV |
Database | Notes |
|---|---|---|
development |
PostgreSQL | debug |
testing |
SQLite | CSRF disabled |
production |
PostgreSQL | — |
Secrets live in .env — .env_default lists them all (secret key, mail server, GITHUB_TOKEN for
GitHub imports, INSTANCE_PUBLIC_URL, Ollama URL / model, AI provider keys…).
Everything else (lists, labels, prices, defaults, feature switches) is a setting: one JSON file per
setting in app/config/, editable live from Admin → Configuration (/admin/configuration). Admin
changes are kept apart from the file (three-way merge on update, full history), so git pull stays
clean.
| Format | Format | ||
|---|---|---|---|
yara |
malware / file detection | wazuh |
Wazuh HIDS / SIEM rules |
sigma |
generic SIEM detection (+ correlation rules) | sagan |
Snort-family log rules |
suricata |
network IDS / IPS | crs |
OWASP Core Rule Set (ModSecurity / Coraza) |
zeek |
network analysis scripts | nova |
Nova hunting rules |
elastic |
Elastic Security rules | nse |
Nmap Scripting Engine |
kql |
Kusto queries (Sentinel / Defender) | splunk |
Splunk searches |
kunai |
Kunai (Linux) detections | atr |
Agent Threat Rules |
plum |
Plum rules |
A new format is one class in app/features/rule/rule_format/available_format/ (see below).
- Create, edit, propose edits (owner review, discussion) and soft-delete with a trash
- Parse pasted content: format detected, metadata extracted
- Import from GitHub / Git repositories (Git Sources registry, scheduled syncs, quality score of each source), ZIP archives and JSON
- Syntax validation with each format's own engine; invalid rules are kept apart and can be fixed
- Rule history, versions, diff; linked rules (dependencies, YARA references, Wazuh parents,
Sigma
related:and correlations) as a graph - Quality score per rule (documentation, traceability, validity, tests)
- Default TLP:CLEAR / PAP:CLEAR tags, MISP taxonomies and galaxies, ATT&CK techniques, CVEs
- YARA editor and Sigma editor tabs on the create page: completion, live errors giving Rulezet's own verdict, quick fixes, hover help, rename, formatter, rule tools, templates, tutorial, several rules per document, a Fields panel that writes Rulezet's metadata into the rule
- Checks panel: Rulezet's validation plus external tools — YARA-X, CCCS YARA standard, yaraQA for YARA; SIEM conversion and SIEM data models (pySigma), SigmaHQ conventions, sigmalint, rsigma, search cost for Sigma; "Already in Rulezet?" for both
- Create checks every rule (already in Rulezet, syntax, external checks, samples) before writing anything: new rules created, your changed rules updated, other people's proposed to their owner
- Rules run on sample sets in a bubblewrap sandbox: YARA on files, Sigma on events (synthetic, benign and recorded attacks) — detections, misses and false positives, per rule version
- Rules and Bundles explorers (search, filters, cards / table), bundle tree, bundle forks and merge requests
- CVE response kits (
/vulnerability/<id>) and ATT&CK technique pages (/attack/technique/<id>): every rule for one subject, coverage per format, gaps, download - Workspace, favourites, votes, comments, reports, notifications, leaderboard
- Connectors: pull rules from other Rulezet instances (soft / hard), by uuid
- Rulesets mirrors: rules pushed to Git repositories
- MISP (taxonomies, galaxies, export), Velociraptor, MITRE ATT&CK data
- REST API with API keys
- Users, organisations, verification; activity log (public / private); background jobs with live progress
- Workflows: scheduled and chained admin tasks (maintenance, data refresh, Rulesets publication…) with templates, runs, notes, calendar
- Settings, rule formats, similarity engine, reported rules, trash, AI assistants (chatbot, rule analysis, fixer, generator)
- Guided tour on every page, light / dark mode
Swagger UI at /api/. Public namespaces read without a key; private ones need X-API-KEY
(generated with your account, shown on your profile).
Namespaces: rule, bundle, connector, account, comment, config, log, instance,
rule_tester, utils.
# Create a rule
curl -X POST http://127.0.0.1:7009/api/rule/private/create \
-H "X-API-KEY: your-key" -H "Content-Type: application/json" \
-d '{"format": "yara", "title": "My Rule", "to_string": "rule My_Rule { condition: true }"}'
# Validate a rule without saving it
curl -X POST http://127.0.0.1:7009/api/rule/public/validate \
-H "Content-Type: application/json" \
-d '{"format": "sigma", "content": "title: …"}'python3 manage.py test # the suite CI runs (tests/)
FLASKENV=testing pytest tests/rules/test_rule.py -k "test_name"
FLASKENV=testing pytest tests_new # the new suite, by feature (docs/design/test_restructure.md)
# submodules
cd app/modules/rulezet-editor && npm test # editor (JS)
cd app/modules/rulezet-tester && pytest # testerBoth suites create their app, SQLite schema and baseline data once per run. Each
test uses a transaction that is rolled back afterwards, including changes made by
db.session.commit() inside requests. App settings and login throttling are reset
between tests too. Tests that need independent commits across worker contexts use
@pytest.mark.independent_db to restore a SQLite snapshot instead; they also reuse
the schema and seed data. Database and session files live in pytest's temporary directory,
separately for each suite and worker; instance/rulezet-test.sqlite is not used.
Tests that touch other shared checkout files should still be run sequentially.
| Homepage | Rule Detail | Invalid Rules |
|---|---|---|
![]() |
![]() |
![]() |
- Create
app/features/rule/rule_format/available_format/myformat_format.py - Subclass
RuleTypefromrule_type_abstract.py - Implement
format,validate(),parse_metadata(),detect(),get_rule_files(),extract_rules_from_file(),find_rule_in_repo() load_all_rule_formats()discovers it — no other registration
To give it an editor, tests on samples and external checks as YARA and Sigma have, follow the
rulezet-editor-format skill (app/modules/rulezet-editor/skills/, also in
rulezet-ai-skill).
- Pull requests for features and fixes are welcome (commits:
fix: [section] …/chg: [section] …) - Issues and ideas: GitHub Issues
- New rule formats, sample sets, documentation
- Working with an AI coding assistant: rulezet-ai-skill
This software is licensed under the GNU Affero General Public License version 3.
Copyright (C) 2025-2026 CIRCL - Computer Incident Response Center Luxembourg
Copyright (C) 2025-2026 Thëo GEFFE @ CIRCL
Rulezet is co-funded by CIRCL and by the European Union under the FETTA (Federated European Team for Threat Analysis) project.
This project is inspired by Flask launchpad, extended with a modern UI, collaborative features, and full integration capabilities.




