> ## Documentation Index
> Fetch the complete documentation index at: https://docs.jesta.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture

> How Thumper is put together.

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

<CardGroup cols={3}>
  <Card title="UI" icon="browser">
    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).
  </Card>

  <Card title="Server" icon="server">
    FastAPI. Serves the JSON UI contract and the plain-text agent protocol,
    generates honeytokens, signs/verifies callbacks, and fans alerts out through
    plugins.
  </Card>

  <Card title="Agent" icon="terminal">
    Pure Bash (`curl` + `openssl`), delivered by a deploy plugin. Enrolls, pulls
    its unique instances, plants them, and watches for reads.
  </Card>
</CardGroup>

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](/thumper/concepts)
for the full vocabulary.

<Steps>
  <Step title="Tripwire - the definition" icon="pen-to-square" iconType="solid">
    <Icon icon="pen-to-square" color="#3b82f6" size={20} /> A credential recipe
    (`name`, `token_type`, `path`, `source`) that lives on no machine.
  </Step>

  <Step title="Endpoint - a self-enrolled machine" icon="server" iconType="solid">
    <Icon icon="server" color="#8b5cf6" size={20} /> A box that ran an install
    command and registered itself (`hostname`, `platform`).
  </Step>

  <Step title="Deployment - one tripwire x one endpoint" icon="location-dot" iconType="solid">
    <Icon icon="location-dot" color="#c9a227" size={20} /> 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.
  </Step>

  <Step title="Alert - the verified read" icon="bell" iconType="solid">
    <Icon icon="bell" color="#ef4444" size={20} /> On a read, the agent fires an
    HMAC-signed, enriched callback; the server records an alert and fans it out to
    SIEM / EDR / webhook.
  </Step>
</Steps>

## 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](/thumper/writing-plugins).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.