Skip to main content
Thumper ships as one Docker image with three parts - a UI, a server, and the endpoint agent - and two plugin seams, deploy and alert.

Components

UI

React + Vite + TypeScript. Talks only to the server. Dashboard, Tripwires (with the install command and per-endpoint instances), Endpoints, Integrations (config forms rendered from each plugin’s manifest).

Server

FastAPI. Serves the JSON UI contract and the plain-text agent protocol, generates honeytokens, signs/verifies callbacks, and fans alerts out through plugins.

Agent

Pure Bash (curl + openssl), delivered by a deploy plugin. Enrolls, pulls its unique instances, plants them, and watches for reads.
The server is organized into focused modules: api/routes.py (endpoints), db.py / store.py (the database seam), models.py (Pydantic schemas that mirror the UI’s types), tokens/ (honeytoken generators + the recommended-path catalog), plugins/ (the framework), and services/ (deploy, alerting, signing, content rendering, integrations).

Data model

The model is definition → instance - see Core concepts for the full vocabulary.

Tripwire - the definition

A credential recipe (name, token_type, path, source) that lives on no machine.

Endpoint - a self-enrolled machine

A box that ran an install command and registered itself (hostname, platform).

Deployment - one tripwire x one endpoint

Deploying a tripwire mints one deployment per endpoint, each with its own bait content and own HMAC secret - so a leak on one box can’t forge another’s triggers, and a read is attributable to exactly one endpoint.

Alert - the verified read

On a read, the agent fires an HMAC-signed, enriched callback; the server records an alert and fans it out to SIEM / EDR / webhook.

Database

The store is built on SQLAlchemy + Alembic, so the schema is portable and versioned. SQLite ships in the monolith with zero setup. Swap the backend by how far you need to go:
  • Different file/location - set THUMPER_DB to a SQLAlchemy URL pointing at another SQLite file.
  • Different engine - point THUMPER_DB at PostgreSQL or MySQL. The engine is selected from that URL; SQLite-specific PRAGMAs (WAL, foreign keys) are applied only when the dialect is SQLite. Alembic migrations bring any supported engine to the current schema on startup.

Plugins

Deploy and alert are both plugin seams. Drop a directory under plugins/{deploy,alert}/<name>/ with a manifest.yaml and a plugin.py, and the loader discovers it on startup - its config_schema is rendered into a UI config form automatically. See Writing a plugin.