Reference
Quick lookup tables for environment variables, permissions, check types, alert types, and ports.
Ports
| Port | Service | Notes |
|---|---|---|
8080 | Snitcher server | SPA + REST API + SignalR hubs |
8025 | Mailpit | Dev/demo email sink web UI |
8081 | Keycloak | Optional OIDC provider (dev mode) |
| (internal) | Postgres / TimescaleDB | No host port published |
Environment variables
Secrets (from a git-ignored .env)
| Variable | How to generate | Description |
|---|---|---|
SNITCHER_DB_PASSWORD | openssl rand -base64 24 | Postgres role password |
SNITCHER_JWT_KEY | openssl rand -base64 48 | HS256 JWT signing key (min 32 chars; must not be a known dev default) |
SNITCHER_ADMIN_PASSWORD_HASH | PBKDF2 — see deployments/prod/README.md | PBKDF2 hash of the local admin password |
SNITCHER_SECRETS_KEY | openssl rand -base64 32 | AES-GCM-256 key encrypting stored target secrets. Changing it makes existing secrets undecryptable. |
SCOUT__SCOUT_ID | Created in the UI (Scouts → Add Scout) | Scout ID (GUID) the bundled Scout registers under |
SCOUT__REGISTRATION_KEY | Minted in the UI (Scouts → Add Scout) | One-time Scout registration key (activates first key registration) |
SCOUT__KEY_ENCRYPTION_KEY | openssl rand -base64 32 | AES-GCM-256 key encrypting the Scout's stored Ed25519 private key. Changing it makes the stored key undecryptable, forcing re-enrolment. |
Copy
deployments/prod/.env.exampletodeployments/prod/.envand fill in each value; the dev stack (deployments/dev/) needs none of these — it ships throwaway defaults.
Server configuration
| Variable | Default | Description |
|---|---|---|
Auth__Username | admin | Local admin username |
Auth__PasswordHash | — | PBKDF2 hash; required in Production (plaintext Auth__Password is Development-only) |
Auth__JwtKey | — | JWT signing key |
ConnectionStrings__SnitcherDatabase | (internal) | Postgres connection string |
Snitcher__SecretsKey | — | AES-GCM-256 secrets key |
Snitcher__PublicUrl | http://localhost:8080 | Public URL shown in the Add-Scout dialog |
Snitcher__Security__FrameAncestors | (unset) | CSP frame-ancestors allowlist for the whole origin (admin UI included). Unset = framing denied (DENY / 'none'). Accepts a space-separated origin list, 'self', or a wildcard. See Framing |
Snitcher__Security__StatusPageFrameAncestors | (unset) | Same, but scoped to only the public status pages (/status/*); the admin control plane stays denied. Falls back to Snitcher__Security__FrameAncestors when unset |
Snitcher__FirstScout__RegistrationKey | (unset) | Config-driven first Scout's reusable, non-expiring registration key (read-only Scout). Bridged from the Scout's SCOUT__RegistrationKey in the bundled compose |
Snitcher__FirstScout__ScoutId | (unset) | Config-driven first Scout's Scout ID (GUID); must match the Scout's SCOUT__ScoutId |
Snitcher__FirstScout__Name | scout-1 | Config-driven first Scout name |
Snitcher__FirstScout__Location | local | Config-driven first Scout location |
Snitcher__Ui__LoginMessage | (unset) | Free-text message shown on the login page between the title and the credential inputs (plain text; line breaks preserved). Unset/blank = no message. |
Smtp__Host / Smtp__Port | mailpit / 1025 | SMTP relay for alert email |
Smtp__UseStartTls | false | STARTTLS (port 587) |
Smtp__FromAddress / Smtp__FromName | snitcher@localhost / Snitcher | Sender identity |
Seed__DemoData | false | Seed demo targets/alerts on startup (idempotent) |
Scout key rotation (Settings → Scout Key Rotation)
Global policy, not per-Scout — editable in the UI, or via GET/PUT /api/settings/scout-key-rotation.
| Setting | Default | Description |
|---|---|---|
| Rotation interval | 7 days | Rotate a trusted, online Scout's key once it's older than this |
| Retry delay | 1 hour | Wait this long before re-attempting an unacknowledged rotation while the Scout stays online (a reconnect always retries immediately, independent of this) |
| Max key age | 30 days | A key older than this without a successful rotation flips the Scout to Untrusted; connects are refused until it's re-enrolled |
OIDC / SSO
| Variable | Example | Description |
|---|---|---|
Oidc__Enabled | true | Enable SSO (accept OIDC tokens alongside the local admin) |
Oidc__MetadataAddress | http://keycloak:8080/realms/snitcher/.well-known/openid-configuration | Internal discovery URL the server fetches JWKS/metadata from |
Oidc__Issuer | http://localhost:8081/realms/snitcher | External issuer the browser obtains tokens from |
Oidc__Authority | http://localhost:8081/realms/snitcher | External authority the SPA redirects to |
Oidc__ClientId | snitcher-web | Public client id used by the SPA |
Scout agent
| Variable | Description |
|---|---|
SCOUT__URL | Snitcher server URL the Scout dials out to |
SCOUT__ScoutId | Scout ID (GUID) from the UI; identifies which Scout row this agent's key belongs to |
SCOUT__RegistrationKey | One-time (or, for config-managed Scouts, reusable) registration key — authenticates first public-key registration only |
SCOUT__KeyEncryptionKey | AES-GCM-256 key (base64, 32 bytes) encrypting the stored Ed25519 private key. Required once the Scout has registered an identity |
SCOUT__KeyEncryptionKey_FILE | Path to a file (e.g. a Docker secret) holding the key encryption key; takes precedence over SCOUT__KeyEncryptionKey |
SCOUT__Database__Provider | Sqlite (default, zero-config) or Postgres |
SCOUT__Database__ConnectionString | Connection string for the Scout's local identity store (default Data Source=/data/scout.db) |
SCOUT__NAME | Display name |
SCOUT__LOCATION | Location label |
SCOUT__ReconnectIntervalSeconds | Fixed reconnect interval (default 10) |
SCOUT__ResultRetentionHours | Retention window (hours) for durably-queued check results before the eviction sweep deletes them, delivered or not (default 24; minimum effective value 1) |
Permissions
Permissions are (Action, ResourceType[, Scope]), assigned to groups:
| Resource type | Actions | Scoping |
|---|---|---|
| Dashboard | Read | — |
| Target | Create · Read · Update · Delete | All / by Label / by Resource ID |
| Scout | Create · Read · Update · Delete | All / by Label |
| Alerting | Create · Read · Update · Delete | All / by Label |
| StatusPage | Create · Read · Update · Delete | All |
| Group | Create · Read · Update · Delete | All |
| User | Create · Read · Update · Delete | All |
| AuditLog | Read | All |
| Settings | Read · Update | All |
Built-in groups: Administrators (every permission, immutable), Operators (view everything + manage targets/scouts/alerting, no user/group admin), Viewers (read-only). See Users & Groups.
Data retention
Check results live in a TimescaleDB hypertable with continuous aggregates chained at increasing resolution; each tier is independently configurable:
| Tier | Default retention | Source |
|---|---|---|
| Raw | 7 days | Hypertable |
| 1-minute | 30 days | Continuous aggregate |
| 5-minute | 90 days | Continuous aggregate |
| 15-minute | 180 days | Continuous aggregate |
| 1-hour | 365 days | Continuous aggregate |
| 1-day | 1825 days (5y) — or indefinite | Continuous aggregate |
Coarser tiers must be kept at least as long as finer ones. The 1-day tier can be set to "keep forever"; Settings → Data Retention shows a live storage estimate (per-target and total) with a growth-per-year projection when it is. Audit-log retention is configured independently (default 2 years) — see Auditing.
Check types
| Type | Highlights |
|---|---|
| HTTP/HTTPS | Expected status codes/ranges, keyword & JSON-path assertions, custom method/headers/body, Basic/Bearer auth, redirect control, TLS cert capture + expiry alerts, degraded-latency threshold |
| TCP | Connection check, optional TLS/STARTTLS, send string + expect/expect-not patterns |
| ICMP | Ping with packet count/size/TTL and packet-loss threshold (--cap-add=NET_RAW on the Scout) |
Common options: check interval, timeout, retries, IP version, and inverted mode (swap Up/Down for firewalled ports).
Alert types
ScoutDown, ScoutUp, ResourceDown, ResourceRecovered, ResourceDegraded, ClockSkewWarning, CertExpiring, IncidentEvent, KeyRotationFailed, ScoutUntrusted.
Alert rules can be scoped to a specific resource and gated by a persistence threshold — N consecutive failures or a continuous duration. KeyRotationFailed and ScoutUntrusted are system-level (always unscoped) — see Scouts & Provisioning.