Alon Sentinel is a single-tenant, self-hosted, API-first monitoring service written in Rust.
One Sentinel installation serves one owner and can monitor many sites.
The Rust service is the product boundary. It owns:
- client-credentials authentication and bearer token issuance
- Sentinel admin user authentication and role-based permissions
- installation-scoped site management
- HTTP, SSL, TCP, DNS, and Heartbeat monitor configuration
- background execution of site checks
- incident lifecycle management (open on failure, resolve on recovery)
- public status page serving
- notification channel configuration and delivery
- Prometheus metrics endpoint
Client applications are expected to integrate with Sentinel over HTTP. A UI can be built in any stack as long as it follows the public API contract.
The stable public HTTP API is versioned under /v1.
- Contract overview: docs/api/README.md
- Machine-readable contract: docs/api/openapi-v1.yaml
The /v1 contract documents:
- authentication flow
- supported scopes
- request and response schemas
- status code and error semantics
- versioning and compatibility rules
- Rust stable (2024 edition) — install via rustup
- PostgreSQL 14+
CREATE DATABASE alon_sentinel_db;cp .env.example .envOpen .env and set the required values:
DATABASE_URL=postgresql://user:password@localhost/alon_sentinel_db
# 64 hex characters — generate with: openssl rand -hex 32
WEBHOOK_SECRET_ENCRYPTION_KEY=your_64_hex_chars_here
SEED_ADMIN_PASSWORD=a-strong-admin-passwordSee .env.example for the full reference.
cargo run --bin migrateThis applies all pending migrations and seeds the built-in roles (viewer, operator,
admin) and their permission sets.
cargo run --bin provision_admin_userCreates the admin user if it does not already exist and prints the credentials for
POST /v1/admin/auth/login. The command uses these environment variables:
| Variable | Default |
|---|---|
SEED_ADMIN_EMAIL |
admin@localhost |
SEED_ADMIN_PASSWORD |
Required; no default |
SEED_ADMIN_NAME |
Sentinel Admin |
SEED_ADMIN_ROLE |
admin |
Set them in .env or inline to override:
SEED_ADMIN_EMAIL=you@example.com SEED_ADMIN_PASSWORD=strongpassword cargo run --bin provision_admin_userSkip this step if you only need the admin UI. For programmatic or service-to-service access, provision an API client:
cargo run --bin provision_clientPrints the client_id and client_secret needed for POST /v1/auth/token. Defaults:
| Variable | Default |
|---|---|
SEED_CLIENT_ID |
sentinel-client |
SEED_CLIENT_SECRET |
sentinel-local-client-secret |
SEED_CLIENT_NAME |
Sentinel API Client |
Start the API server and the worker (each in its own terminal — see Runtime Entry Points below for all options):
cargo run --bin apicargo run --bin workerRun the HTTP API with:
cargo runor explicitly:
cargo run --bin apiWhen Sentinel is deployed behind a trusted reverse proxy, build and run the API with the
trusted-proxy feature so auth audit IPs are taken from the proxy-appended
X-Forwarded-For hop:
cargo run --bin api --features trusted-proxyRun background site checks and notification delivery workers with:
cargo run --bin workerWorkers also prune historical site_monitor_checks rows in the background. The retention
window and sweep behavior are configurable with:
SITE_MONITOR_CHECK_RETENTION_DAYS,
SITE_MONITOR_CHECK_RETENTION_INTERVAL_SECONDS, and
SITE_MONITOR_CHECK_RETENTION_BATCH_SIZE.
API and worker processes already run with separate sqlx pools. To reserve database
capacity for checks under API load, size them independently with
API_DB_MAX_CONNECTIONS / API_DB_MIN_CONNECTIONS and
WORKER_DB_MAX_CONNECTIONS / WORKER_DB_MIN_CONNECTIONS.
If you do not set them, both services fall back to the shared DB_MAX_CONNECTIONS and
DB_MIN_CONNECTIONS defaults.
Auth endpoints are also protected by an in-process per-IP rate limiter. Tune it with
AUTH_RATE_LIMIT_MAX_REQUESTS and AUTH_RATE_LIMIT_WINDOW_SECONDS.
/v1 is the current stable API line.
Within v1, Sentinel may add:
- new endpoints
- new optional response fields
- new optional request fields
- new scopes
Within v1, Sentinel will not make breaking changes such as:
- removing an existing endpoint
- removing a documented field
- changing the type or meaning of a documented field
- changing authentication requirements for an existing endpoint
- changing a successful response code for an existing operation
Breaking changes require a new versioned path such as /v2.