How we protect you
Security Measures
We take security seriously because you're trusting us with personal, spiritual content. Here's exactly what protects you — every layer, in plain English. You can verify all of this in our open source code.
Your account
- Username + password (no email required)
- Passwords hashed with bcrypt (never stored in plaintext)
- Minimum password strength enforced using zxcvbn
- Account lockout after 5 failed attempts in 10 minutes
- Generic error messages (no username enumeration)
End-to-end encryption for your journal & talk notes
- Journal entries, talk notes, and private intentions encrypted in your browser before being sent
- Journal supports rich text and embedded drawings — all encrypted as HTML before storage
- AES-GCM 256-bit encryption (same standard used by banks and governments)
- Encryption key derived from password using PBKDF2 with 250,000 iterations
- Encryption key lives only in browser memory during session — never stored on disk, never sent to server
- Even the database admin sees only ciphertext
- Verify in browser dev tools — network requests show encrypted blobs
Recovery phrase
- 12-word BIP39 recovery phrase on signup (crypto-secure RNG)
- Secondary way to unlock encryption key if password forgotten
- If you lose both password and phrase, encrypted content is mathematically unrecoverable
Bot & abuse protection
- Cloudflare Turnstile (privacy-friendly human verification)
- Honeypot field on signup (invisible to real humans)
- Cloudflare Bot Fight Mode at network edge
- Rate limiting: max 10 auth requests per minute per IP
Database security (Supabase)
- Row-Level Security (RLS) on every table
- RLS policies:
auth.uid() = user_id(you can only see your own data) - Only anon key in client code (safe to expose); service role key never in codebase
- Database hosted by Supabase on AWS with encryption at rest and in transit
Network security
- All traffic HTTPS only
- Strict security headers (X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, CSP)
- Cloudflare WAF, DNSSEC, DDoS protection
Input sanitization
- All user content rendered as plain text (
textContent, neverinnerHTML) - All database queries use parameterized SDK calls (SQL injection impossible)
- Honeypot traps silently reject bot submissions
Audit logging
- Every admin action automatically logged to immutable audit table
- Records: who, when, on whom, what
- You can view your own audit log in Account Settings
Soft delete & recovery
- Account deletion = 7-day scheduled deletion
- During grace period, log in to cancel
- After 7 days, permanently deleted (all related rows cascade-deleted)
- Full export offered before deletion
What we deliberately chose NOT to do
- No 2FA (adds friction for group reluctant about email)
- No full security team (built by one person for a small group)
- Client-side encryption only for journal and intentions
- Session keys in browser memory (lock your phone)
Found a security issue?
Email alex@sjdyoungadults.com directly.
Verify it yourself
All verifiable in source code: github.com/ragerbanjoo/ascend
Files to check:
- script.js — auth flow, encryption module, rate limiting
- supabase/migrations/001_hub_schema.sql — RLS policies
- _headers — security headers
- hub.html — how user input is rendered (plain text only)
"We don't ask you to trust us. We give you everything you need to verify us."