ThreatLens is a prototype Cyber Threat Intelligence
Indicator Quality Checker. It extracts candidate indicators of compromise
(IoCs) from CTI reports and feeds, organises them into a structured
repository, and checks them for quality issues — before handing the reader
an auditable quality_score for every indicator instead of a raw,
unfiltered dump.
Capstone project for ZEIT3118, UNSW Canberra (ADFA), Semester 2 2026, for client Dr. Clemens Sauerwein (University of Innsbruck).
Threat reports are full of candidate indicators — IPs, domains, hashes, URLs, file paths — but not everything that looks like an indicator is one, and not everything that is one is reported cleanly. The client's brief names three quality problems explicitly, and ThreatLens exists to demonstrably address them:
Whatever survives that screening is scored against the quality framework
adapted from the project's research paper, producing a 0–100
quality_score for every stored indicator, alongside — but never
conflated with — its 0–100 confidence of being malicious. Four
of the paper's five dimensions are scored: timeliness, accuracy, completeness
and relevance. The fifth, consistency, needs an external feed and is deferred
(see Quality Checker).
CTI report (PDF/text)
│
▼
Extraction Engine ──▶ candidate IoCs + context, verified by one engine per
│ run (Qwen LLM by default, or python heuristics)
│
├──▶ CLI (threatlens) ──▶ inspect one report: summary or JSON,
│ no database
▼
Quality Checker ──▶ structural rejection → STIX conformance →
│ false-positive screen → dimension scoring
▼
Database (SQLite via SQLAlchemy + Alembic)
│ sources, raw_documents, indicators, sightings,
│ quality_flags, allowlist, scoring_config
▼
Dashboard / Web UI ──▶ browse and triage the data; upload, ingest, configure
Reports reach the database through one ingest pipeline: extract, quality
checks, persist, rescore. The dashboard's Ingest page, the
threatlens-ingest command and the batch runner behind the
evaluation runs all use it. The
threatlens CLI stops after extraction: it shows what the engine
made of a single report, and its JSON output can be fed to the quality
checker's own command line to inspect that stage as well.
pip install "threatlens-cti[dashboard]",
or pip install -e ".[dashboard]" from a checkout (add
dev for the tests). The package carries
the dashboard's pages, these documentation pages and the database
migrations, and installs the threatlens,
threatlens-ingest, threatlens-calibrate and
threatlens-dashboard commands. The llm engine
also needs an Ollama server with the
verifier model pulled.threatlens init. It asks for
the data folder, Ollama URL (tested live), models (chosen from those the
server has pulled), dashboard address and optional quality weights, writes
them to threatlens.conf, creates the database, and can
calibrate the LLM settings for your hardware
(details). The file lives in the repo
root in a checkout and in the per-user config folder when pip-installed
(where files live); re-run the
wizard, use the dashboard's Configuration page, or edit the file to change
it later.threatlens-calibrate benchmarks the Ollama server and saves the
[llm] settings (details).
A database can likewise be created or upgraded on its own with
python -m threatlens.db.migrate
(details).threatlens-dashboard for the web UI
(these pages are at /docs/), threatlens-ingest
report.pdf to ingest from a terminal, or threatlens
report.pdf to inspect one report.Until setup and calibration are done, the commands and the dashboard print a
warning naming the missing step (and, in a terminal, offer to run
threatlens init) and carry on with built-in defaults (see the
setup check).
Pulls candidate IoCs and document metadata out of a CTI report, then verifies them — either with local Python heuristics or an Ollama-hosted LLM.
Owner: Technical Lead (Ben King) · Read more →
The seven-table SQLite repository (SQLAlchemy + Alembic) that the ingest pipeline writes to and the dashboard reads, and the STIX/MISP/OpenCTI design lineage behind it.
Owner: Project Lead (Tyler Passey) · Read more →
The four-layer pipeline — structural rejection, STIX conformance, false-positive screening, dimension scoring — that turns raw candidates into a scored, auditable indicator.
Owner: QA Lead (Ethan McLachlan) · Read more →
A FastAPI app over the live database: browse and triage indicators, reports and quality flags, upload and ingest reports, export data as CSV, JSON or STIX 2.1, and edit the per-machine configuration.
Owner: Project Lead (Tyler Passey) · Read more →
The threatlens command: runs one report through extraction
and verification and prints a summary or writes the full result as JSON,
without touching a database. Also covers threatlens-calibrate,
the single threatlens.conf and its setup check.
Results from full runs over the 103-report CTI corpus: a run report (timing, extraction funnel) and a comparison of LLM output across runs.
No threat actor / campaign / kill-chain graph modelling, no inter-indicator relationships, no intelligence sharing between organisations, no external enrichment (VirusTotal, AbuseIPDB). These are OpenCTI territory and are noted as future work rather than built.
Status key Pages marked Written are the full explanation for that component. Pages marked Stub are placeholders — a short, accurate summary and pointers into the source — pending the full write-up.
ThreatLens is free software, licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). Copyright © 2026 Tyler Passey, Ben King and Ethan McLachlan.