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.