What we
actually do.
Everything below is either something this codebase does — with the file that does it named beside it — or a platform fact attributed to the provider who supplies it. Nothing here is planned, and nothing is a certification we do not hold.
In our code
- Sensitive fields are encrypted before they reach the databaseAES-256-GCM, applied in the application layer. Every value is stored with its own random IV and an authentication tag, so a modified ciphertext fails to decrypt rather than returning altered data.
lib/crypto.ts - Six categories of field are coveredContact cell-phone numbers, calendar addresses, connected-mailbox OAuth tokens, bank fields on invoices, and Google Analytics tokens — each with its own key, so one compromised key does not read the others.
lib/crypto.ts - Mailbox tokens are never stored in plaintextWhen you connect Gmail or Microsoft for sending, the refresh and access tokens are encrypted before storage and decrypted only to make the send. A refreshed token is re-encrypted before it is written back.
lib/mailbox/refresh.ts - Tenant isolation is enforced by the database, not the applicationRow-Level Security policies decide what your workspace can read, so a bug in application code cannot return another workspace's rows. Eighteen test files exercise those policies directly against the database.
tests/rls/ - Card details never reach our serversPayment happens in Stripe Checkout and the Stripe Billing Portal. Pitcher never receives, transmits or stores a card number, expiry or CVC — there is no code here that could.
lib/billing/checkout.ts - HTTPS is required, not merely offeredStrict-Transport-Security is sent on every response with a one-year max-age and includeSubDomains, so a browser that has seen the site once refuses to speak to it over HTTP afterwards.
next.config.ts - The app cannot be framedX-Frame-Options and a Content-Security-Policy frame-ancestors directive both deny embedding, which closes clickjacking against the authenticated product.
next.config.ts - Sign-in is delegated, so we hold no passwordsAuthentication runs through Supabase Auth, including Google sign-in. Pitcher stores no password hashes because it is never given a password.
app/auth/actions.ts
From our platform
Two things we rely on rather than implement. They are real, and they are not ours to claim credit for — so they are attributed, and you can read each provider's own account of them.
- Encryption at restThe database is hosted on Supabase, which encrypts stored data at rest. The field-level encryption above sits on top of that, so the most sensitive values are encrypted twice by different systems with different keys.
supabase.com/security - TLS in transitThe application is served by Vercel, which terminates TLS on every request. Our own HSTS header is what stops a browser from ever trying plain HTTP in the first place.
vercel.com/security
What we do not have
Pitcher is not SOC 2 certified. If your client runs a vendor security review that requires a SOC 2 report, we cannot supply one today. We say so here for the same reason our comparison pages record it as an advantage a competitor has over us: a security page that skipped the subject would be answering a different question than the one you asked.
We also publish no penetration-test report and operate no formal vulnerability disclosure programme. If you find something, email info@prpitcher.com and it will reach a person — see Support for how quickly.