project file / 06 / Threat-intelligence workbench
Omnissiah
A self-hosted place to connect security APIs, build and run queries, collect intelligence, map it to ATT&CK, and keep credentials out of the query definitions.
Working version 2
Omnissiah is a security operator’s workbench for APIs and threat intelligence. It keeps connections, queries, credentials, feeds, intelligence items, ATT&CK data, code repositories, and workflows in one self-hosted application.
It started as API tooling and grew outward. The frontend now has separate views for connections, query libraries, feeds, credentials, intelligence, MITRE ATT&CK, code repositories, administration, and dashboards. REST and GraphQL queries can be written directly, imported from cURL, or generated from an OpenAPI document.
Why the name
The name is a direct nod to Warhammer 40,000. In that universe, the Omnissiah is the machine-god figure revered by the Adeptus Mechanicus. It felt right for a security workbench built around machines, collected knowledge, exact commands, and an unreasonable number of cables.
Where it sits in the workshop
Omnissiah is not one of the sister agents. It is the security workbench built beside them. Aria and the Cadre family explore local agents, memory, and autonomy; Omnissiah is aimed at the day job of querying security systems and organizing threat intelligence.
How it is put together
FastAPI exposes one router per domain and SQLAlchemy stores the data in SQLite. The React 19 interface uses Monaco for query editing and Recharts for visual summaries. MISP events, TLP markings, and ATT&CK objects have purpose-built views rather than being flattened into generic JSON.
Authentication uses signed JWTs and bcrypt password hashes. Stored API credentials are encrypted with Fernet and referenced by connections and workflows. Current routers scope records to the authenticated user.
What matters in the design
- Queries and secrets are separate objects. A saved query can refer to a credential without copying the secret into its definition.
- The intelligence formats keep their shape. MISP, TLP, and ATT&CK each get handling that matches how security teams use them.
- Schema changes are visible. Features arrived through named migration scripts, which makes the database history readable even before a full migration framework is added.
- The security work is real but not finished. The code has user scoping and encrypted credentials. The repo still needs broader automated coverage, formal migrations, and a deployment hardening pass before it should be called production-ready.
- The interface favors operators. The main work happens in queries, trees, editors, and source records. Charts support that work instead of replacing it.
architecture / high-level view
How the pieces connect
These maps leave out implementation detail on purpose. They show the boundaries and paths that explain the project.
Queries stay separate from encrypted credentials while purpose-built intelligence records keep their original security meaning.
Drawing system map...
flowchart TD Operator["Security operator"] --> UI["React + Monaco workbench"] UI --> Auth["JWT-authenticated FastAPI routers"] Auth <--> DB["Per-user SQLite records"] Auth --> Runner["Query + workflow runner"] Vault["Fernet-encrypted credentials"] --> Runner Queries["Saved queries without secrets"] --> Runner Runner <--> APIs["REST + GraphQL APIs"] Feeds["RSS + MISP feeds"] --> Intel["Threat-intelligence ingestion"] APIs --> Intel Intel --> Formats["MISP + TLP + ATT&CK records"] Formats --> DB DB --> UI
Read this diagram as text
- A security operator works through the React and Monaco interface and authenticated FastAPI routers.
- Saved queries remain separate from Fernet-encrypted credentials when the runner calls REST or GraphQL APIs.
- API results, RSS, and MISP feeds enter the threat-intelligence pipeline.
- MISP, TLP, and ATT&CK records keep their purpose-built shapes in per-user SQLite storage and return to the workbench.