Real-Time SIEM Dashboard with AI-Powered Alert Analysis
Specter is a real-time security dashboard that connects to your Wazuh SIEM and Suricata IDS. It streams live alerts with severity-based color coding and includes an AI chat panel (Claude) that can autonomously search your historical alerts to provide context-aware threat analysis.
Specter is one of four open-source security tools published by CarbeneAI, alongside Harbinger (AI threat intel), Talon (AI-assisted offensive workflows), and Forge (AI operations platform).
CarbeneAI builds open-source tooling for security operations and teaches practitioners to build their own. These repos are the working reference.
Use this repo. Fork it. Improve it. More at carbene.ai
- Deterministic Scorer - Rules-only pre-triage that scores every alert 0-100 and bands it critical/high/medium/low/noise before any LLM is called. No API key, no network call, so it keeps working when the AI chat is unconfigured. Every weight lives in one documented constant.
- Investigation Ledger - Every AI investigation persisted as a replayable record: system prompt, each tool call and its result, final analysis, token counts, timing. Addressable by permalink. The receipt that makes autonomous response auditable after the fact.
- Live Alert Streaming - WebSocket-based real-time alert feed from Wazuh Indexer (polls every 30s)
- Severity Color Coding - CarbeneAI dark theme with Critical/High/Medium/Low visual hierarchy
- AI Security Analyst - AI-powered chat that autonomously searches Wazuh for historical context
- Cloud/Local AI Toggle - Switch between Anthropic Claude (cloud) and Ollama (local) with one click. Keep sensitive SIEM data on your network.
- Analyst Guidance Mode - AI responses are structured to mentor junior analysts: What is this? Why does it matter? How do I know? What do I do next? What should I watch for?
- Markdown Rendering - AI responses render with full markdown: headers, bold, code blocks, lists, and blockquotes via marked.js
- Alert Suppression - Suppress noisy Suricata SIDs or Wazuh rules directly from the UI
- Alert Filtering - Filter by severity, agent, and rule group
- Resizable Split-Screen - Drag to resize the alert feed and chat panel
- MITRE ATT&CK Mapping - Full attack chain mapping with technique IDs, detection opportunities, and ATT&CK Navigator heatmaps
- MITRE D3FEND Countermeasures - Defensive technique recommendations mapped to detected threats (Detect, Isolate, Deceive)
- Compliance Tags - PCI DSS, HIPAA, GDPR, NIST 800-53 tags on alerts
- HTTP Ingest - Accept alerts via POST endpoint (useful with n8n webhooks)
Live alert feed with severity color coding, alert suppression, and the AI chat panel.
Switch between Anthropic Claude (cloud) and Ollama (local) with one click. Configure your Ollama URL and model in the settings panel. Data stays on your network.
The AI walks analysts through structured triage: What is this? Why does it matter? How do I know? Markdown rendering with headers, code blocks, and formatted lists.
Prioritized remediation steps with exact commands, compliance references, and escalation guidance.
Indicator of compromise extraction with severity-based escalation and attack pattern identification.
Complete attack chain mapping with technique identification, tactic classification, and detection opportunities.
Defensive technique recommendations mapped to detected threats, including detection, isolation, and deception strategies with ATT&CK Navigator heatmaps.
Data source identification, pseudo-detection rule generation, and attack pattern relationship mapping.
| Component | Technology |
|---|---|
| Runtime | Bun |
| Frontend | Vue 3 + Vite + Tailwind CSS |
| Backend | Bun HTTP + WebSocket server |
| AI | Anthropic Claude API (tool use) or Ollama (local) |
| Theme | CarbeneAI dark (cyan/purple) |
| Icons | Lucide Vue |
- Bun v1.0+
- Wazuh SIEM instance (self-hosted)
- Anthropic API key (for cloud AI chat) or Ollama (for local AI)
- SSH access to Suricata/Wazuh hosts (optional, for rule suppression)
git clone https://github.com/CarbeneAI/Specter.git
cd Spectercp .env.example .envEdit .env and set at minimum:
WAZUH_DASHBOARD_URL=https://your-wazuh-server
WAZUH_DASHBOARD_PASSWORD=your-admin-password
ANTHROPIC_API_KEY=sk-ant-...cd apps/server && bun install
cd ../client && bun install
cd ../.../manage.sh startSee docs/setup.md for complete setup instructions including:
- Connecting to your Wazuh instance
- Configuring SSH for rule suppression
- Setting up as a systemd service
- Production deployment behind a reverse proxy
Every alert is scored before the LLM is ever consulted. This is deliberate: LLM calls cost money and latency, and most alerts don't need one. The scorer is pure, has no dependencies, reads no secrets, and makes no network calls.
Signals, all in SCORER_WEIGHTS in apps/server/src/scorer.ts:
| Signal | Effect | Reasoning |
|---|---|---|
Wazuh rule.level |
+10 to +90 | Dominant signal. Rule authors already tuned severity; start there rather than re-deriving it. |
| MITRE ATT&CK mapping present | +10 | The rule was vetted against real adversary behavior. Absence is never a penalty, only less enrichment. |
| High frequency, same srcip + rule | -40 | Alert fatigue, not an incident. Flat penalty so one very noisy source can't swing the score further than a merely noisy one. |
Rule group in SUPPRESSED_GROUPS |
-20 | Already-classified routine noise. |
The frequency downweight only fires on low and medium severity. A repeating critical or high alert is an active incident, not noise, and frequency alone must never demote it. That gate is the kind of thing that is obvious in hindsight and expensive to learn in production.
Swap in your own model by implementing ScoringBackend and calling registerScoringBackend() once at startup. No other call site changes.
Specter's AI chat used to be ephemeral: the reasoning, the evidence, and the tool calls vanished when the tab closed. The ledger persists each investigation to SQLite (bun:sqlite, no new dependency) as an ordered sequence of steps, replayable at /ledger/:id.
It records the system prompt, every tool call with its arguments and result, the final analysis, model, token usage, and duration. sk-ant- patterns are scrubbed before insert as defense in depth. All queries are parameterized; the :id route validates UUID shape by regex before SQLite is touched at all.
Ledger writes are fail-open: a SQLite failure logs and is swallowed, never breaking the chat response. Only the Anthropic path is recorded, because the Ollama path has no tool-use loop and therefore no multi-step investigation to reconstruct.
This is the part that matters for autonomous response later. An action a machine took without asking is only defensible if you can reconstruct why it took it.
Full design, schema, and testing strategy: docs/architecture-scorer-ledger.md.
When you click an alert and use the chat panel:
- The selected alert is included as context in the system prompt
- The AI structures responses to guide analyst thinking (What/Why/How/Next/Watch)
- Claude can call
search_wazuh_alertstool to query your Wazuh Indexer for historical data (cloud mode) - Up to 3 tool call iterations for deep correlation
- Quick actions: Analyze, Remediation, Related alerts, IOCs, MITRE ATT&CK/D3FEND mapping
Use the Cloud/Local toggle in the chat panel header to switch providers:
| Cloud (Anthropic) | Local (Ollama) | |
|---|---|---|
| Model | Claude Sonnet | Any Ollama model (llama3.1, gemma4, etc.) |
| Data privacy | Sent to Anthropic API | Stays on your network |
| Wazuh search | Autonomous tool use | Not available |
| Speed | Fast | Depends on model size and hardware |
| Cost | API usage fees | Free (your hardware) |
Ollama setup: Click the gear icon when Local is selected to configure the Ollama URL and select a model. Settings persist across sessions. Smaller models (8B) respond in seconds; larger models (30B+) may take over a minute.
Two suppression mechanisms:
- Suricata SID: Updates
disable.confvia SCP, runssuricata-update, reloads rules - Wazuh Rule: Adds
level="0" overwrite="yes"tolocal_rules.xml, restarts Wazuh manager
Requires SURICATA_SSH_HOST and WAZUH_SSH_HOST env vars with SSH key auth configured.
| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Health check |
| GET | /alerts/recent?limit=100 |
Recent alerts |
| GET | /alerts/stats |
Counts by severity |
| GET | /alerts/filter?severities=critical,high |
Filtered alerts |
| GET | /alerts/scored?band=noise&limit=100 |
Scored alerts, optionally filtered by band |
| GET | /ledger?limit=50 |
List recent investigations |
| GET | /ledger/:id |
Replay one investigation (UUID only) |
| POST | /alerts/ingest |
Ingest alert(s) via HTTP |
| POST | /chat |
AI chat message |
| GET | /chat/prompts |
Quick prompt templates |
| POST | /alerts/search |
Search Wazuh Indexer |
| POST | /alerts/suppress |
Suppress a rule |
| GET | /alerts/suppressed |
List suppressed rules |
| GET | /settings/ollama-models?ollamaUrl=... |
List available Ollama models |
| WS | /stream |
Real-time alert stream |
./manage.sh start # Start dashboard
./manage.sh stop # Stop dashboard
./manage.sh restart # Restart
./manage.sh status # Check if running
./manage.sh logs # View recent logsSee docs/deployment.md for systemd service setup.
- OhMyPCAP — Standalone PCAP analyzer by Doug Burks (Security Onion). Pairs naturally with Specter: when an alert needs packet-level investigation, drop the PCAP into OhMyPCAP for Suricata alerts, flow/DNS/HTTP/TLS metadata, ASCII transcripts, hexdumps, and stream carving. Self-host with the docker-compose manifest in homelab-deploy/ohmypcap/, or try the public demo at securityonion.net/pcap.
Hover any Suricata alert row → click the download (FileDown) icon in the action gutter. A panel pops up with a copy-paste shell command that:
- SSHes to the Suricata host
- Locates the rotating PCAP file matching the alert's timestamp
- Carves only the alert's flow (BPF:
host SRC and host DST) - Streams the resulting
.pcapstraight to~/Downloads/alert-<flow_id>.pcapon your laptop
Drop that file into OhMyPCAP for full analysis.
Requires: Suricata's pcap-log output enabled with conditional: alerts and mode: normal (uncompressed). The button only appears for Suricata alerts where srcip and dstip are populated. Override the SSH target with VITE_PCAP_SSH=user@host at build time.
Specter currently analyzes and explains alerts. The next phase is autonomous response.
Automatically classify incoming alerts by severity and urgency. Filter noise so analysts only see what matters. Correlate related alerts into incidents instead of showing individual events.
For each alert, generate actionable remediation steps specific to your environment — not generic advice, but commands you can run, configs you can change, and rules you can deploy.
Execute AI-recommended fixes directly from the dashboard with user approval. SSH brute force detected? One click to block the IP, harden SSH config, and verify fail2ban is active.
For trusted alert patterns with known-safe remediations, let the AI act without waiting for approval — then notify you after. A SOC analyst that never sleeps and never gets alert fatigue.
This isn't hypothetical. The autonomous response workflow has already been tested manually. Suricata detected 1,500+ SSH brute force attempts against a production server, and Claude Code responded by hardening SSH configuration, verifying fail2ban was active, adding firewall rules, and whitelisting trusted IPs. The entire incident was handled in a single AI conversation. Specter's roadmap is about packaging that capability into the dashboard.
The architectural case for moving detection and response onto the agent, including the parts that break when you do and the parts that are not solved, is published in full at endpoint-mesh. No patents, no restrictions. Any open-source security project is free to implement it.
Pull requests welcome. Please open an issue first to discuss major changes.
MIT - see LICENSE
Built by CarbeneAI







