Zero-PHI architecture
The database schema has no column for a patient name, date of birth, chart number, health card, phone number, or address, and no binary column of any kind. There is no upload route. Checklist questions are typed: every answer is a yes/no, a date, a count, or one of a fixed set of options, so a chart note cannot be typed into one.
- What is stored
- Your clinic’s sign-in email and a salted password hash. Per case: the category, the typed answers, the verdict with its citations, the date, and an optional label capped at 60 characters that carries a visible “no patient identifiers” warning. Optionally, the outcome Sun Life gave and a drafted justification built from findings you type — same warning, same cap.
- What cannot be stored
- Patient identifiers of any kind, radiographs, photographs, PDFs, claim forms, or any file. Not by policy — there is no field or route that would accept them.
Enforced, not promised. An automated test reads the database schema and the source tree on every build and fails if a binary column, an upload surface, an identifier-shaped column, or an unjustified free-text column appears.
Hosting and residency
- Application
- Cloudflare Workers (global edge network)
- Application data
- Neon Postgres in the United States (AWS us-east-2)
- In transit
- TLS everywhere, including between the application and the database.
We state the data location plainly rather than implying Canadian residency: application data is stored where it says above. Because no personal health information enters the system, none of it is stored there or anywhere else.
Retention
Case records are kept for as long as the clinic account exists so that outcomes can be logged against verdicts. To have an account and every case under it deleted, email support@cdcpcheck.ca from the sign-in address. Sign-in throttle records are keyed hashes and expire on their own within 30 minutes. Billing records are held by Stripe under its own retention policy.
Accounts and rate limiting
- Passwords are hashed with PBKDF2-SHA256 at 100,000 iterations with a per-account salt. The password itself is never stored or logged.
- Sessions are signed, HttpOnly, SameSite cookies that expire after 30 days. A password reset signs out every device.
- 5 failed sign-ins for an account within 15 minutes lock that account for 15 minutes. Sign-ups and reset requests are throttled the same way. The throttle is stored as a keyed hash, so neither the email nor the connecting address is written down.
- Reset links are single-use and expire after 60 minutes; only a hash of the link is stored.
- Every checklist submission is re-validated on the server against the ruleset, so a tampered request cannot store an answer the form could never have sent.
Payments
Cards are entered on Stripe Checkout and managed in the Stripe Customer Portal. This application never sees, transmits, or stores a card number. Webhooks from Stripe are signature-verified before they are read.
Questions about any of this: support@cdcpcheck.ca. Not affiliated with Health Canada or Sun Life. Back to the overview.