datewise/SECURITY.md
metatroncubeswdev 1d2d943d54 feat(security): encrypt customer personal data at rest
- Prisma extension seals booking name/email/phone/address and waitlist contacts with
  AES-256-GCM on write and opens them on read (incl. nested reads)
- keyed-hash columns for exact email/phone lookups (privacy webhooks, booking search,
  waitlist de-duplication); migration 0002
- tests prove only ciphertext is stored; privacy/terms/SECURITY.md updated to match

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:56:05 -04:00

2.7 KiB

Datewise security and incident response policy

Owner: Metatroncube Software Solutions · Contact: info@metatroncubesolutions.com · Last reviewed: 2026-10-14

Data we hold

Shop settings and scheduling rules; bookings (order ID and number, method, location, date, time, items); customers' name, email, phone and delivery address for reminders and driver run sheets; waitlist emails and phone numbers. Merchant Twilio / WhatsApp credentials when connected.

Data protection

  • In transit: HTTPS only (TLS at Nginx or Caddy).
  • At rest: customer name, email, phone and address (bookings and waitlist) and messaging credentials are encrypted with AES-256-GCM in the application before they reach the database (app/lib/pii.server.ts). Email and phone lookups use HMAC-SHA256 keyed hashes. The key (APP_ENCRYPTION_KEY) lives only in the server's .env and the team password manager.
  • Backups: nightly pg_dump, encrypted with AES-256 (scripts/backup.sh), kept 14 days.
  • Minimisation: postal codes typed into the cart are used for zone lookup and not stored with identity.
  • Retention: customer redaction requests clear that customer's details from bookings and delete their waitlist entries; all shop data is deleted 48 hours after uninstall (shop/redact).
  • Test and production are separate: development uses local databases and Shopify development stores.

Access control

  • Production access (VPS, database, Shopify Partner/Dev Dashboard) is limited to named staff who need it.
  • SSH uses key-based login; Shopify and Git accounts use strong unique passwords and two-factor authentication.
  • Secrets (.env: Shopify secret, database password, APP_ENCRYPTION_KEY) are never stored in Git or chat. Rotate them when someone with access leaves (the encryption key needs a re-encryption step; see below).
  • Access is reviewed every quarter.

Incident response

  1. Detect and contain (immediately): revoke exposed credentials, rotate secrets, block the access path, take the affected service offline if needed.
  2. Assess (within 24 h): what data, which shops, how many records, time window. Preserve logs.
  3. Notify (within 72 h of becoming aware): affected merchants by email, and Shopify via the Partner support channel; regulators where the law requires it.
  4. Recover: fix the root cause, restore from encrypted backups if needed, verify.
  5. Review (within 2 weeks): written post-mortem, follow-up actions, update this policy.

Key rotation

Changing APP_ENCRYPTION_KEY makes existing ciphertext unreadable. To rotate: deploy with both keys, re-encrypt rows with a one-off script, then remove the old key. Never change the key on its own.