Skip to main content

Prohori (প্রহরী)

CI CodeQL OpenSSF Scorecard Secret scanning: gitleaks Dependabot

PyPI Python versions Wheel Downloads GitHub release Release workflow Status: alpha Platforms License: MIT

uv Ruff Checked with mypy pre-commit Conventional Commits Contributor Covenant

Last commit Commit activity Open issues Pull requests Wiki PRs welcome

A laptop-sized mini-SOC: from raw logs to detections, enriched incidents and analyst-ready reports, with honest machine-learning evaluation and a streaming data pipeline.

Prohori (প্রহরী) is Bengali for "guard". It is an open-source, defensive security-operations toolkit in Python that runs on a single laptop with free tools only, offline by default.

Status: alpha (v0.1.0). The batch core is complete: one command goes from a log file to scored incidents and shareable reports, and a labelled attack simulator measures the rules. Machine learning, the streaming pipeline and the LLM analyst follow in later releases. See the CHANGELOG and the roadmap.

60-second demo

pipx install prohori        # or: pip install prohori
prohori demo

prohori demo: three simulated attacks, the incidents found and every expected rule fired

The demo simulates an account takeover, an SSH brute force and a web scan, triages each one offline and writes an HTML report per incident to prohori-demo/. It needs no configuration and sends nothing over the network. Sample reports: Markdown, HTML (download and open it) and redacted.

Contents

What it does

flowchart LR
    A[Log files<br>auth.log, nginx, app JSON] --> B[parse<br>common event schema]
    B --> C[detect<br>15 YAML rules]
    C --> D[incidents<br>group, score, ATT&CK]
    E[enrich<br>GeoLite2, AbuseIPDB, VirusTotal] --> D
    D --> F[report<br>Markdown, HTML, JSON, CSV]
Stage Today
Parse Linux auth.log (sshd, sudo, PAM), nginx/Apache access logs, application security events (JSON Lines) and any JSON Lines layout through a YAML field mapping, into one typed event schema. Format detection, streaming with bounded memory, hostile input handled (oversized lines, bad encodings, control characters).
Detect 15 readable YAML rules (Sigma-inspired) with field modifiers, thresholds, distinct counts, ratios, sliding and tumbling windows and ordered sequences. Every rule ships with test fixtures and a runbook; regular expressions run on RE2, so no pattern can hang a run.
Enrich IP geolocation, network owner and reputation from local GeoLite2 files, AbuseIPDB and VirusTotal, all optional. SQLite cache, daily budgets, rate limiting and bounded retries. Private and documentation addresses never leave the machine.
Incidents Related alerts (same IP, account, request or session within a time gap) become one incident with a points-based score you can read line by line, severity, confidence, MITRE ATT&CK v20.0 mapping, a timeline, recommended actions and stated limitations. Detects sign-ins from an IP or app new to the account.
Simulate Eight labelled attack scenarios (SSH brute force, password spraying, credential stuffing, token reuse, account takeover, web scanning, injection, admin misuse) hidden in realistic background activity, byte-identical for a seed, documentation IP addresses only. Used to measure every rule's precision and recall.
Report Markdown, a self-contained HTML page, JSON or a CSV timeline, with an appendix of input and rule-file SHA-256 hashes. --redact replaces account names, ids and emails (and optionally IPs) with keyed pseudonyms, and refuses to write a report that would still leak one.

Prohori only recommends actions. It never blocks addresses, disables accounts or touches remote systems.

Install

Prohori needs Python 3.11 or newer. CI tests it on Linux and Windows; macOS should work but is not tested.

  • From PyPI: pipx install prohori puts the prohori command in its own environment; pip install prohori works in any virtual environment. Local GeoLite2 support is an extra: pip install "prohori[geoip]".
  • From source: install uv, then git clone https://github.com/UtshaBasak/Prohori.git && cd Prohori && uv sync, and run commands as uv run prohori .... The sample files used below are in the repository.

Quick start

