Back to Security

Technical Security

For the curious: how Lurien actually protects your data at a cryptographic and architectural level.

Password hashing

Account passwords are hashed with Argon2id(OWASP 2024 standard, RFC 9106). Parameters: m=19456 KiB, t=2, p=1. Memory-hard → high cost for GPU/ASIC attacks. Legacy bcrypt hashes from earlier accounts are transparently upgraded to Argon2id on next login (lazy migration).

Link access URLs

Trackable links use HMAC-SHA256 signed tokens bound to the view session (TTL 5 min, view_id included in signature). A leaked link cannot be replayed beyond its original session.

JWT and session revocation

Sessions use JWT (HS256, 30-day TTL) in httpOnly cookies. When the user changes their password, the database storespassword_changed_at; any JWT with iat earlier than this is rejected — instant invalidation of all old sessions.

IP pseudonymisation

Raw IP addresses never reach the database. They are hashed with SHA-256 + an application-secret pepper before storage. Useful for anonymised "same visitor returned" detection without storing PII. Required env: IP_HASH_SECRET.

PII masking before AI

Every AI call (DeepSeek / OpenAI / etc.) routes through a mandatory middleware: maskPII() finds national IDs, IBANs, Turkish-format phone numbers and emails, and replaces them with [TC] / [IBAN] / [PHONE] / [EMAIL] placeholders. The raw PII never leaves the EU server.

SSRF protection on webhooks

User-supplied webhook URLs go through DNS resolution and IP checks before any HTTP request. Private/loopback/AWS-metadata IP ranges are rejected. https-only in production.

Rate limiting

Login (5/min per IP+email), signup (5/hour per IP), AI calls (10/min per user), upload (10/min). Backed by Upstash Redis (sliding window) with in-memory fallback.

Technical Security — Lurien · Lurien