Autonomous Tier 1 SOC triage — from raw packets to RFC-grounded diagnosis.
ZeekSight is an autonomous Tier 1 SOC triage agent that automates the first-response workflow of a Security Operations Center analyst.
It ingests raw packet captures, processes them through Zeek to generate structured network logs, detects anomalies using signature-based detection, retrieves authoritative RFC documentation via a pgvector RAG pipeline, and generates structured triage reports grounded in protocol standards — all without human intervention.
Designed to replace the 30–60 minute manual triage cycle that Tier 1 analysts spend staring at raw Zeek logs with an autonomous agent that diagnoses, classifies, and escalates in seconds.
ZeekSight implements two agent paths:
| Path | Trigger | Retrieval |
|---|---|---|
| Known attack | Signature match | Deterministic pre-retrieval from pgvector |
| Unknown pattern | No signature match | LLM-driven tool calling via agentic loop |
Evaluated using DeepEval 4.0.7 with Gemma 4 12B as the LLM judge via LM Studio.
| Metric | Score | Threshold | Status |
|---|---|---|---|
| Contextual Precision (RAG) | 1.0 | 0.7 | ✓ Pass |
| Contextual Recall (RAG) | 1.0 | 0.7 | ✓ Pass |
| Faithfulness (Agent) | 1.0 | 0.7 | ✓ Pass |
| Answer Relevancy (Agent) | 1.0 | 0.7 | ✓ Pass |
| SYN Flood Detection Confidence | 0.99 | — | — |
Note: Scores reflect a well-scoped single-attack scenario. Broader eval coverage across multiple attack types and normal traffic baselines is in the roadmap.
| Component | Choice | Rationale |
|---|---|---|
| Vector store | pgvector (PostgreSQL) | Production-grade, updateable, no vendor lock-in |
| Index | HNSW | High accuracy, scales as corpus grows, better than IVF for small-medium corpora |
| Chunking | TOC-based semantic chunking | RFC section boundaries are natural semantic units |
| Overlap | 200 character overlap | Preserves context at section boundaries |
| Embeddings | nomic-embed-text (LM Studio) | Local, free, 768-dim |
| RFC | Title | Role |
|---|---|---|
| RFC 9293 | Transmission Control Protocol | TCP specification, state machine |
| RFC 4987 | TCP SYN Flooding Attacks | Primary SYN flood reference |
| RFC 3552 | Security Considerations Guidelines | Meta-document for cross-RFC semantic grounding |
{
"attack_type": "SYN Flood",
"confidence": 0.99,
"severity": "CRITICAL",
"explanation": "The connection metrics show a massive volume of half-open connections (S0)
originating from 37,621 unique source IPs targeting a single destination
port (25565). This aligns with RFC 4987, which describes a SYN flooding
attack as a denial-of-service method that exploits TCP state retention to
exhaust the backlog of half-open connections.",
"rfc_citation": "RFC 4987, Section 1 and Section 2",
"recommendation": "ESCALATE",
"timestamp": "2021-04-28T10:30:44Z"
}ZeekSight uses a signature-based detection system with mathematically-derived confidence scores.
ATTACK_SIGNATURES = {
"SYN Flood": {
"conditions": {
"s0_rate": (">", 0.8), # half-open connection rate
"unique_src_ips": (">", 50), # spoofed source diversity
},
"proto": "tcp",
},
"Port Scan": {
"conditions": {
"unique_dst_ports": (">", 100),
"unique_src_ips": ("==", 1),
},
"proto": "tcp",
},
}Confidence is derived from how strongly observed metrics exceed signature thresholds:
score per condition = min(observed / threshold, 1.0)
confidence = mean(condition scores), capped at 0.99
This is a signature match confidence, not a probability estimate. Adding a new attack type requires only a dictionary entry — no code changes.
ZeekSight monitors conn.log in real time using a time-window aggregation strategy:
Watchdog thread → detects file changes → appends to buffer (thread-safe)
Analysis thread → wakes every 10s → drains buffer → computes metrics
→ threshold check → invokes agent if suspicious
→ cooldown (30s) prevents duplicate alerts
This ensures S0 rate is calculated over a meaningful sample window, not per-line, avoiding alert fatigue from repeated firing on the same attack episode.
zeeksight/
├── agent/
│ ├── agent.py # LangGraph graph, nodes, routing
│ ├── tools.py # Deterministic tool definitions
│ └── rag.py # pgvector ingestion and retrieval
├── rag_corpus/
│ ├── rfc9293.txt
│ ├── rfc4987.txt
│ └── rfc3552.txt
├── pcaps/
│ └── synflood.pcap
├── logs/ # Zeek output directory
├── dataframes/ # Parsed CSVs
├── evals/
│ ├── test_unit.py # Unit tests (no external deps)
│ ├── test_rag.py # RAG retrieval evals
│ └── test_agent.py # Agent triage evals
├── docs/
│ └── assets/
│ └── zeeksight-architecture.png
├── monitor.py # Live monitoring loop
├── requirements.txt
├── .env.example
└── README.md
| Layer | Technology |
|---|---|
| Packet analysis | Zeek 8.2.0 |
| Log parsing | ZAT 0.4.9 + Pandas |
| Agent framework | LangGraph 1.2.6 |
| LLM | Gemma 4 12B QAT |
| Embeddings | nomic-embed-text via LM Studio |
| Vector store | pgvector 0.4.2 + HNSW |
| Time-series DB | InfluxDB 2.7 |
| Dashboard | Grafana |
| Evals | DeepEval 4.0.7 + Gemma 4 12B judge |
| Language | Python 3.14 |
Note: Due to local compute constraints, the same model family (Gemma 4 12B) was used for both inference and evaluation. Self-preference bias may inflate scores. Independent judge model evaluation is in the roadmap.
- Docker
- Python 3.11+
- Zeek 8.x
- LM Studio with
nomic-embed-textloaded
git clone https://github.com/Divyesh-Kamalanaban/zeeksight.git
cd zeeksight
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt# pgvector
sudo docker run -d \
--name pgvector \
--network bridge \
--restart unless-stopped \
-e POSTGRES_PASSWORD=zeeksight \
-e POSTGRES_DB=zeeksight \
-p 127.0.0.1:5432:5432 \
pgvector/pgvector:pg16
# InfluxDB
docker run -d --name influxdb \
-p 8086:8086 \
-e DOCKER_INFLUXDB_INIT_MODE=setup \
-e DOCKER_INFLUXDB_INIT_USERNAME=admin \
-e DOCKER_INFLUXDB_INIT_PASSWORD=zeeksight123 \
-e DOCKER_INFLUXDB_INIT_ORG=zeeksight \
-e DOCKER_INFLUXDB_INIT_BUCKET=zeeksight \
-e DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=your-token-here \
influxdb:2.7
# Grafana
docker run -d --name grafana \
-p 3000:3000 \
grafana/grafana:latestcp .env.example .env
# Edit .env with your credentialswget https://www.rfc-editor.org/rfc/rfc9293.txt -P rag_corpus/
wget https://www.rfc-editor.org/rfc/rfc4987.txt -P rag_corpus/
wget https://www.rfc-editor.org/rfc/rfc3552.txt -P rag_corpus/
python agent/rag.pymkdir -p logs
zeek -r pcaps/synflood.pcap Log::default_logdir=$(pwd)/logs
python agent/agent.py# Terminal 1
python monitor.py
# Terminal 2
zeek -r pcaps/synflood.pcap Log::default_logdir=$(pwd)/logs# Unit tests — no external deps required
pytest evals/test_unit.py -q
# RAG eval — requires pgvector + LM Studio
deepeval test run evals/test_rag.py
# Agent eval — requires full stack
deepeval test run evals/test_agent.py# .env.example
INFLUX_URL=http://localhost:8086
INFLUX_TOKEN=your_token_here
INFLUX_ORG=zeeksight
INFLUX_BUCKET=zeeksight
LOCAL_MODEL_API_KEY=lm-studio
LM_STUDIO_MODEL="google/gemma-4-12b-qat [Model of your choice]"
DEEPEVAL_RESULTS_FOLDER="./my_results"
CONN_LOG_PATH=logs/conn.log- Grafana dashboard with pre-built panels
- Docker Compose for one-command setup
- UDP flood and ICMP flood attack signatures
- Additional RFC corpus (RFC 4732 — DoS considerations)
- False positive rate benchmarking on normal traffic pcaps
- Multi-attack scenario eval coverage
Note: Grafana reporting works but no pre-built panels exist. Hence added in roadmap.
| Problem | ZeekSight |
|---|---|
| Tier 1 analysts spend 30–60 min per alert | Agent triages in seconds |
| Raw Zeek logs require expert interpretation | Plain English RFC-grounded explanation |
| Rule-based IDS gives no context | RAG retrieval cites authoritative standards |
| Alert fatigue from duplicate notifications | Time-window aggregation + 30s cooldown |
| Static detection rules don't scale | Signature dict — new attack = 8 lines of config |
- RFC 9293 — Transmission Control Protocol
- RFC 4987 — TCP SYN Flooding Attacks and Common Mitigations
- RFC 3552 — Guidelines for Writing RFC Text on Security Considerations
- Zeek Network Security Monitor
- SYN Flood Packet Captures
- Corelight — Production Zeek
MIT © Divyesh Kamalanaban
