Security

Monitoring software sits next to production, so it is written to be boringly defensible rather than clever.

Accounts

  • argon2id password hashing (64 MiB, t=3) with a per-hash salt
  • Password policy with a length floor, an entropy floor and a blocklist
  • Two-factor authentication via TOTP, with ten single-use recovery codes stored only as hashes
  • Login attempts throttled per IP and per account: an IP-only limit is defeated by rotating addresses

Sessions

  • Opaque 256-bit tokens; only a SHA-256 hash is stored, so a database copy cannot be replayed as a login
  • HttpOnly, SameSite=Lax, and Secure whenever the base URL is HTTPS
  • Absolute expiry and an idle timeout
  • Session rotated on login, one live session per account
  • A stolen cookie is useless from a different client: sessions are bound to a user-agent fingerprint

Requests

  • Per-session CSRF tokens on every state-changing request
  • Request body size capped
  • Trusted-proxy aware client IP resolution, so X-Forwarded-For cannot be used to choose your own rate-limit key
  • CSP with no inline script and no third-party origins
  • recover middleware: a panic is a 500, never a dead process

Probes cannot be used as a pivot

Monitor URLs are attacker-controlled input, so probes block loopback, private (RFC1918), link-local, CGNAT and IPv6 unique-local ranges at dial time against the resolved address, and re-check every redirect hop. This stops a monitor being used to reach cloud metadata endpoints or your internal network. Internal deployments that deliberately monitor a LAN set PIMA_ALLOW_PRIVATE_TARGETS=true.

Audit trail

Logins, failed logins, throttling, permission denials, and every monitor or channel change are recorded with the acting user, source address and user agent. The record is in the database and never leaves it.

Credentials

Provider credentials — SMTP, SMS, WhatsApp, Telegram — are read from the environment and never stored in a channel row, so exporting the database does not export your ability to send messages as the operator. The UI shows only a redacted destination.

Reporting a problem

Email support@example.co.ke. Please do not open a public issue for a vulnerability.