Skip to content

Security

What protects a fan list.

A smart-link product holds two things worth stealing: an artist’s audience, and the ability to change where their links point. This page describes what stands in the way of both.

Workspace isolation

Every table that holds workspace data has row-level security enabled in Postgres, and every policy is written against membership rather than against a value the application supplies. An application bug that forgot a filter would still return nothing, because the database refuses the rows independently.

Public pages do not read those tables at all. They call a single definer function that returns an explicit public projection — page content, destinations, brand — and never internal titles, campaign notes, or ownership.

Fan data

Addresses are encrypted at rest

AES-256-GCM, applied in the application before the row is written. The database never holds a readable address, so a database dump on its own does not yield an email list.

Lookup is by keyed hash

Uniqueness and suppression checks use a separate keyed digest, which is why an address can be recognised without being decrypted — and why there is no index to search across the list, a limitation the product states rather than hides.

Consent is evidence, not a flag

The exact wording a fan agreed to is stored with the record and cannot be edited afterwards. Only a revocation timestamp may be added.

Visitor identifiers rotate daily

A salted digest of address, user agent, and the UTC date. Full IP addresses are never stored, and an identifier cannot follow a person between reporting windows.

Access and sessions

Roles are enforced twice: once in the application through a single permission map, and once in the database through policies that do not consult the application. Sensitive operations — transferring ownership, changing billing — additionally require a recent authentication rather than merely a valid session.

Changing a password ends other sessions. Invitations expire. Every administrative action writes an audit row that cannot be edited or deleted.

Infrastructure

Hosted on Vercel with Supabase as the database. Traffic is HTTPS only; a content security policy is applied to every response. Secrets live in environment configuration, are never committed, and are redacted from structured logs by the logger rather than by convention.

Rate limiting is stored in Postgres rather than in process memory, so it survives a cold start instead of resetting every time a serverless function is recycled.

Reporting a vulnerability

Email support@droproute.app (opens in a new tab) with enough detail to reproduce the issue. Please do not open a public issue first, and please do not test against another workspace’s data — a test account is free and takes a minute to create.

In return: an acknowledgement, a straight answer about whether it is a real finding, and credit if you want it. There is no bounty programme yet, and saying so is more useful than implying one exists.

What is not in place yet

No third-party penetration test has been carried out, and there is no SOC 2 or ISO certification. There is no external uptime monitor — the status page explains what it can and cannot honestly report.

Anything on this page that is not yet true would be listed here instead. This section exists so that it has somewhere to go.