LangChain-powered threat intelligence Q&A agent — runs fully locally via Ollama.
Pulls live threat feeds (MITRE ATT&CK, ThreatFox, AlienVault OTX), indexes them into a local vector store, and answers natural-language questions about threat actors, TTPs, IOCs, CVEs, and malware.
- Ollama running locally (
ollama serve) - Required models pulled:
ollama pull mistral:7b ollama pull nomic-embed-text
Local
pip install -r requirements.txt
cp .env.example .env # optionally add OTX_API_KEYDocker
cp .env.example .env # optionally add OTX_API_KEY
docker compose buildIngest live threat feeds (MITRE ATT&CK + ThreatFox + OTX if key set):
# local
python main.py ingest
# docker
docker compose run --rm threatlens ingestAsk a single question:
# local
python main.py ask "What TTPs does APT29 use?"
# docker
docker compose run --rm threatlens ask "What TTPs does APT29 use?"Interactive chat:
# local
python main.py chat
# docker
docker compose run --rm threatlens chatWeb dashboard (chat + IOC browser + MITRE technique browser):
# local
streamlit run dashboard.py
# docker
docker compose up dashboard
# then open http://localhost:8501Docker note: the dashboard container reaches Ollama on the host via
host.docker.internal. SetOLLAMA_BASE_URL=http://host.docker.internal:11434in.envwhen running under Docker.
ThreatLens/
├── chroma_db/ # vector store (auto-created on first ingest)
├── src/threatlens/
│ ├── feeds/
│ │ ├── mitre.py # MITRE ATT&CK techniques
│ │ ├── abusech.py # ThreatFox IOCs (last 7 days)
│ │ └── otx.py # AlienVault OTX pulses (optional)
│ ├── config.py # env-based configuration
│ ├── ingest.py # feed ingestion and embedding
│ ├── agent.py # RAG chain (Ollama + Chroma)
│ └── stats.py # Chroma metadata queries for the dashboard
├── main.py # CLI entry point
├── dashboard.py # Streamlit web dashboard
├── requirements.txt
├── Dockerfile
├── docker-compose.yml
└── .env.example
All settings can be overridden in .env:
| Variable | Default | Description |
|---|---|---|
OLLAMA_BASE_URL |
http://localhost:11434 |
Ollama server URL |
CHAT_MODEL |
mistral:7b |
Chat model (must be pulled in Ollama) |
EMBED_MODEL |
nomic-embed-text |
Embedding model (must be pulled in Ollama) |
OTX_API_KEY |
— | AlienVault OTX key (optional, free at otx.alienvault.com) |
CHROMA_PATH |
./chroma_db |
Vector store path |
CHUNK_SIZE |
500 |
Characters per chunk |
CHUNK_OVERLAP |
50 |
Overlap between chunks |
RETRIEVAL_K |
5 |
Documents retrieved per query |
