Environment configuration
The file bridge can't write .env files, so copy these by hand.
Append to your dev .env
# โโโ Telemetry store โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# postgres (default, dev) | clickhouse (production / SaaS)
TELEMETRY_STORE=postgres
CLICKHOUSE_URL=http://localhost:8123
CLICKHOUSE_DB=sentinel
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=
# Optional read replica for dashboard queries (managed PG providers hand these out)
# DATABASE_REPLICA_URL=
# โโโ Retention โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
RETENTION_LOGS_DAYS=30
RETENTION_METRICS_DAYS=400
Create .env.production from this template
POSTGRES_DB=sentinel
POSTGRES_USER=sentinel
POSTGRES_PASSWORD=change-me
CLICKHOUSE_DB=sentinel
CLICKHOUSE_USER=sentinel
CLICKHOUSE_PASSWORD=change-me
# Public URL the browser uses to reach the API
PUBLIC_API_URL=https://api.sentrinel.example.com
# Optional managed-Postgres read replica
DATABASE_REPLICA_URL=
RETENTION_LOGS_DAYS=30
RETENTION_METRICS_DAYS=400
Trying the ClickHouse path locally
docker compose --profile ch up -d # Postgres + ClickHouse
bun run --cwd packages/db ch:migrate # apply ClickHouse schema
# set TELEMETRY_STORE=clickhouse in .env, then:
bun run dev
curl localhost:3001/health # โ telemetryStore: "clickhouse"
New in the completed roadmap
# โโโ Authentication & multi-tenancy โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# Leave unset for a single-user self-hosted install. Set to true for a SaaS
# deployment: the dashboard API then requires a session AND scopes every query
# to the caller's organization. Ingest, cron check-ins, and public status pages
# are always exempt (they carry their own credentials).
SENTRINEL_REQUIRE_AUTH=true
# Self-serve signup is on by default and gives each new account its own
# organization. Set this to lock a private deployment to invite-only โ the very
# first account can always be created, or there'd be no way in.
# SENTRINEL_DISABLE_SIGNUP=true
What SENTRINEL_REQUIRE_AUTH=true changes
| off (default) | on | |
|---|---|---|
| Dashboard API | open | 401 without a session |
?appId= from another org |
served | 403 |
| Unscoped lists (apps, issues, alerts, keysโฆ) | everything | only your org's |
| Live tail (SSE) | all traffic | only your org's |
| SQL console | unrestricted | rows filtered to your apps (project app_id) |
Tenant isolation is enforced in packages/api/src/lib/guard.ts and
lib/tenancy.ts, and covered by packages/api/tests/tenancy.test.ts.
Sending OpenTelemetry traces
Any OTel SDK or Collector can export to Sentrinel:
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:3001
OTEL_EXPORTER_OTLP_PROTOCOL=http/json
OTEL_EXPORTER_OTLP_HEADERS=x-api-key=<your app key>
GenAI spans (gen_ai.request.model + gen_ai.usage.*_tokens) are additionally
priced and shown on the LLM cost page.
Cron monitoring
Create a monitor in the dashboard, then add its check-in URL to the job:
# at the end of the job
curl -fsS https://sentrinel.example.com/api/checkin/<token>
# or, for long jobs, report start / duration / explicit failure
curl -fsS "https://sentrinel.example.com/api/checkin/<token>?state=start"
curl -fsS "https://sentrinel.example.com/api/checkin/<token>?duration=1430"
curl -fsS "https://sentrinel.example.com/api/checkin/<token>?state=fail"
Deploy markers
Pass a version to the plugin and every release is recorded automatically:
sentrinelPlugin({ appName: "my-api", version: process.env.GIT_SHA })