Security & privacy
Built so that being careful is the default, not the discipline.
Electronic visit verification holds some of the most sensitive information
a person has: where they live, who comes into their home, and when they are
alone. The protections below are structural — properties of how the system
is built, rather than rules staff are asked to remember.
01 Every tenant is isolated in the database itself
Separation is not a filter the application remembers to apply — it is enforced by Azure SQL row-level security on every table, evaluated on every query. An organization cannot read another organization’s records even if a query is malformed, a filter is dropped, or an interface is used in a way nobody anticipated.
Reads are filtered and writes are blocked, so a record cannot be moved out of an organization either. The application account is denied the permission that would switch row-level security off, and an automated check refuses to release any schema where a table carrying an organization identifier lacks its isolation rule.
02 Visit records cannot be quietly altered
Clock-ins and clock-outs are append-only. A correction never overwrites the original — it creates a new record that references it, carrying who asked, who agreed, when, and why.
Both the device time and the server time are stored on every punch, so a shifted device clock is visible rather than authoritative. This is what lets a provider answer an audit years later with evidence instead of assurances.
03 A location is either verified or it is labeled
Where a modality genuinely proves presence, the visit is recorded as verified. Where it does not — a caregiver reading an address over the phone, a call from a mobile — it is recorded as attested and sent for review.
The distinction is structural, not a convention someone can override under pressure to lift a compliance percentage. The system will not let an assertion be stored as evidence.
04 Two-step verification, and a trail when it is reset
Time-based one-time codes are supported for every account and can be required across an organization. Resetting somebody’s second factor is the classic social-engineering route, so it demands a written reason and is recorded against the name of whoever did it.
Sessions are deliberately short-lived, and passwords are chosen by the worker — never generated, seen, or reset by an administrator.
05 The audit trail is append-only, and permission-gated
Every meaningful action writes an audit record with actor, organization, before and after values, and reason. Update and delete are revoked from every application role, so the trail cannot be edited by the software that writes it.
Visit and membership history is additionally kept by the database engine itself, in a form that cannot be rewritten by the application, by a database administrator, or by anyone holding the highest level of database access. Who may read the trail is a permission an organization grants deliberately, visible in the portal — not a hidden capability.
06 There is no database password to steal
Services authenticate to the database with a platform-issued identity rather than a stored credential. No connection password exists in source control, in configuration, in a vault, or on a developer’s machine — because none exists at all.
Access is granted and revoked centrally in the directory, and revocation is immediate rather than waiting for a shared secret to be rotated. The application account also holds no delete permission anywhere: records are corrected and people are deactivated, never erased.
07 Every punch can be traced end to end
When a caregiver says a shift is missing, the answer should not be guesswork. Each punch carries an identifier generated on the device before it ever leaves the phone, and that identifier follows it through the offline queue, the network, and into the permanent record. “What happened to this one?” has an answer rather than a theory — which matters to the person who was not paid, and later to whoever audits the claim.
The traces record the shape of the traffic and never its contents. Request URLs are stripped of identifiers before anything is exported, and database statement text is never captured at all. Diagnostics should not quietly become a second copy of the data they exist to help protect.
08 The cross-tenant console is not on the public internet
The internal console used to create and manage organizations sits behind Cloudflare Zero Trust. An unauthenticated visitor is stopped at the network edge and never reaches the application at all.
Defense in depth, not the only defense: every privileged operation re-checks authorization in the database, so bypassing the edge still yields nothing.
Where we are, plainly
Security pages tend to imply more than they say. This one is a status
report. If a control is not in place yet, it says so — you should expect
the same candour from any vendor holding this data.
- Encryption in transit and at rest In place
- Row-level tenant isolation, enforced by the database In place
- Engine-maintained history that nobody can rewrite In place
- Append-only visit records and audit trail In place
- No stored database credentials anywhere In place
- Two-step verification (TOTP) In place
- Zero Trust on internal administration In place
- Offline punches hold no identifying data on the device In place
- End-to-end tracing with identifiers stripped from telemetry In place
- Automated isolation checks on every schema change In place
- Field-level encryption of identifying data, keys held outside the database Designed, not yet enabled
- Signed business associate agreements across all vendors Before first production PHI
- Independent security assessment Before first production PHI
What we deliberately do not collect
No background tracking
Location is captured at clock-in and clock-out. Never in between, never
while the app is closed. A caregiver’s day is not a route we record.
A lost phone gives up almost nothing
Visits captured without a signal wait on the device, encrypted, holding
identifiers and measurements and nothing else. No client name, no
address, no Medicaid number, no caregiver name — not even the wording
of a reason code, because 112 says nothing about the person it
concerns while the sentence it stands for might.
Someone who takes a caregiver’s handset gets a list of anonymous
identifiers and coordinates, with no way to say whose care they
describe. Lost and stolen devices are the most commonly reported cause
of healthcare data breaches, so we assumed it will happen and made the
phone a poor thing to steal.
No verbose query logging
Database auditing is scoped to schema and permission changes. Statement
text is deliberately excluded, because logging it would copy personal
information into logs that then need protecting too.
Questions from a compliance officer are welcome
We would rather answer a hard question early than discover a mismatch during
an audit.
Contact us about security