Per-clinic keys
A key on disk wraps a separate key for each clinic. One clinic's data cannot be read with another's key, and offboarding destroys the key — which makes the backups unreadable too.
Security
Every claim on this page is a thing the software does, phrased so you can ask us to demonstrate it. Where something is not done, it says so.
Tenancy
Not a shared table with a column saying which practice a row belongs to. One database and one encryption key per clinic, which makes backup, restore, export and deletion single operations rather than careful queries.
The query helpers refuse to run at all without knowing whose data they are reading. Forgetting the scope is a crash during development, not a leak in production — and another clinic's record is a "not found" because the row is not in your database at all.
The audit log
Every entry carries the hash of the one before it, so changing an old line breaks every line after it. On top of that, database triggers refuse updates and deletes outright — against the application, against a migration, and against an administrator with full credentials.
You read your own complete history, including every time our staff entered your workspace and the reason they typed. The chain is verified nightly and again after every restore, because a backup whose audit trail no longer validates is not evidence of anything.
Ask any vendor to demonstrate this by trying to edit a past audit entry as an administrator. It is very revealing.
Ours: the database refuses, the application never asked, and the attempt itself is on the record.
Encryption
A key on disk wraps a separate key for each clinic. One clinic's data cannot be read with another's key, and offboarding destroys the key — which makes the backups unreadable too.
AES-256-GCM with the table and column name as additional data, so ciphertext cannot be moved from one field to another even by someone with database access.
Phone numbers are matched by a keyed hash, so lookup and de-duplication work without reading anybody's number.
The payment tables have no column for a number, expiry or security code — a property of the schema rather than of anybody's discipline. Providers hand back tokens; tokens are what we keep.
A consultation goes directly between the two browsers, encrypted before it leaves either device. It is not recorded and it never reaches this server, so there is no retention policy to argue about and nothing to produce under a subpoena. The setup messages that introduce the two browsers are deleted as they are delivered.
Authentication
| Who | How | Notes |
|---|---|---|
| Clinic staff | Password, then a code by email | No way to switch the second step off |
| Our platform staff | Password and a code, always | Entering a workspace needs a typed reason, written into your audit log |
| Resellers | Password and a code | Commercial data only — a partner session never points at a clinic database |
| Patients | A code to the number on their record | No password to lose; sessions are revocable by your front desk |
| Other systems | Signed requests, five-minute window | No session, no cookie, constant-time comparison |
Permissions are checked as named capabilities, never as job titles or rank numbers. Emergency access grants a small fixed set for sixty minutes with a mandatory reason and an alert — not a blanket override that nobody notices staying on.
Each is rate limited and audited, none can be used to look anybody up, and each is tested to prove what it does not show.
Unauthenticated pages
The referral page a sending practice opens shows initials and a stage. Not a name, not a phone number, not the reason for referral — because that link will eventually be forwarded, pasted into an email, and left in a browser history on a shared machine.
Recovery
Nightly, per clinic, encrypted under a key that is deliberately not the clinic's data key — so destroying that key at offboarding does not also destroy the copies you are contractually required to hold.
A backup is restored into a scratch database, the row counts are compared, and the audit chain is re-verified. A backup nobody has restored is a hypothesis.
What we have not done
Both are booked before the first paying customer, and we would rather you read that here than discover it in a questionnaire.
Controls map to HIPAA §164.312 access control, audit, integrity and transmission security; §164.308(b) business associate contracts; ISO 27001 A.8.24; and NIST SC-4, SC-12/13, AU-9/AU-10 and CP-9/CP-10. The mapping is not a document — it is a command that inspects the running system, and each control names what would disprove it. Three outcomes, never two: in force, failing, or could not be checked here, because a green tick on something unverified is worse than no check at all.
It also prints what no code can produce: the penetration test, the counsel-reviewed agreement, the risk analysis, the training records — and that on a shared host every site’s PHP runs as one account, so any of them can read what this one can. A file permission does not fix that, and we would rather name it than imply a column of ticks is a compliance position.