Security
- Authentication is handled by Clerk (passwords, social login, MFA, session management). Penny never stores passwords.
- Authorization happens on the server for every request: data access, Server Actions and API routes resolve the signed-in user and scope all SQL to that user id.
- Database: a dedicated Postgres schema with row-level security enabled and no public policies; the Supabase anon/authenticated roles have no grants. Connections use TLS.
- Payments are processed by Stripe Checkout. Webhooks are verified with Stripe’s signature and processed idempotently.
- Validation: every write is validated with Zod; amounts, dates and ids are type-checked before they reach SQL, and all SQL is parameterised.
- Secrets live only in Vercel environment variables and are never sent to the browser.
- Recoverability: deletes are soft with undo, and every change is written to an audit log.
Found a problem? Please report it privately to the project owner via GitHub.