Security
Small surface. Boring choices.
What we do, what we never do, and how to tell us when something is wrong.
- Sessions
- Sign-in is handled by Supabase Auth. Sessions are JWTs in httpOnly cookies, validated on every request. Google sign-in is optional.
- Data isolation
- Every table has row-level security. A user reads and writes their own rows and nothing else. Auditors may read; only admins may act, and every role change is audited.
- Broker keys
- Stored in an encrypted vault inside the database, readable only by the server, never shown again after you paste them. Revocable at the broker at any time.
- Financial rows
- Snapshots, fills, blocks and the audit log reject updates and deletes at the database level, even from us.
- Secrets and logs
- No secrets in code, logs or the browser bundle. Logs carry identifiers, not payloads.
- Headers
- Strict content security policy, no framing, no third-party scripts on the website beyond optional cookieless analytics.
- Payments
- Card details go to Stripe and never touch our servers. We store a customer id and the subscription state.
- Deploys
- Every change runs typechecks, tests, a fresh-database migration and row-level security tests before it reaches staging, and again before production. Migrations are additive; nothing is renamed or dropped in the release that stops using it.
Report a vulnerability
E-mail us. Do not open a public issue. We answer within two business days and credit reporters who want it.