Back home
TRUST / SECURITY

Treat every boundary as untrusted.

FirstContact uses layered controls around identity, tenant data, public input, providers, and irreversible actions.

Application and data controls

  • Convex's typed validators and indexed document queries are used instead of raw SQL; there is no raw SQL execution surface for classic SQL injection.
  • Authorization is enforced in server functions from the authenticated identity, with per-organization membership checks before protected reads or writes.
  • Operator reads and writes require TOTP step-up for the current session, and repeated TOTP guesses are rate-limited.
  • Passwords use Convex Auth's provider-managed hashing. Provider keys and webhook secrets stay in server-side deployment variables.
  • Public JSON bodies are schema-validated, size-bounded, origin-checked where browser access is expected, and rate-limited before durable writes or paid provider calls.

Browser and delivery controls

  • Vercel sends CSP, HSTS, clickjacking, MIME-sniffing, referrer, permissions, and cross-origin security headers.
  • React escapes user text; the only inline HTML sink is a fixed, source-controlled theme bootstrap script containing no user or provider data.
  • Resend webhook events are verified over the raw body, time-bounded, and deduplicated before processing.
  • Outbound messages require recorded human approval, source and jurisdiction checks, suppression checks, postal identity, HTTPS unsubscribe handling, an atomic send reservation, and a provider idempotency key.

AI and research boundaries

Web content and model output are untrusted. Research remains source-linked, model-produced claims require human review before becoming contact records, and drafts require a separate approval before delivery. Provider output never grants tool authority.

Limits and reporting

No application is perfectly secure. Static browser sessions cannot use server-issued HttpOnly cookies, so admin MFA is an important compensating control. Do not publish exploit details or personal data in a public issue. Use the repository's private vulnerability-reporting channel, or use the authenticated privacy center for a data concern.