Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

Verdict — SOC AI Assistant

Open-source, on-premise, AI-powered SOC alert triage tool.

Paste a raw alert → the pipeline extracts IOCs, queries threat-intel sources (VirusTotal, AbuseIPDB, OTX, Shodan, CVEDB…), and asks a local Llama 3.1 8B model to produce a structured verdict:

  • Classification — true_positive / false_positive / needs_investigation
  • Confidence — 0–100
  • Severity — critical / high / medium / low / info
  • Reasoning — short natural-language justification
  • MITRE ATT&CK techniques referenced
  • Next steps — actionable checklist for the analyst

Backed by a FastAPI + Postgres backend and a Next.js frontend with team groups, invitations, and in-app notifications.


Requirements

Hardware

  • 16 GB RAM minimum, 32 GB recommended (LLM lives in RAM/VRAM once loaded)
  • ~15 GB free disk (Docker images + Llama 3.1 8B model + deps)
  • CPU virtualization enabled in BIOS/UEFI (Intel VT-x / AMD-V) — Docker Desktop refuses to start without this. Check Get-CimInstance Win32_Processor → VirtualizationFirmwareEnabled should be True.
  • (Optional) NVIDIA or AMD GPU for fast LLM inference

OS

Windows 10 build 19041+ or Windows 11. This is a native Windows setup — no WSL required for the app itself, but Docker Desktop uses WSL2 internally.

Software (all installable via winget)

Tool Version Purpose
Git for Windows any recent version control
Python 3.11.x backend runtime
uv latest Python package manager (much faster than pip)
Node.js 20+ LTS frontend build + dev server
Docker Desktop 27+ Postgres + Redis containers
Ollama for Windows 0.24+ local LLM runtime

Free API keys (~10 minutes to register all)

Service URL Required?
VirusTotal https://www.virustotal.com/gui/join-us Recommended
AbuseIPDB https://www.abuseipdb.com/register Recommended
AlienVault OTX https://otx.alienvault.com/ Recommended
abuse.ch https://auth.abuse.ch/ Optional

Leaving a key blank just disables that connector — the pipeline still runs with whichever keys you provide. Shodan InternetDB + CVEDB need no key.


First-time setup

Copy-paste blocks in order into an admin PowerShell 7 window.

1. Install tools

winget install --id Git.Git -e
winget install --id Python.Python.3.11 -e
winget install --id OpenJS.NodeJS.LTS -e
winget install --id Docker.DockerDesktop -e
winget install --id Ollama.Ollama -e

# Install uv (fast Python package manager)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Close and reopen PowerShell so PATH updates are picked up. Verify:

python --version   # Python 3.11.x
uv --version
node --version     # v20+
docker --version   # 27+
ollama --version   # 0.24+

2. Enable WSL2 + Virtual Machine Platform (for Docker Desktop)

Docker Desktop needs these Windows features. Run as admin:

Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform -NoRestart
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux -NoRestart
wsl --install --no-distribution

Restart Windows after this step. On next login, launch Docker Desktop from the Start Menu and accept the EULA. Wait for the whale icon in the system tray to say "Docker Desktop is running".

3. Pull the LLM model

ollama pull llama3.1:8b   # ~5 GB, one-time
ollama run  llama3.1:8b "Reply with only: OK"   # sanity check

4. Start Postgres + Redis containers

docker run -d --name soc-postgres `
  -e POSTGRES_DB=socai `
  -e POSTGRES_USER=socai `
  -e POSTGRES_PASSWORD=changeme_dev_only `
  -p 5432:5432 `
  -v soc_pgdata:/var/lib/postgresql/data `
  --restart unless-stopped `
  postgres:16-alpine

docker run -d --name soc-redis `
  -p 6379:6379 `
  --restart unless-stopped `
  valkey/valkey:7-alpine

# Verify
docker exec soc-postgres pg_isready -U socai   # /var/run/postgresql:5432 - accepting connections
docker exec soc-redis    valkey-cli PING       # PONG

Both are set to unless-stopped, so once Docker Desktop launches on boot, these containers come back automatically.

5. Configure the backend

cd .\backend

# Copy the template, then edit .env with real API keys + a fresh JWT secret
Copy-Item .env.example .env
notepad .env

Inside .env:

  • Set JWT_SECRET to a fresh UUID: [guid]::NewGuid().ToString()
  • Paste your VirusTotal / AbuseIPDB / OTX keys

6. Backend: create venv, install deps, apply migrations

cd .\backend

