Security
Operational reference for the security model. The customer-facing security summary lives at /security; this page documents the technical contract.
Data in transit
All inbound and outbound traffic uses TLS 1.2 or higher. Endpoints:
- Apps Script → RouteForms. HTTPS POST to a per-form URL on
api.routeforms.com. - RouteForms → Slack. HTTPS POST to the Slack-issued webhook URL on
hooks.slack.com. - Dashboard ↔ RouteForms. HTTPS only; HTTP redirects upgrade to HTTPS.
HSTS is enabled on production hosts. There is no plaintext fallback.
Data at rest
Production databases and object storage are encrypted at rest with AES-256. Secrets (Slack webhook URLs, inbound webhook signing keys, OAuth tokens) are stored separately from the application data and encrypted with a per-row envelope key.
Secret handling
The two classes of secret RouteForms holds:
- Slack webhook URLs. Per-form, encrypted at rest, displayed masked in the dashboard after initial entry. Plaintext is available only at delivery time and never logged. Rotation is a single click (the dashboard re-encrypts).
- Inbound webhook signing keys. Per-form, generated at form creation, included in the Apps Script. Used to validate that every inbound POST came from the legitimate Apps Script for that form. Rotate by re-generating the script and re-installing.
Authentication
Dashboard authentication uses an email-link (magic link) flow via Supabase Auth. Optionally OAuth with Google for accounts that prefer SSO. Sessions are short-lived and refreshed via secure HTTP-only cookies.
There are no service accounts available to customers; every action in the dashboard is attributable to a user.
Tenant isolation
Multi-tenancy is enforced at the application layer on every read. A query for a form, rule, or delivery log row is bound to the requesting user's workspace membership and refuses cross-tenant access at the query level.
The Agency plan adds a second layer of isolation: workspaces inside one Agency account. See agency workspaces reference for the role and membership model.
Data scope
RouteForms stores the minimum data needed to deliver and audit submissions:
- Form metadata (name, owner, settings, rules).
- Per-delivery rows. Google Forms response ID, the rendered Slack payload, the Slack response code, retry history. See delivery logs for the per-row schema.
- Slack webhook URLs (encrypted) and inbound signing keys (encrypted).
What RouteForms does notstore: the original Google Forms response (Google Forms is the system of record), respondent personally-identifying data beyond what's in the rendered payload preview, Slack-side message reactions or threads.
Retention
The delivery log retention window is per plan. See limits reference for current values. Beyond the retention window, log rows are deleted; the form metadata persists until the form or account is deleted.
Incident response
The on-call contact for security incidents is security@routeforms.com. Reports are acknowledged within one business day. The published security page at /security carries the current disclosure policy.
Subprocessors
The third-party services that process customer data:
- Supabase, primary database and auth.
- Vercel, application hosting.
- Stripe, billing (no customer form data passes through Stripe).
- Resend, outbound email (failure alerts, account notifications).
Google (Forms, Apps Script) and Slack (webhooks) are first-party integrations the customer wires up themselves; RouteForms does not act as a subprocessor for them in the legal sense.