Security

KeepBP · What we store and how we protect it · Updated September 17, 2026

KeepBP is a personal blood pressure tracker with optional health-system connect. We do not sell PHI and we do not train models on identifiable readings.

This page describes current practice. Items marked Planned are on the roadmap and are not claimed as live.

What we store

  • Account: email and/or username, password hash (bcrypt)
  • Readings: systolic, diastolic, optional pulse, timestamps
  • Session: signed HTTP-only cookie (bp.sid)
  • Optional Epic tokens: when you connect MyChart, access tokens live in the server session until you disconnect
  • Optional analytics: GA4 page views / product events with no BP values, emails, or passwords
  • Live Per-user audit log (login, logout, FHIR connect/fetch, import, PDF export, report share create/view/revoke, account export/delete). No blood pressure values stored in audit rows.

What we do not store

  • MyChart / portal passwords
  • Your full EHR chart
  • Payment card data (we do not take payments today)

Authentication

Live Email + password, bcrypt hashing, rate limits on signup/login, signup honeypot, and Cloudflare Turnstile on signup — Live on production (keys configured; server-side siteverify runs).

Live Email verification (Resend when configured; otherwise staging link in server logs), Have I Been Pwned breach-password check (k-anonymity), minimum password length 12, account+IP lockout after repeated failures.

Live Optional authenticator (TOTP with scannable QR + backup secret + recovery codes), and passkeys (WebAuthn) when WEBAUTHN_RP_ID / WEBAUTHN_ORIGIN are set. MFA is optional for normal users (soft reminder after five logins/uses; dismiss snoozes ~14 days); high-risk actions (account delete, Epic write-back) require step-up when MFA is enrolled. Operator ADMIN_EMAILS accounts still must enroll MFA before elevating.

Sessions & tokens

  • Production cookies use Secure + SameSite=Lax + HttpOnly
  • SMART tokens are server-side only; not readable from page JavaScript
  • Live Session regenerate on login/signup; idle + absolute timeouts; “sign out all other sessions” via session version
  • Live CSRF double-submit cookie on state-changing /api POSTs (FHIR OAuth GET start/callback unaffected)
  • Live Security headers including CSP (Turnstile/GA/fonts), HSTS in production, Referrer-Policy, Permissions-Policy

Transport & at rest

  • Live HTTPS for production traffic
  • Live Primary database: Postgres on Render (DATABASE_URL). SQLite remains available for optional local/dev when Postgres is not configured.
  • Live App-level AES-256-GCM field encryption for readings (and FHIR tokens in session) when DATA_ENCRYPTION_KEY is set — current practice on production.
  • Live Postgres primary database when DATABASE_URL / POSTGRES_URL is set (sessions via connect-pg-simple). Badges below downgrade if env is missing on another deploy.

Access control

  • Each account only sees its own readings
  • Operator admin roster (/admin) shows email, username, and created date only — no passwords or readings — prefer ADMIN_EMAILS (verified + MFA + step-up) or emergency ADMIN_SECRET
  • Doctor PDFs are generated for the signed-in user to download or share via the device share sheet
  • Live Optional expiring share links (default 7 days, max 30): patient creates a read-only report URL; token is high-entropy and stored only as a SHA-256 hash; revoke anytime; readings loaded at view time so revoke works

Abuse controls

Live Rate limits on signup, login, import preview, PDF, verify resend, FHIR start/write, account delete, and admin login; disposable-email checks; honeypot; login lockout.

  • Live Distributed Redis rate limits when REDIS_URL is set (otherwise in-memory on this instance). Probe below downgrades if Redis is unset.
  • Planned Optional security alert webhook (SECURITY_ALERT_WEBHOOK_URL) for lockout storms, mass deletes, admin login, FHIR write-fail bursts — no PHI in payloads.

Your rights

  • You can log out anytime
  • Live Self-serve data export (JSON) and account hard-delete from Your account (requires password + typing DELETE)
  • Or email support@bloodpressuretracker.app for help

Controls mapped to SOC 2 / HIPAA Security Rule themes

KeepBP is a personal tracking app. The table below maps live technical controls to common assurance themes. It is not a certification claim.

Certification: not claimed. We do not claim SOC 2 or HIPAA certification. A BAA or formal audit is discussed only when a covered-entity partner requires it.

Theme KeepBP live control
Access control Account auth (bcrypt), optional MFA / passkeys, per-user data isolation, admin elevate with verified allowlist + step-up
Encryption in transit HTTPS / HSTS in production; Secure + HttpOnly session cookies
Encryption at rest AES-256-GCM field encryption for reading PHI and FHIR session tokens when DATA_ENCRYPTION_KEY is set (live on production)
Audit logging Per-user audit events (login, FHIR, import/export, share, delete) without BP values in audit rows
Integrity CSRF on mutating APIs; session regenerate on login; share tokens stored as SHA-256 hashes only
Transmission security TLS to clients and EHR OAuth; SMART tokens server-side only
Disposal / deletion Self-serve JSON export and account hard-delete; share-link revoke and expiry

See also Privacy, Terms, and Not medical advice.

Report a vulnerability

Email support@bloodpressuretracker.app. We aim to acknowledge security reports within 72 hours.

Home · Integrations · MyChart BP · Doctor log · Epic FHIR · AHA home BP · CSV import · Share w/ doctor · Security · Privacy · Terms · Not medical advice