Security

Last updated: 19 March 2026

Encryption

  • In transit: All connections use TLS 1.2 or higher. HSTS is enforced with preload, includeSubDomains, and a two-year max-age.
  • At rest: Commercially sensitive fields (cost of goods, sale prices, removal fees, recovery amounts) are encrypted using AES-256-GCM with per-user encryption keys via envelope encryption. Each user's data is encrypted with a unique data encryption key (DEK), which is itself encrypted by a master key.
  • Passwords: Hashed using bcrypt. Never stored in plaintext.
  • API keys: Hashed using bcrypt. The plaintext key is shown once at creation and never stored.

Access control

  • Row-level security: PostgreSQL row-level security (RLS) policies enforce that each user can only access their own data at the database level.
  • Session management: Single active session enforced via a session version cookie. Password changes and email changes invalidate all other sessions immediately.
  • Password policy: Minimum 12 characters, requires uppercase, lowercase, digit, and special character. Common passwords are blocked. Passwords expire after 365 days.
  • Multi-factor authentication: TOTP-based two-factor authentication is required for all users via authenticator apps (Google Authenticator, Authy, 1Password, etc.).
  • Progressive lockout: Failed login attempts trigger escalating cooldowns (60 seconds after 5 failures, up to 1 hour after 20 failures).
  • Login risk engine: Automated risk assessment on every login. Medium-risk logins require email verification. High-risk logins are blocked with an alert.

Network and application security

  • Content Security Policy: Strict CSP headers restrict script sources, frame ancestors, and external connections.
  • CSRF protection: Origin validation on all state-changing requests. Trusted origins are explicitly allowlisted.
  • Rate limiting: All sensitive routes are rate-limited by user and/or IP address using sliding window algorithms.
  • Security headers: X-Frame-Options DENY, X-Content-Type-Options nosniff, Referrer-Policy strict-origin-when-cross-origin, Cross-Origin-Opener-Policy same-origin, Permissions-Policy restricting browser features.
  • Cache control: Authenticated responses include Cache-Control: private, no-store to prevent caching of sensitive data.

Audit logging

  • All authentication events, data mutations, permission changes, and administrative actions are recorded in an append-only audit log.
  • Audit entries are protected by a SHA-256 integrity chain to detect tampering.
  • Logs are retained for a minimum of 90 days.
  • Automated alerts are raised for suspicious patterns including repeated failed logins, origin validation failures, and sensitive operation abuse.

Data handling

  • Amazon Marketplace data that does not contain personally identifiable information is retained for no longer than 18 months. Retention limits are enforced automatically via a daily scheduled process that permanently deletes expired records.
  • Payment processing is handled entirely by Stripe. We do not store card details.
  • Server-side error logs never contain email addresses, passwords, tokens, or API keys.
  • Client-facing error messages never expose internal system details or third-party error messages.

Incident response

  • In the event of a data security incident affecting personal data, we notify affected users within 72 hours in accordance with UK GDPR.
  • We notify the ICO (Information Commissioner's Office) where required by law.

Infrastructure

  • Hosting: Vercel (serverless, edge network).
  • Database: Supabase (managed PostgreSQL with row-level security).
  • Secrets scanning: Automated secret scanning runs on every push via GitHub Actions (Gitleaks).
  • Dependency scanning: Automated dependency vulnerability scanning runs on every push, pull request, and weekly via GitHub Actions.

Contact

To report a security vulnerability or ask a security question, email hello@reclaimhq.uk.