Crubby Security
How we protect your data.
Encryption in transit and at rest, append-only audit logs, PCI-DSS via Stripe, GDPR by design. Transparency for whoever has to clear the purchase with the compliance officer.
Encryption
All traffic is encrypted in transit (TLS 1.3) and at rest (AES-256). No sensitive data ever travels in the clear.
- TLS 1.3 with modern cipher suites (ChaCha20-Poly1305, AES-256-GCM) for all browser ↔ server traffic.
- HSTS enabled with max-age 31,536,000 (1 year) to prevent downgrade attacks.
- Database encrypted at rest with AES-256, managed by Supabase EU (region eu-central-1, Frankfurt).
- Backups are also encrypted at rest with a separate key and rotated periodically.
- Session tokens are hashed before persistence and can be revoked by an admin in case of compromise.
- Passwords hashed with bcrypt cost factor 12 (~250ms per hash). Not reversible, not rainbow-attackable.
Access control
Multi-tenant by design: every query goes through requireStaff/requireAdmin, which applies the restaurantId filter. No cross-tenant data leaks.
- Next.js server actions: every mutation passes through requireStaff() / requireAdmin(), which verifies Supabase auth + restaurantId.
- Row Level Security on Postgres as a second layer (defense-in-depth) for critical multi-tenant tables.
- Granular SaRole roles (SUPPORT, FINANCE, OPS, ADMIN) for the cross-customer Crubby team.
- Append-only audit log of every cross-tenant administrative action (impersonate, plan change, refund, invite member, note).
- Impersonation requires explicit consent or a recorded justification.
Audit log and traceability
Every administrative action is logged with actor, target, timestamp, role and payload. Append-only, unlimited retention.
- SaAuditEntry table indexed by actor + timestamp and action + timestamp.
- Logged: impersonate, change_plan, refund, invite_member, remove_member, add_note.
- JSON meta with before/after for plan changes, and a free-text reason for impersonation.
- Viewer at /admin-internal/audit with actor/action/target/date-range filters and a KPI strip.
- On a customer’s request we can provide an export of the log for their restaurantId.
Payments and PCI-DSS
Crubby never sees card numbers. Stripe handles the entire PCI-DSS Level 1 flow.
- All payments go through Stripe Elements / Stripe Connect (PCI-DSS Level 1 certified).
- Card numbers never pass through our server at any point; only PaymentIntent ID tokens.
- Stripe webhooks signed with HMAC-SHA256 plus strict signature validation.
- Idempotency on WebhookEvent.id to avoid double ledger entries on Stripe retries (3 days of retries).
- Refunds and disputes are handled via the Stripe dashboard; Crubby logs the action in SaAuditEntry.
Backup and disaster recovery
Daily backups with 7-day point-in-time recovery; weekly backups kept for 90 days. RPO < 1 hour, RTO < 4 hours.
- Point-in-time recovery (PITR) active on Supabase Postgres: restore to any second within the last 7 days.
- Weekly logical backups kept for 90 days on independent storage.
- RPO (Recovery Point Objective) target: < 1 hour.
- RTO (Recovery Time Objective) target: < 4 hours for a regional disaster.
- Restore test documented every six months.
Incident response
Automatic alerting on critical errors via Sentry. Data-breach notification SLA: 72 hours, per GDPR art. 33.
- Sentry monitors application errors 24/7 with alerting to the Crubby team’s Slack.
- Vercel Speed Insights + edge monitoring for availability issues.
- Health-check endpoint /api/health exposed for external uptime monitoring.
- Customer notification by email within 72 hours of a material data breach (GDPR art. 33).
- Public post-mortem in /changelog for substantial incidents (the “Reliability” section).
GDPR and data residency
Personal data hosted in the EU (Frankfurt). DPA available on request. US transfers only under SCC 2021/914.
- Primary database on Supabase region eu-central-1 (Frankfurt, Germany).
- Cloudinary primary EU, US fallback (non-personal images — dish photos).
- US sub-processors (Vercel, Stripe, Resend, Sentry) covered by Standard Contractual Clauses 2021/914.
- DPA (Data Processing Agreement) available on request at privacy@crubby.com.
- GDPR rights can be exercised by writing to privacy@crubby.com — reply within 30 days.
- A complaint to the Italian Data Protection Authority (Garante Privacy) can be filed via garanteprivacy.it.
Found a vulnerability?
We value responsible disclosure. If you’ve identified a security bug, write to us at security@crubby.com with the technical details (PoC, steps to reproduce, impact). Here’s what we promise:
- A reply within 48 working hours of your report.
- An update on remediation status within 7 days of the first confirmation.
- Public credit (with your consent) in the Reliability section of the changelog when the patch is in production.
- No legal action against researchers acting in good faith and following responsible disclosure.
Questions from your compliance officer?
DPA, security questionnaire, ISO/SOC2 roadmap. We answer every enterprise requirement in writing.