Skip to content

Hardening checklist

Before going productive, walk through this list. Everything is optional, but skip few of them.

Authentication

  • [ ] Mandatory 2FA for super admin and tenant admin
  • [ ] Password complexity in admin settings to high
  • [ ] JWT lifetime capped at 8–24 h (shorter = more frequent login, safer)
  • [ ] Default admin account renamed or disabled — don't leave admin@example.com
  • [ ] Login rate limit verified — default 10 req/min/IP

Tokens

  • [ ] Distribute agent tokens minimally — only one per host
  • [ ] Collector API keys with long prefix so leaks reveal which tenant
  • [ ] Personal access tokens with short lifetime (e.g. 90 days) and targeted scope

Encryption

  • [ ] FIELD_ENCRYPTION_KEY in password manager + printed safe-stored
  • [ ] Backup of key separate from DB backup
  • [ ] Only 1–2 people should know the key

TLS

  • [ ] Real cert (Let's Encrypt or own CA), not self-signed in production
  • [ ] HSTS active (default yes)
  • [ ] TLS 1.2+ only in nginx config
  • [ ] A/A+ at SSL Labs
  • [ ] Auto-renewal (Let's Encrypt) or calendar reminder before expiry

Network

  • [ ] Outbound whitelist on the server: only allowed targets (registry, licence portal, FCM, SMTP)
  • [ ] Inbound 80/443 only — all other ports closed except possibly SSH and NSCA
  • [ ] SSH key-only, no password
  • [ ] Fail2ban or similar on SSH brute-force
  • [ ] Firewall rules documented and versioned

API replicas and locking

  • [ ] With multiple API replicas: distributed locks via Redis working (watch system tab)
  • [ ] Redis auth active (REDIS_PASSWORD set — default yes, verify)

Logging and monitoring

  • [ ] Audit log active and retention configured
  • [ ] Log tailing external if compliance-relevant (SIEM)
  • [ ] System health email alarm to super admins
  • [ ] Failed-login alerts as log alert rule

Updates

  • [ ] GUI updater works (test with small update before first live update)
  • [ ] Backup before each update runs (default yes, verify)
  • [ ] Update window communicated (status page / wiki)

Backup

  • [ ] Backup sidecar active
  • [ ] Off-site copy (at least weekly)
  • [ ] Restore drill at least once per quarter
  • [ ] .env backup separate

RBAC

  • [ ] Permission inventory — no user with more than necessary
  • [ ] Default admin account not for daily use
  • [ ] Auditor role for external auditors (only audit.view, audit.export)

AI

  • [ ] With cloud provider: be clear what goes to the API
  • [ ] AI permissions sparingly — not every user needs ai.query
  • [ ] AI visibility toggle in user pref explained (privacy wish)

Mobile

  • [ ] Own Firebase project if privacy matters (instead of shared)
  • [ ] APK distribution via MDM, not free download

Custom code (scripts, profiles)

  • [ ] script.create not for viewer/operator
  • [ ] Custom scripts tested on test machine before rollout
  • [ ] Profile imports from unknown source carefully

Security updates

  • [ ] CVE feeds watched (Postgres, Redis, FastAPI, React)
  • [ ] Docker images pulled regularly (GUI updater does this)

Operations docs

  • [ ] Runbooks in wiki — what to do on XYZ
  • [ ] Contact list for escalations (in wiki)
  • [ ] Status page for external communication
  • [ ] Storage of FIELD_ENCRYPTION_KEY documented (who has access)

Compliance-specific

Standard Special note
ISO 27001 Audit log + 2FA + backup drill suffice for most audits
GDPR Clear: no personal data is monitored (devices). Login data yes → DPA with vendor
HIPAA Disable cloud AI or pick provider with BAA
PCI Vesana is out of scope unless in card-data path — but can help with monitoring

Next