Tenant isolation
- Every B2B query filters by
tenantId; Supabase Row Level Security policies enforce isolation at the database. - Per-tenant API keys, video/avatar provider credentials and OAuth tokens are encrypted at rest with AES-256-GCM.
- Support impersonation uses a short-lived (1h) HMAC-signed httpOnly cookie and is an in-memory overlay — Supabase auth is never modified. Every impersonation start/stop is audited.
Secrets & OAuth
- OAuth state is HMAC-SHA256 signed (
OAUTH_STATE_SECRET) with a Redis nonce (anti-replay, TTL 15min) on everyconnectand validated against the session on everycallback. - Shared-media link passwords are stored as
salt:hashvia scrypt, with rate limiting on attempts.
Uploads & content safety
- Upload
storageUrlmust start with the Supabase public storage prefix, otherwise it is rejected with 422. - Assignment submissions live in a private bucket with a validated prefix (
{tenantId}/{courseId}/{lessonId}/{userId}/); downloads use signed, short-lived URLs with ownership checks. - HTML from users/LLMs is sanitized server-side (DOMPurify) before any
dangerouslySetInnerHTML, including HTML served to the mobile app. - Input is validated with Zod on POST/PATCH routes; SSRF prevention blocks private IPv4/IPv6 and metadata endpoints.
Moderation
An AI chat supervisor classifies tutor turns (severity + category) in the background and can warn or quarantine; self-harm signals trigger a non-punitive safety flow with crisis resources and an urgent admin notification.
LGPD / privacy
- Export (Art. 18 IV):
GET /api/user/data-exportreturns all user data as JSON, rate-limited to 1 request per 24h (Redis cooldown). - Deletion (Art. 18 VI):
DELETE /api/user/accountanonymizes PII and deletes conversational data, but retains learning data (grades, completions, quiz attempts) for ~5 years of fiscal retention (Art. 16 I). - Public
/privacyand/termspages are accessible without authentication. - Observability via Sentry uses Replay with masked text and blocked media for LGPD.
Audit
Sensitive admin actions (impersonation, plan/config changes, manual payments, role changes) are recorded in an immutable admin audit log with IP and user-agent.