1. Authentication
- Passwords are never stored in plaintext. Supabase Auth hashes passwords with bcrypt.
- Minimum password length of 6 characters enforced at signup and password reset.
- Auth API calls are rate-limited client-side (5 attempts per 60 seconds). A server-side rate limiter (Vercel Edge or Upstash) will be layered on as additional defence.
- Session tokens use HttpOnly, Secure, SameSite=Lax cookies managed by Supabase SSR.
- Access tokens have short expiry with rolling refresh; sessions are revocable.
2. Encryption
- All traffic is encrypted in transit with TLS 1.2+ (HTTPS) and HSTS is set with 1-year preload.
- Supabase encrypts data at rest with AES-256.
- Secrets and API keys are stored in Vercel environment variables, never in source control.
3. Row-Level Security
Every table in the Supabase PostgreSQL database has Row-Level Security (RLS) enabled. Policies enforce auth.uid() = user_id for every SELECT, INSERT, UPDATE and DELETE on user-owned tables, so that even a bug in application code cannot leak one user’s data to another.
4. HTTP Security Headers
| Header | Value |
|---|---|
| Content-Security-Policy | default-src 'self'; frame-ancestors 'none'; object-src 'none'; form-action 'self'; base-uri 'self' |
| Strict-Transport-Security | max-age=31536000; includeSubDomains; preload |
| X-Content-Type-Options | nosniff |
| X-Frame-Options | DENY |
| X-XSS-Protection | 1; mode=block |
| Referrer-Policy | strict-origin-when-cross-origin |
| Permissions-Policy | camera=(), microphone=(), geolocation=(), interest-cohort=() |
5. Input Validation and Injection Defences
- All database access goes through the Supabase client, which issues parameterised queries over PostgREST - no raw SQL is constructed from user input.
- Server actions and API routes validate types at the Supabase SDK boundary.
- React auto-escapes rendered values; we do not use
dangerouslySetInnerHTMLon user-supplied content.
6. CSRF and Clickjacking
- SameSite=Lax cookies prevent cross-site form submissions from authenticating.
- X-Frame-Options DENY and CSP
frame-ancestors 'none'prevent embedding.
7. Infrastructure
- Database and authentication: Supabase (EU, Ireland) - SOC 2 Type 2.
- Hosting and edge network: Vercel (US) - SOC 2 Type 2, ISO 27001.
- Supabase performs automated daily backups; we do not maintain off-platform copies.
8. Auditing and Monitoring
- Supabase Auth logs authentication events.
- Consent events (
legal_consent_log) are recorded with user ID, consent type, version, timestamp, IP and user agent. - Application logs are rotated every 90 days.
- We conduct periodic manual security reviews and will commission independent penetration testing before any major feature that materially expands the threat surface.
9. Operational Controls
- Access to production Supabase and Vercel dashboards is limited to directors and restricted by multi-factor authentication.
- No production database credentials are shared; individual personnel access is logged.
- Secrets are rotated on personnel changes and after any suspected compromise.
10. Responsible Disclosure
If you identify a security vulnerability in TradeJournal, please report it to privacy@tradejournal.co.za. We acknowledge within one business day. We do not currently offer a bug bounty, but we credit responsible researchers in our security notes where appropriate.
One-line summary
Encryption in transit and at rest. Row-level security on every table. Bcrypt password hashing. Strict CSP, HSTS, sandboxed iframes, SameSite cookies. Operators SOC 2 and ISO 27001. Rate-limited auth. Full consent audit trail. Clear breach procedure.