Security
How your data is protected
Read-only by design
Institution access goes through Plaid (PCI-compliant, bank-grade links) and is read-only: we can read balances and transactions, never initiate a payment.
Tokens stay on the server
Plaid access tokens are stored in a table with no client-side access policies — only server-side, service-role code inside API routes can ever touch them. They never appear in a browser, a response body, or a log.
Per-user row isolation
The database enforces row-level security: every table query from your session is automatically filtered to your own rows at the Postgres layer. There is no code path where user A can read user B's accounts, transactions, goals, or insights.
Auth without passwords
Sign-in is magic-link only (Supabase Auth) — no passwords to store, leak, or reuse. Sessions are scoped cookies; sensitive writes additionally require the session to match the row owner.
Least-privilege writes
Settings save through a security-definer function that can only write your own display name — a blanket update policy would let anyone flip their own “paid” flag, so we don't have one.
Secrets
All credentials (Supabase, Plaid, Stripe, model APIs) live on the server as environment variables — none are in the repo, the client bundle, or the Vercel project's public config.
Report a concern
If you find something that looks off, email security@sharkfinsoup.cc and it gets personal attention.
Last updated: September 22, 2026