Projects
OT Triage
Now / Next / Never triage for OT/ICS vulnerabilities
Most vulnerability scores come from IT thinking: a high CVSS number means “patch it”. In an OT environment the better question is what do I do about this one, on this asset, given what protects it. I built OT Triage to answer that question and to show its work.
You give it a CVSS score or a full CVSS vector, optionally a CVE, and what you know about the asset: how critical it is, how exposed, whether a patch exists and what controls protect it. It answers NOW, NEXT or NEVER, and lists the reasons in plain language. It also shows the single change that would move the answer, so the logic is easy to explain to someone else.

An actively exploited CVE on an exposed crown-jewel asset: NOW, with the reasons and CISA's own guidance.
What it does
- Threat intelligence built in. Looks a CVE up in CISA's Known Exploited Vulnerabilities catalog and in EPSS. It shows CISA's required action, its reference links (only plain HTTPS links are clickable, and you always see the real domain), and the forensic-triage flag.
- CVSS vectors. Paste a CVSS 3.0, 3.1 or 4.0 vector and the score is filled in. Every possible base vector was checked against FIRST's official calculators.
- CISA ICS advisories. Shows which of CISA's published ICS advisories name a CVE, with a link to each one, what it says about a fix (a vendor fix, a mitigation only, or nothing yet) and the vendor's own steps in the vendor's words: the firmware to install, the setting to change, the workaround. This is context: it never changes the answer.
- Batch mode. Load a CSV of findings, filter by bucket, search, sort and export the ranked results. An asset inventory fills in criticality, exposure and controls, and an earlier export shows what is new, what moved and what was resolved.
- By asset. OT assets get patched in short outage windows, so one view groups the findings by asset: the worst bucket on each, and what could be handled on one visit. With a vendor, product and version in the inventory it also points at the advisories that may apply, and says which of them list your version as affected.
- Scanner imports. Turn an export from Nessus, Tenable, OpenVAS, Claroty, Nozomi or Dragos into findings and an asset inventory, with a preview of what is imported and skipped. Nothing is scored by the import and nothing leaves the machine. A scanner's own risk scores and exploitation flags are never used: the threat level comes from CISA's KEV catalog and EPSS. The Nozomi and Dragos readers are experimental (they follow published descriptions and have not been checked against a real export), and the Claroty reader has so far seen one report layout.
- Command line. The same ranking from a script or a scheduled job, with an exit code you can gate on.
- Offline first. The only network access is a threat-data update that you start yourself, over HTTPS, to three public sources: CISA's KEV catalog, EPSS and CISA's advisory repository. Nothing about your assets or findings ever leaves the machine.
- Explainable rules. The decisions behind the rules, and the reasons for each, are written down in the project's policy document, and the scoring thresholds are adjustable.
Built to be trusted
It is a security tool, so it is tested like one. The project has a written security test plan with archived reports, tests that feed it hostile files and hostile network responses, property-based fuzzing, and automated checks on every change (Linux and Windows, static analysis and a secret scan). It is pure Python with no third-party dependencies, so there is no dependency tree to audit.
The Now / Next / Never categories come from the framing Dragos has used in its annual ICS/OT Year in Review. The definitions and scoring rules here are my own and are documented in the repository.
Get it
The current version is 0.10.0. Each release has a portable bundle (ot-triage-0.10.0.zip) with a checksum file next to it. Unzip it anywhere and, on Windows, double-click OT Triage.pyw; everywhere else run python3 ot_triage_gui.py. It needs Python 3.12 or newer with Tkinter, and nothing else: no third-party packages and no .exe. The bundle is reproducible, so anyone can rebuild it from the tag and compare the checksum, and from 0.9.0 on it carries a signed build attestation that gh attestation verify can check.
If you are looking for places to learn more about OT security, there is also a curated list of free OT/ICS resources.
MIT licensed code. The OkieOTSec name and logo are not part of that license.