Everything below runs offline on the synthetic samples in the repository (run from a clone).

uv run prohori triage samples/logs/account-takeover.jsonl -o triage/   # the whole pipeline
uv run prohori parse samples/logs/auth.log                      # normalise a log
uv run prohori detect samples/logs/auth.log                     # run the 15 rules
uv run prohori enrich 203.0.113.7 --offline                     # look up an IP (demo data)
uv run prohori incidents samples/logs/account-takeover.jsonl    # group alerts into incidents
uv run prohori report samples/incidents/INC-ee7c8818fbb34989.json -f html -o report.html
uv run prohori simulate account-takeover --seed 1 --out out/      # your own labelled attack

prohori triage writes triage/summary.md, triage/incidents.jsonl and an HTML report per incident. Open a report in a browser: one file, no scripts, no external resources. For your own logs, prohori triage /var/log/auth.log --year 2026 -o triage/ works the same way (add --redact-ips before sharing the output).

Example: an account takeover

samples/logs/account-takeover.jsonl is a synthetic attack on a web shop account: twelve wrong passwords from one IP in 33 seconds, a successful sign-in, two-step verification switched off and the bKash payout number changed. Prohori raises four alerts and joins them into one critical incident:

$ uv run prohori incidents samples/logs/account-takeover.jsonl     # first lines
INC-ee7c8818fbb34989  critical  score 100
+-------------------------------------------------------------------------------------------------+
| title       | Successful sign-in after many failures from one IP and 3 related alerts           |
| time (UTC)  | 2026-10-24 21:10:00 - 2026-10-24 21:13:10                                         |
| confidence  | high                                                                              |
| rules       | PRH-ACCT-001, PRH-AUTH-001, PRH-AUTH-003                                          |
| entities    | source.ip: 203.0.113.7                                                            |
|             | user.email_hash: 0cc175b9c0f1b6a831c399e269772661                                 |
|             | user.id: u-2001                                                                   |

Every point of the score is explained (from prohori report):

Points Reason
+50 Most severe alert: PRH-AUTH-003 (critical)
+20 2 more rules fired: PRH-ACCT-001, PRH-AUTH-001
+20 A sign-in succeeded after failed attempts
+15 Sensitive account or admin change: account.2fa.disabled, account.bkash.changed
+20 Reputation of 203.0.113.7: abuse confidence 97; 9 vendors flag it as malicious (from bundled demo data)
+10 Sign-in to u-2001 from 203.0.113.7, an IP not seen for this account before (1 earlier IP)
+5 Sign-in to u-2001 with client web, not seen for this account before
-40 Capped at 100
100 Total

The report adds the timeline, the IP's enrichment, the ATT&CK techniques (T1110 Brute Force, T1078 Valid Accounts, T1098 Account Manipulation, T1556.006 Multi-Factor Authentication), recommended actions from the runbooks and the limitations, such as "single log source" and "enrichment is bundled demo data".

Commands

Command What it does Docs
prohori demo Simulate attacks, triage them and show the results; no configuration, offline CLI.md
prohori triage FILE Log in, incidents and a report per incident out (--format, --redact, --online) CLI.md
prohori parse FILE Parse and normalise a log; table or JSON Lines PARSERS.md
prohori detect FILE Run the 15 built-in rules (and --rules DIR); exit code 3 when alerts are found RULES.md
prohori rules list / validate / test Show, check and test detection rules RULES.md
prohori enrich IP... Geolocation and reputation; --offline never uses the network ENRICHMENT.md
prohori incidents FILE Parse, detect and group alerts into scored incidents; offline enrichment unless --online INCIDENTS.md
prohori report INCIDENT Render an incident as md, html, json or csv; --redact, --redact-ips REPORTS.md
prohori simulate SCENARIO --out DIR Write a labelled attack scenario (--list, --seed, --variant heldout, --set) SIMULATOR.md
prohori version The version, ATT&CK release and built-in rule set

