Skip to content
Nick Wilkinson edited this page Jul 6, 2026 · 4 revisions

Server

trove-server is the central process. It accepts agent reports, stores the catalog, serves the dashboard, exposes read-only APIs, and runs the background workers.

Source areas:

  • cmd/trove-server/main.go
  • internal/server
  • internal/store
  • internal/alert
  • internal/registry
  • web

HTTP routes

The server registers these routes:

Method Path Auth Purpose
POST /api/v1/report Agent bearer token Ingest one full-state report from an agent.
GET /api/v1/services none List catalog services for the dashboard/API.
GET /api/v1/agents none List agents and last-seen status.
GET /api/v1/events none List recent activity events.
GET /healthz none Basic health endpoint.
GET / none Embedded dashboard SPA.

Only /api/v1/report is authenticated in the current phase.

The dashboard and read APIs should be treated as private. Bind them to a trusted network or put them behind an authenticating reverse proxy.

Report ingest

Report ingest happens in internal/server/ingest.go.

The handler:

  1. caps request bodies at 8 MiB
  2. decodes JSON into model.Report
  3. validates the report contract
  4. calls store.ApplyReport
  5. returns { "ok": true, "services": N }

Invalid JSON or invalid model data returns 400. Invalid/missing token returns 401. Store failures return 500.

Agent authentication

Agent authentication uses bearer tokens.

Authorization: Bearer trove_...

Tokens are created with:

trove-server agent create <agent-name>

The plaintext token is shown once. Trove stores a SHA-256 hash in SQLite, not the token itself.

At request time, the presented token is hashed and looked up. The matched hash is confirmed with constant-time comparison.

Bootstrap agent

Compose examples can seed a first agent with:

  • TROVE_BOOTSTRAP_AGENT
  • TROVE_BOOTSTRAP_TOKEN

This is useful for a first install where the server needs to accept an agent before the operator has run agent create interactively.

If an agent with that name already exists, bootstrap is idempotent and leaves the existing token alone.

Background workers

Staleness loop

The staleness loop evaluates agent heartbeat state from last_seen_at and report_interval_seconds.

General behaviour:

  • never-seen agents are unknown
  • normal recent agents are ok
  • agents that miss enough pushes become stale
  • agents that miss more become offline

When an agent changes heartbeat state, the server records an agent event.

When an agent is stale or worse, the server also marks that agent's services as health="stale". This avoids pretending services are healthy when the agent is no longer reporting.

Freshness loop

The freshness loop resolves latest image digests from registries and caches them in image_checks.

See Image-Freshness.

Maintenance loop

The maintenance loop prunes old history:

  • old events, controlled by TROVE_EVENT_RETENTION
  • old removed services, controlled by TROVE_REMOVED_RETENTION

This is deliberately not done on the report ingest write path.

Alert engine

The alert engine reads events and sends instant notifications through configured channels.

See Alerts-and-Digest.

Digest scheduler

The digest scheduler checks once per minute whether an email digest is due.

See Alerts-and-Digest.

Embedded dashboard

The dashboard is served from the embedded web filesystem.

There is no separate frontend build service required at runtime. The server binary includes the static assets.

Database location

The server uses TROVE_DB to find its SQLite database.

Common examples:

TROVE_DB=/data/trove.db
TROVE_DB=/var/lib/trove/trove.db

Back this file up. It contains the agent list, token hashes, service catalog, events, image check cache, and alert state.

Clone this wiki locally