Argon2id hashing, authenticated field encryption, hardware passkeys, and audited access. The technical foundation behind your financial data.
From password storage to data at rest, Convexity uses modern cryptographic primitives. No legacy algorithms, no compromises.
OWASP-recommended memory-hardened algorithm with time_cost=3 and memory_cost=64MB. Resistant to GPU and ASIC brute-force attacks.
Sensitive database fields encrypted with Fernet (AES-128-CBC + HMAC-SHA256). Per-deployment key derived from server-side secret. Future upgrade to AES-256-GCM is on the roadmap.
All API and WebSocket connections encrypted with TLS. HSTS headers enforced across all domains. HTTP permanently redirected.
Short-lived access tokens (15-minute expiry) with database-backed refresh tokens. Automatic rotation on each refresh. Replay detection revokes the entire token family.
Tiered rate limiting on all API endpoints. Auth routes throttled at 5 requests per 5 minutes. Global API limit of 120 requests per minute per IP. AI routes capped at 30 per minute.
Legacy bcrypt password hashes are silently migrated to Argon2id on successful login. No user action required.
Three independent authentication factors plus Google SSO. Each layer adds protection without adding friction.
Memory-hardened hashing with OWASP parameters. Automatic upgrade from legacy bcrypt on login.
Time-based one-time passwords via pyotp. Works with Google Authenticator, Authy, 1Password, or any TOTP app.
Phishing-resistant FIDO2 authentication using hardware security keys or platform biometrics. Passwordless capable.
One-click sign-in with automatic account linking, token exchange, and profile sync via Authlib.
Database-backed sessions with automatic expiry. Revoke individual sessions or all active sessions from any device.
Append-only JSONL audit trail covering 18+ security event types: logins, MFA changes, password resets, session revocations, and account modifications.
Sensitive fields in our database are encrypted with Fernet (AES-128-CBC + HMAC-SHA256) using a per-deployment key. Encryption and decryption happen server-side. We never sell, share, or monetize your financial data.
How we classify information, who is responsible for what, and which controls apply to which data. Effective 2026-04-17. Next review 2027-04.
| Domain | Control |
|---|---|
| Encryption | Argon2id for password hashing. Fernet (AES-128-CBC + HMAC-SHA256) for at-rest field encryption on restricted data. TLS 1.3 for all transport. Planned upgrade to AES-256-GCM on the roadmap. |
| Access control | JWT-based session auth; tier-based RBAC enforced at middleware on every request. See access control policy below. |
| Authentication | Password + optional TOTP + optional WebAuthn for account holders. MFA available, not yet mandatory. |
| Logging & monitoring | Structured JSON logs with request-ID propagation. Sentry error tracking. Audit log covering 18 security-sensitive event types. |
| Vulnerability management | Patching SLAs: Critical 72h, High 14d, Medium 30d, Low 90d. Continuous scanning via Dependabot, pip-audit, unattended-upgrades. |
| Data retention | Soft delete with 30-day recovery. Hard delete on request. Full policy: /privacy. |
| Third-party risk | Subprocessors disclosed publicly on this page. New subprocessors disclosed before data is shared. |
Built on zero-trust principles, scoped to a single-VPS architecture. Every request is independently authenticated and authorized at middleware before reaching any business logic. There is no "trusted internal network" — even requests from our own services are verified the same way as external ones.
Every API request carries a JWT access token with a 15-minute expiry. No long-lived trust.
Role-based access control enforced at middleware (tier_gate) on every protected route. No implicit privilege from session state alone.
Refresh tokens are rotated on each use; replay revokes the entire token family.
Production secrets are loaded from a root-owned env file by systemd; they never transit between processes in plaintext.
Failed auth attempts trigger rate limiting (5 requests per 5 minutes on auth routes).
Device trust, continuous risk-based authentication, identity federation, and network segmentation are not meaningful at current scale (single VPS, no corporate network, no managed device fleet). If we add any of those later, this section will be updated.
Access to systems and data follows the principle of least privilege. Permissions are tier-based, enforced in application middleware, and granted only when required to deliver a specific feature. Scope covers user access to the application and operator access to the underlying infrastructure.
Single operator today (founder). Server access via SSH key-based authentication only; password logins disabled at the sshd level. Production secrets live in a root-owned env file loaded by systemd. MFA is enforced on all operator-facing third-party accounts (domain registrar, DNS, email, GitHub, VPS vendor, cloud console).
backend/app/security/offboarding.py — revokes all tokens, disables MFA, deletes passkeys, disconnects Plaid, clears passwords.Reviewed on material architecture changes and at minimum annually · Effective 2026-04-17
Honesty about gaps matters more than marketing claims. Here's what we're building toward.
Third-party services that process data on our behalf.
| Service | Purpose | Data processed |
|---|---|---|
| Anthropic | AI analysis (primary) | Prompts containing market data, portfolio context |
| OpenAI | AI analysis (fallback) | Prompts containing market data, portfolio context |
| Plaid | Brokerage account linking | OAuth tokens, account balances, positions |
| Polygon.io | Market data feed | Ticker symbols (no user data) |
| Sentry | Error monitoring | Error stack traces, performance metrics (PII excluded) |
| Hostinger | Infrastructure (VPS) | All application data (encrypted at rest) |
| Cloudflare | DNS, CDN | HTTP requests, IP addresses |
| Let's Encrypt | TLS certificates | Domain names only |
We take security reports seriously and respond within 48 hours. Good-faith security research is welcome.