Commands that take a file also read standard input with -, and every command has --help. Exit codes are the same everywhere: 0 nothing found, 3 alerts or incidents found (--exit-zero turns this off for CI pipelines), 1 nothing could be processed and 2 invalid usage. The full reference is docs/CLI.md.

Built-in detection rules

Rule Detects Severity ATT&CK
PRH-AUTH-001 Brute-force sign-in attempts from one IP high T1110, T1110.001
PRH-AUTH-002 Password spraying or credential stuffing from one IP high T1110.003, T1110.004
PRH-AUTH-003 Successful sign-in after many failures from one IP critical T1110, T1078
PRH-AUTH-004 Account lockouts across many accounts high T1110
PRH-SESS-001 Refresh-token reuse high T1528, T1550.001
PRH-ACCT-001 Sensitive account change shortly after sign-in high T1098, T1556.006
PRH-AUTHZ-001 Authorisation denials across many resources medium T1595.003
PRH-ABUSE-001 Rate-limit bursts or bot-check failures from one IP medium T1499.002
PRH-ADMIN-001 Admin role granted high T1098
PRH-ADMIN-002 Admin action at an unusual hour (22:00-07:00 local time) medium T1078
PRH-WEB-001 Web scanning from one IP medium T1595.003
PRH-WEB-002 Injection patterns in request paths medium T1190
PRH-WEB-003 Scanner or empty user agent at a high request rate medium T1595.002
PRH-WEB-004 Probes for sensitive files and admin tools medium T1595.003
PRH-SSH-001 SSH invalid-user storm or repeated authentication-limit disconnects high T1110, T1110.001

ATT&CK tags are verified against the official Enterprise ATT&CK v20.0 data. Each rule has a runbook in src/prohori/runbooks/. Writing your own rules is covered in docs/RULES.md.

How well the rules work

prohori simulate writes each attack scenario in two variants: default, the attack the rules were designed for, and held-out, the same attack done the way a careful attacker would (slower, from more addresses, with a browser user agent, obfuscated, or at another hour). scripts/evaluate_rules.py runs all rules over five seeds of each and compares the alerts with the line labels.

Default Held-out
Attacks caught by at least one expected rule 40/40 35/40

Expected rules that missed in the held-out variants (runs missed out of runs):

  • account-takeover: PRH-ACCT-001 3/5, PRH-AUTH-001 5/5
  • admin-misuse: PRH-ADMIN-002 5/5
  • credential-stuffing: PRH-AUTH-001 5/5, PRH-AUTH-002 5/5, PRH-AUTH-003 5/5
  • password-spraying: PRH-AUTH-001 5/5
  • ssh-bruteforce: PRH-AUTH-001 5/5
  • web-scanning: PRH-WEB-003 5/5

PRH-ACCT-001 has low precision on purpose: it flags every sensitive change soon after a sign-in, including the owners' own. These are synthetic results written by the rules' author; the full per-rule table and caveats are in docs/SIMULATOR.md.

Privacy and safety

  • Offline by default. Nothing leaves the machine unless you configure API keys and, for incidents, pass --online. Tests block real network access.
  • Private, reserved and documentation IP addresses are never sent to outside services, even when keys are configured. VirusTotal keeps the addresses it is asked about, so querying is a deliberate choice.
  • Logs are untrusted input. Parsers cap line lengths and strip control characters; reports escape every value for their format (HTML, Markdown, CSV formulas) and are tested with hostile input.
  • Shareable reports. --redact / --redact-ips use keyed pseudonyms and fail closed.
  • No secrets in the repository. API keys live in the environment or a git-ignored .env; gitleaks runs on every commit and in CI.
  • Samples are synthetic and use documentation address ranges only.

Third-party data terms (MITRE ATT&CK, GeoLite2, AbuseIPDB, VirusTotal) are summarised in docs/LICENSES.md.

Documentation

