Ngenzipack/intelligent-security-alert-triage-engine

GitHub: Ngenzipack/intelligent-security-alert-triage-engine

Stars: 0 | Forks: 0

# Intelligent Security Alert Triage Engine Production-style proof-of-concept for reducing SOC alert fatigue using local LLM triage. ## Why this project exists Security teams often face alert fatigue: high-volume SIEM alerts with limited analyst time. This project demonstrates a practical triage pipeline that takes raw alerts, normalizes them, performs LLM-assisted analysis, enriches results with threat context, and presents analyst-ready outputs. ## Project positioning This repository is intentionally presented as a **Proof of Concept (POC)** with production-minded design choices: - typed data contracts - deterministic fallback when LLM is unavailable - structured logging - audit persistence - unit/integration tests and CI It is not a certified production SOC platform. ## Validation artifacts - Project report: [`docs/Intelligent_Security_Alert_Triage_Engine_Project_Report.docx`](docs/Intelligent_Security_Alert_Triage_Engine_Project_Report.docx) - Before/after patch report: [`REPORT_BEFORE_AFTER_PATCH.md`](REPORT_BEFORE_AFTER_PATCH.md) - Full-capability dashboard screenshots: `screenshots/full-capability/` - Patch validation screenshots: `screenshots/report/` ## Production-ready packaging This repository is prepared as a production-style project package with: - explicit architecture and data contracts - defensive runtime behavior and graceful fallback mode - structured logging and auditable storage - CI gates (lint + tests) and reproducible validation evidence - before/after patch report with screenshot proofs ## Showcase screenshots ### Dashboard overview (LLM run) ![Dashboard overview](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/3171b3f903062900.png) ### Sidebar workflow controls ![Sidebar controls](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/cc33b23ed3062901.png) ### Metrics and charts ![Metrics and charts](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/f0857b6b71062902.png) ### Alert detail with enrichment and engine mode ![Alert detail](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/c3b718ca7e062902.png) ## Core capabilities 1. Ingest alerts from: - local JSON/CSV simulation files (primary path) - optional Wazuh API - optional Elasticsearch index 2. Normalize to canonical schema: - `timestamp` - `source` - `event_type` - `description` - `raw_log` 3. Analyze with local LLM (Ollama + `llama3`): - classification: `true_positive | false_positive | uncertain` - criticality score: `0-100` - plain-English summary - mitigation steps 4. Enrich alerts: - MITRE ATT&CK technique inference - frequency in last 24h - composite risk score - severity band (`Low|Medium|High|Critical`) 5. Persist and visualize: - append enriched output to `alerts_log.json` - interactive Streamlit dashboard with filters, charts, drill-down, and export ## Architecture and data flow flowchart LR A["Wazuh API"] --> D["Ingestion Layer"] B["Elasticsearch"] --> D C["JSON or CSV Simulation"] --> D D --> E["Normalization to Canonical Schema"] E --> F["LLM Analysis Engine via Ollama llama3"] F --> G["JSON Parser and Validation"] G --> H["Fallback Classifier if needed"] H --> I["Enrichment MITRE and Risk"] I --> J["JSON Audit Store alerts_log.json"] J --> K["Streamlit Dashboard"] ### Pipeline stages - **Ingest**: collect records from selected source. - **Normalize**: convert heterogenous payloads into one schema. - **Analyze**: query Ollama at `POST /api/generate` with strict JSON prompt. - **Guardrail parse**: recover JSON from noisy model output, validate required keys. - **Fallback**: deterministic keyword triage if model is down/malformed. - **Enrich**: attach MITRE mappings + frequency + composite risk. - **Persist**: append enriched records to JSON audit log. - **Visualize**: dashboard table, filters, pie chart, timeline, and exports. ## Repository structure src/ analysis/ # prompting, parser, Ollama client, fallback logic ingestion/ # file/wazuh/elk adapters + normalizer enrichment/ # MITRE mapping + risk scoring storage/ # JSON append store with file lock support dashboard/ # Streamlit UI cli.py # command interface pipeline.py # orchestration data/ sample_alerts.json screenshots/ README.md tests/ unit + integration tests .github/workflows/ ci.yml ## Requirements - Python **3.11+** - Ollama installed locally - `llama3` model pulled (`ollama pull llama3`) ## Quick start 1. Clone repo and enter it. 2. Create env and install dependencies: python3.11 -m venv .venv source .venv/bin/activate pip install --upgrade pip pip install -r requirements.txt 3. Configure environment: cp .env.example .env 4. Ensure Ollama is running: ollama serve ollama list | grep llama3 ## Commands ### CLI batch (simulation) python -m src.cli run-batch --source file --path data/sample_alerts.json ### CLI batch (Wazuh) python -m src.cli run-batch --source wazuh ### CLI batch (ELK) python -m src.cli run-batch --source elk ### CLI manual alert analysis python -m src.cli analyze-text --text "Suspicious PowerShell execution from C:\Users\admin\AppData\Local\Temp\payload.ps1" ### Streamlit dashboard streamlit run src/dashboard/app.py ### Makefile shortcuts make setup make lint make test make run-cli make run-ui make sample ## Environment variables | Variable | Purpose | Default | |---|---|---| | `OLLAMA_BASE_URL` | Ollama endpoint base URL | `http://localhost:11434` | | `OLLAMA_MODEL` | Local model name | `llama3` | | `OLLAMA_TIMEOUT_SECONDS` | HTTP timeout for model/API calls | `45` | | `OLLAMA_MAX_RETRIES` | LLM retry attempts before fallback | `2` | | `WAZUH_API_URL` | Optional Wazuh alerts endpoint | empty | | `WAZUH_API_TOKEN` | Optional Wazuh bearer token | empty | | `ELK_URL` | Optional Elasticsearch URL | empty | | `ELK_INDEX` | Elasticsearch index pattern | `security-alerts-*` | | `ELK_API_KEY` | Optional Elasticsearch API key | empty | | `ALERT_LOG_PATH` | JSON audit log path | `logs/alerts_log.json` | | `APP_LOG_PATH` | Application log file path | `logs/app.log` | | `APP_LOG_LEVEL` | Log verbosity | `INFO` | | `PIPELINE_VERSION` | Enriched record version tag | `1.0.0` | ## Output schema Each enriched alert includes: - normalized input fields - `classification`, `criticality_score`, `summary`, `mitigation` - `mitre_techniques` - `frequency_24h` - `composite_risk_score` - `severity_band` - `processed_at` - `engine_mode` (`llm` or `fallback`) - `pipeline_version` ## Example behavior Input: Expected style of output: - Classification: `true_positive` - Criticality: high (90+) - Summary: likely LOLBin style abuse - Mitigation: isolate host, block C2, collect forensic artifacts - MITRE: `T1059.001` ## Design decisions - **Strict JSON prompt + parser guardrails**: LLM output is constrained and validated before acceptance. - **Deterministic fallback path**: demo and pipeline stay operational during model outages. - **Composite risk formula**: combines severity with recent recurrence: - `min(100, round(0.75 * criticality_score + 0.25 * min(frequency_24h*10, 100)))` - **JSON append store with lock**: simple and auditable persistence for project scope. ## Testing and CI Local: ruff check . pytest GitHub Actions (`.github/workflows/ci.yml`): - Python 3.11 - dependency install - Ruff linting - Pytest execution ## Engineering review points - Why schema normalization is critical before LLM inference. - How to harden LLM output with validation + retries + fallback. - Risk scoring tradeoffs and explainability. - Limitations of keyword MITRE mapping and next improvements. - Evolution path: queue-based ingestion, DB storage, SOC integrations, RBAC, model eval benchmarks. ## Limitations and roadmap Current limitations: - heuristic MITRE mapping - JSON-file storage instead of database - no distributed workers or real-time queueing Next steps: 1. Add async worker queue (Celery/RQ/Kafka). 2. Move persistence to PostgreSQL/Elasticsearch. 3. Add alert de-duplication and suppression policies. 4. Add analyst feedback loop for model tuning. 5. Add evaluation dataset and precision/recall tracking. ## Demo assets - Sample alerts: `data/sample_alerts.json` - Screenshot checklist: `screenshots/README.md` - Posting runbook: `scripts/capture_demo_checklist.md`