Security Whitepaper

Security at every layer

Sentinel is built with defence-in-depth security from the ground up. Every component \u2014 from the agent on your devices to the database that stores your data \u2014 is designed to protect your school's infrastructure.

🔒

Encryption in Transit

  • All API and dashboard traffic encrypted via HTTPS (TLS 1.2+) with auto-renewed Let’s Encrypt certificates managed by Caddy reverse proxy.
  • Agent-to-server communication uses MQTTS (MQTT over TLS) on port 8883 — no plaintext MQTT is exposed to the internet.
  • Dashboard real-time feeds use WSS (WebSocket Secure) for live device telemetry.
  • Internal service communication (server → database, server → Redis, server → MQTT broker) is bound to localhost only and never exposed externally.
🛡️

Authentication & Authorization

  • Admin authentication via Supabase Auth with JWTs and automatic refresh token rotation.
  • Role-based access control (RBAC): owner, admin, and readonly roles enforced at the API level. Read-only users cannot create, modify, or delete any resources.
  • Device authentication uses unique per-device bearer tokens generated at enrollment. Tokens are SHA-256 hashed before storage — raw tokens never persist in the database.
  • API rate limiting enforced globally (100 req/min) with stricter limits on sensitive endpoints: enrollment (10/min), billing (10/min), org creation (5/min).
🏢

Tenant Isolation

  • Multi-tenant architecture with full data isolation: each organization’s data resides in a separate PostgreSQL schema.
  • Tenant pool routing resolves the correct database connection per-request based on the authenticated user’s organization membership.
  • MQTT access control lists (ACLs) enforce per-device topic scoping. A device can only publish to and subscribe from its own org/device namespace: sentinel/{org_id}/devices/{device_id}/*.
  • Cross-tenant data leakage is structurally impossible — queries are executed against isolated schemas, not filtered rows in shared tables.

Infrastructure Hardening

  • All internal services (PostgreSQL, Redis, MQTT broker) are bound to 127.0.0.1 — inaccessible from the public internet.
  • Redis protected with authentication password and memory limits to prevent abuse.
  • PostgreSQL connections use SSL with certificate verification in production (rejectUnauthorized: true).
  • Caddy reverse proxy enforces security headers: X-Content-Type-Options, X-Frame-Options (DENY), Referrer-Policy, Permissions-Policy.
  • @fastify/helmet applied to all API responses for additional header security (HSTS, X-Download-Options, X-XSS-Protection).
📋

Audit Trail & Compliance

  • Every admin action is logged with: user identity, display name, action type, affected entity, full detail payload, client IP address, and timestamp.
  • Audit logs are written to the tenant’s isolated schema and are immutable (append-only, no UPDATE/DELETE on audit_log table).
  • Searchable and filterable audit log UI with pagination — filter by entity type, action, or free-text search.
  • All audit data stays within your organization’s isolated database schema and is never shared cross-tenant.
💻

Agent Security

  • The Windows agent runs as a SYSTEM-level Windows Service with no user-facing GUI — no attack surface for logged-in users.
  • Agent binary is distributed as a signed MSI package for GPO/SCCM/Intune deployment.
  • Enrollment uses a one-time enrollment token scoped to the organization. The token is exchanged for a unique device bearer token during enrollment.
  • Agent communicates exclusively over MQTTS (TLS). Command payloads are JSON-structured with unique command IDs for correlation and auditing.
  • The agent executes only server-initiated commands (scripts, package installs). It cannot initiate outbound actions or access the management API.
🗄️

Data Protection

  • External database passwords (for “Bring Your Own DB” tenants) are encrypted at rest using AES-256 with a configurable encryption key.
  • Stripe handles all payment card data — no credit card numbers ever touch Sentinel servers. PCI DSS compliance is delegated to Stripe.
  • Database backups are managed by the underlying PostgreSQL infrastructure (Supabase or self-managed) with point-in-time recovery.
  • All environment secrets (API keys, encryption keys, database passwords) are stored in server-side .env files — never exposed to the client bundle.

Questions about our security?

We're happy to discuss our security practices in detail. Reach out to our team for a security review or penetration test coordination.