Document Contents
CLI reference Every command, the shared options, formats and exit codes
Architecture Components, data flow and run modes
Event schema Event, Alert and Incident fields
Parsers Supported formats, options and field mappings
Rules Rule format, evaluation semantics, testing and the built-in rules
Enrichment Providers, privacy, cache, limits and configuration
Incidents Grouping, the scoring table, confidence and limitations
Reports Formats, sections, redaction and output safety
Simulator Attack scenarios, labels, and rule precision and recall
Decisions Architecture decision records
Releasing How releases are built, tested and published
Third-party terms Data and service licences
Wiki Installation, quick start and guides

Limitations

Prohori is honest about what it does not do:

  • It reads logs after the fact. There is no live monitoring yet (the streaming pipeline is planned for v0.3.0), and it never blocks, disables or changes anything.
  • Rules see only what the logs say. Request bodies, headers and encrypted traffic are not inspected; the web rules use the request line only.
  • Thresholds can be evaded. The held-out evaluation shows that slow or widely distributed attacks stay under the brute-force and spraying thresholds; see How well the rules work.
  • Some rules are noisy by design. PRH-ACCT-001 flags every sensitive change shortly after a sign-in, including the owner's own; incidents list such benign causes as limitations.
  • The evaluation is synthetic and written by the rules' author. Test the rules on your own logs before relying on them.
  • Enrichment free tiers are small and non-commercial, and reputation data is evidence, not proof.
  • Supported formats are auth.log, nginx/Apache access logs and JSON Lines (built-in app layout or a field mapping). Windows event logs and cloud audit logs are not supported yet.

Roadmap

Release Contents State
v0.1.0 Batch core: parsers, rules, enrichment, incidents, reports, log simulator with rule evaluation, triage and demo commands Released
v0.2.0 Machine learning: leakage-controlled intrusion detection on public flow datasets, log-derived anomaly detection, model cards Planned
v0.3.0 Pipeline: streaming core, Redpanda and PostgreSQL in Docker, dbt models, dashboard, orchestration Planned
v1.0.0 Optional LLM analyst (opt-in, redacted input, validated output), final polish Planned

Development

uv sync                        # create .venv with the package and dev tools
uv run pre-commit install      # optional: run checks on every commit

uv run ruff check .            # lint
uv run ruff format --check .   # formatting
uv run mypy                    # strict type check
uv run pytest --cov            # tests with coverage (kept at 85 % or more)
uv run prohori rules test      # run every rule against its fixtures

CI runs on Linux and Windows with Python 3.11 to 3.14, plus CodeQL, secret scanning, parser fuzzing and the OpenSSF Scorecard. All GitHub Actions are pinned to commit SHAs. See CONTRIBUTING.md for conventions.

Security

To report a vulnerability, see SECURITY.md.

License

MIT. Third-party data has its own terms; see docs/LICENSES.md.

Metadata

Release files for prohori 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 prohori 0.1.0
File Size Uploaded Provenance
prohori-0.1.0.tar.gz 248.2 kB With provenance Details

Built distribution (wheel)

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

Total release size: 451.9 kB

Release files / prohori-0.1.0.tar.gz

Download URL prohori-0.1.0.tar.gz
Size 248.2 kB
Tags Source
SHA-256 checksum
How to use checksums
0948a7e2c98fbec1024c4d04ad7c63ad44ebc73a67b09544327ededbe77b4a7a
BLAKE2b-256 checksum
How to use checksums
5cad87b324f2155a79e67da9c1b538823e193cddede24fbca2ff16047793788a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 26, 2026.

Transparency log

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

Download URL prohori-0.1.0-py3-none-any.whl
Size 203.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e1d0b92df7cbfe08922224ba82774e75dc6c2e5d49d1e148d7cf4f5f9d5d0ff0
BLAKE2b-256 checksum
How to use checksums
a1a20698516168cdfab66681a7d4a833b4e54ebd190725345413b1cdec2b77fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 26, 2026.

Transparency log

Security for prohori 0.1.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.

Select from 2 files

Attestation for prohori-0.1.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 Oct 26, 2026.

Transparency log

A 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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

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