Security
Built with privacy in mind. Production work remains.
This page lists what is actually implemented in the codebase and what still stands between this local build and real patient data. We'd rather you read a gap list than a badge.
Local evaluation only
What's built
Field-level encryption
Names, dates of birth, contact details, insurance, intake answers, notes, and file names are AES-256-GCM encrypted with a versioned envelope. Keys come from a provider interface so a KMS can replace environment variables without code changes.
Blind indexes
Lookups by last name, DOB, phone, and email use HMAC-SHA256 indexes, so the database can find a patient without ever storing those values in the clear.
Tenant isolation
Every row is owned by a practice. The service layer requires a tenant context for every read and write; cross-tenant ids resolve to “not found”, and a test suite proves it.
Roles and permissions
Staff permissions are separate from technical administration. Hospital technical specialists use a separate MFA-protected login to manage configuration and accounts.
Multi-factor authentication
TOTP enrollment with QR codes. Login becomes a two-step flow the moment MFA is enabled; sessions carry an MFA-verified flag.
Sessions
Random 256-bit tokens stored hashed, httpOnly + SameSite cookies, 90-minute idle and 12-hour absolute limits for staff, 30 minutes for patients and kiosk sessions, all revocable.
Tamper-evident audit log
Append-only, per-practice SHA-256 hash chain covering sign-ins, views, downloads, status changes, and settings. Metadata is screened against a PHI key denylist.
Rate limiting
Sliding-window limits on sign-in, MFA, magic links, kiosk lookups, uploads, and autosave.
Safe uploads
Magic-byte sniffing (client MIME is ignored), 10 MB cap, random storage keys, served only through an authenticated and audited route.
Privacy-preserving analytics
Aggregate only; never decrypts a patient field; counts under five are suppressed.
Before real patient data
The legal, infrastructure, and security work that is deliberately out of scope for local evaluation.
Business Associate Agreement
Prelude has not executed BAAs with hosting, email, or storage vendors and does not offer one to practices yet.
Managed key storage
Keys live in environment variables. Production needs a KMS/HSM, rotation, and envelope re-encryption tooling.
Production database and backups
SQLite is for local demo. Move to managed Postgres with encryption at rest, point-in-time recovery, and tested restores.
Transport and infrastructure hardening
HTTPS termination, HSTS, CSP, WAF, and network isolation belong to the deployment, which does not exist yet.
Email and SMS delivery
No email or SMS delivery is implemented. Staff can issue single-use links through approved hospital channels; email self-service is unavailable. Vendor contracts and tested delivery are required.
Distributed rate limiting and events
In-memory limiter and event bus are single-instance; multi-instance deployments need Redis.
Risk analysis and policies
HIPAA requires a documented risk assessment, workforce training, incident response, and sanctions policies. None exist for this codebase.
Penetration test and third-party review
No external security assessment has been performed.
How to verify it yourself
- Sign in as an owner, open Settings › Audit log, and press “Verify hash chain”.
- Open a patient record, then find the corresponding “patient.updated” or “attachment.downloaded” entry in the log.
- Open the database and note that no name, date of birth, or answer is readable in any table.
- Run
npm testfor the encryption, role, tenant-isolation, and audit-chain suites.