uv venv --python 3.11
.\.venv\Scripts\Activate.ps1
uv pip install -e ".[dev]"

# Create the DB tables
alembic upgrade head

If Activate.ps1 complains about execution policy, run this once per user account: Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned.

7. Start the backend

uvicorn app.main:app --reload --host 127.0.0.1 --port 8000

Sanity check: http://localhost:8000/api/health → {"status":"healthy"} Full API docs: http://localhost:8000/docs

8. Configure + start the frontend

In a new PowerShell window:

cd .\frontend

# Copy the template (default value works out of the box)
Copy-Item .env.local.example .env.local

npm install
npm run dev

9. Log in

Open http://localhost:3000/login

The database is empty on first boot, so register a fresh user via the REGISTER tab, then log in.


Daily use — start the stack

Docker Desktop auto-starts Postgres + Redis on boot. So each morning:

# Terminal 1 — backend
cd .\backend
.\.venv\Scripts\Activate.ps1
uvicorn app.main:app --reload --port 8000

# Terminal 2 — frontend
cd .\frontend
npm run dev

Then open http://localhost:3000.


Try the CLI (no UI needed)

cd .\backend
.\.venv\Scripts\Activate.ps1

# Extract IOCs from a log file
python -m app.cli extract test_samples\rich_iocs.log

# Full triage: extract → enrich → LLM verdict (rich terminal output)
python -m app.cli triage  test_samples\rich_iocs.log

Project layout

soc-ai-assistant/
├── backend/                 # FastAPI + SQLAlchemy 2.0 + Alembic
│   ├── app/
│   │   ├── api/v1/          # auth, analyses, groups, invitations,
│   │   │                    # join_requests, notifications
│   │   ├── core/            # ioc extractor, enrichment connectors,
│   │   │                    # LLM client, pipeline, notification factory
│   │   ├── db/              # SQLAlchemy models + async session
│   │   ├── schemas/         # Pydantic request/response models
│   │   └── cli.py           # Click-based command-line interface
│   ├── alembic/versions/    # DB migrations
│   ├── tests/               # unit + integration + eval
│   └── test_samples/        # example alert logs for testing
│
├── frontend/                # Next.js 16 (App Router) + Tailwind + Zustand
│   ├── app/
│   │   ├── analyze/         # submit a new triage
│   │   ├── history/         # your own past analyses
│   │   ├── analyses/[id]/   # single-analysis detail
│   │   ├── groups/          # groups list + [id] detail
│   │   ├── notifications/   # in-app notifications
│   │   ├── login/           # login + register
│   │   └── profile/         # user profile
│   ├── components/          # AppShell + shadcn/ui primitives
│   └── lib/                 # api client, auth store, utils
│
└── deployments/             # (docker-compose for future production deploy)

Troubleshooting

docker: failed to connect to the docker API Docker Desktop isn't running. Launch it from Start Menu; wait for whale icon.

WSL2 is unable to start since virtualization is not enabled Reboot into BIOS/UEFI and enable Intel VT-x (Intel) or SVM Mode (AMD).

.venv\Scripts\Activate.ps1 : running scripts is disabled One-time fix: Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned.

ImportError: email-validator is not installed or python-multipart The venv is stale. Run uv pip install -e ".[dev]" again — they're pinned in pyproject.toml.

Ollama says GPU usage stays at 0% Update your GPU driver (AMD Adrenalin 24.x+ / latest NVIDIA), then restart Ollama from the system tray.

Frontend loads but every action returns "Failed to fetch" Backend isn't running or NEXT_PUBLIC_API_URL in .env.local doesn't match the backend's port. It should be http://localhost:8000 (no /api/v1 suffix — the frontend adds that itself).

Browser refresh on any page bounces me to /login Only happens on old builds — fixed in commit d2479ac. Update to main.


Ports used

Port Service
3000 Next.js frontend
5432 Postgres
6379 Redis (Valkey)
8000 FastAPI backend
11434 Ollama

What's not in this repo

The following are excluded on purpose and are recreated by the setup steps:

  • backend/.venv/ — Python virtual environment (created by uv venv)
  • backend/.env — secrets (create from .env.example)
  • frontend/node_modules/ — npm packages (npm install)
  • frontend/.next/ — Next.js build cache (created by dev server)
  • frontend/.env.local — client env (create from .env.local.example)
  • The Llama 3.1 8B model (~5 GB, pulled by ollama pull llama3.1:8b)
  • Postgres/Redis data volumes (created fresh by docker run)

License

Internal / TBD.