About Columbina: AI-Native EDR

Inspiration

Security Operations Centers are drowning. The average SOC receives 4,500+ alerts per day, yet over 50% are false positives. Tier-1 analysts spend their days triaging noise while real threats slip through. Meanwhile, attackers are moving faster than ever — the median breakout time is now under 60 minutes.

I asked: what if an AI agent could handle tier-1 triage — detecting threats, correlating events, investigating incidents, and learning from every interaction — so human analysts only touch what actually matters?

Columbina is my answer. Named after the smallest species of owl — always watching, surprisingly intelligent — it's an AI-native EDR that doesn't just alert, it understands.


What I Learned

Building an AI SOC agent taught me that detection is the easy part. The hard problems are:

  1. Context is everything. A PowerShell process alone isn't suspicious. PowerShell spawned by an Office macro, with encoded arguments, on a workstation that just received a phishing email? That's an incident. I learned to build correlation pipelines that stitch atomic signals into coherent attack narratives.

  2. LLMs need guardrails, not free reign. Early prototypes hallucinated threat assessments. I solved this by grounding the AI agent in structured detection rule matches, vector memory of past incidents, and RAG-retrieved IR runbooks — the LLM reasons about evidence, it doesn't invent it.

  3. Memory changes everything. Traditional EDRs treat each alert as independent. By embedding incidents into a vector store and retrieving similar past cases, Columbina builds institutional knowledge — it gets smarter with every investigation.

  4. Free infrastructure can go surprisingly far. The entire stack — FastAPI, React, SQLite, sentence-transformers for embeddings, and a fallback reasoning engine — runs on Render's free tier with zero cost.


How I Built It

┌──────────────┐    ┌──────────────┐    ┌──────────────┐    ┌──────────────┐
│   INGEST     │───▶│   DETECT     │───▶│  CORRELATE   │───▶│  INVESTIGATE │
│  (FastAPI)   │    │ (Rule Engine) │    │ (Graph-based)│    │  (LLM Agent) │
└──────────────┘    └──────────────┘    └──────────────┘    └──────────────┘
                                                                │
                                              ┌─────────────────┘
                                              ▼
┌──────────────┐    ┌──────────────┐    ┌──────────────┐
│   MEMORY     │◀───│  KNOWLEDGE   │    │   TRIAGE     │
│ (Vector DB)  │    │    (RAG)     │    │  (Dashboard) │
└──────────────┘    └──────────────┘    └──────────────┘

Backend: FastAPI (Python) with SQLAlchemy ORM, SQLite for storage, and a modular AI layer supporting sentence-transformers (local embeddings), AWS Bedrock, and OpenAI as pluggable providers.

Detection Engine: 10 built-in behavioral rules mapped to MITRE ATT&CK (T1003.001 LSASS dumping, T1059.001 PowerShell abuse, T1055 process injection, T1053.005 scheduled tasks, and more). Rules evaluate flat event dictionaries against condition trees — no regex, no signatures, just behavioral logic.

Correlation: Events are grouped by host_id, user_name, and process_tree into incidents. Each incident bundles related alerts with a composite severity score.

AI Investigation: When an incident is created, the AI orchestrator retrieves similar past incidents from vector memory, pulls relevant IR procedures from the Knowledge RAG store, and generates a triage recommendation (isolate / investigate / ignore) with a confidence score.

Memory: Incidents are embedded using all-MiniLM-L6-v2 (384-dim) and stored for semantic recall. The system also extracts "semantic facts" — structured observations like "PowerShell + encoded command on workstation ws-005 is a recurring pattern" — that persist across sessions.

Frontend: React 19 + TypeScript + Vite. SOC dashboard with severity histograms, triage queue, alert explorer with MITRE filtering, and a Knowledge tab for IR runbook management.

Data: I use the LogBERT security events dataset from HuggingFace — 25 sessions of structured security telemetry with labeled anomalies — to demonstrate the full pipeline end-to-end.


Challenges I Faced

1. The "empty dashboard" problem

Multi-tenant org isolation meant data ingested by one user was invisible to another. I had to trace the full auth → org → event → alert chain to ensure the admin could see all demo data.

Lesson: Test with the exact user flow you'll demo.

2. Embedding model tradeoffs

all-MiniLM-L6-v2 is fast and free but only 384 dimensions. AWS Bedrock (Titan) gives 1536-dim embeddings with better recall but requires cloud credentials. I built a pluggable provider abstraction so users can swap based on their needs.

3. LLM hallucination in security contexts

When the AI agent investigated incidents without grounding, it would confidently invent attack chains. I fixed this by constraining the LLM to only reason about structured evidence (rule matches, correlated events, memory recall) and cite its sources.

4. Realistic demo data

Most "cybersecurity datasets" on HuggingFace are blog posts and articles, not telemetry. I found the LogBERT dataset — structured process creation, network, and file events with anomaly labels — and wrote a transformation layer to map them into Columbina's canonical event schema with MITRE technique tagging.

5. Single-container deployment

Getting FastAPI to serve both the API and the React SPA from one container (for Render's free tier) required careful static file mounting and SPA fallback routing — every non-API route had to serve index.html while keeping /api/* and /health functional.


What's Next

  • Streaming ingestion — real-time event processing via Kafka/Redpanda
  • eBPF sensor — native host-level telemetry collection (prototype in sensor/ebpf/)
  • Multi-LLM reasoning — ensemble voting across Claude, GPT, and local models
  • Automated response playbooks — close the loop from detection → investigation → containment

Built by Aamira

Built With

Share this project:

Updates