Security
Short version: the controls below are real and you can ask us to walk through any of them. We are not SOC 2 certified and no audit is underway.
Start here
The facts, in one table
Every row is either a statement of what is in place or a statement that something is not. There is no row here we would have to soften on a call.
| Topic | Where it stands |
|---|---|
| Encryption in transit | HTTPS everywhere, terminated at our own edge, with HSTS for a year across subdomains. No practice hostname answers plain HTTP. |
| Encryption at rest | Identifying fields are encrypted inside the database, not only on the disk under it. Keys are held outside the database they protect, with a written rotation procedure. |
| Tenant isolation | A separate database per practice, not a shared table filtered by a customer id. There is no filter to miss. |
| Multi-factor authentication | Required of administrators, using an authenticator app with single-use recovery codes, and neither they nor the practice can lift that. Optional for everyone else until the practice requires it of the team. |
| Backups | Every 24 hours, encrypted before they leave the machine, kept 30 days. Every cycle is restored into a scratch database and checked against the row counts taken at dump time. |
| Recovery objectives | Not contractually committed. We will not put a number in an agreement until it is one we would be held to. |
| Audit logging | Append-only, and it records reads as well as changes. Kept for the life of the account and included in the export. |
| Certifications | None. Not SOC 2 certified and no audit underway. We do not claim our host's certifications as our own: their compliance covers their data center, not our software. When that changes we will say so here, with a date and a report you can ask for. |
| Support hours | Monday to Friday, 9 to 5 Eastern, from the person who built the software. The mailbox is still read outside them, with nothing promised about it, and there is no published response time. If your practice opens on a Saturday, raise that on the call. |
| Security contact | huzaifa@vetmira.com, read by the person who built the system. No security@ address yet: one nobody watches is worse than none. |
| Hosting region and subprocessors | Everything runs in the United States. The full list of who touches your data is below. |
Subprocessors
Who else touches your data
| Who | What for | What they hold | Where |
|---|---|---|---|
| Amazon Web Services | The application servers and every database | Everything your practice records. That is the control database, your practice's own database, which is separate from every other practice's, and the separate store behind the enquiry form on this site. | US East (Ohio) |
| Backblaze | File storage and nightly backups | Pet photographs, clinical documents and message attachments, and the encrypted nightly copy of every database | US East |
| Stripe | Card payments | Card details, typed on Stripe's own page. They never reach our servers, which is why we can say no field here could hold a card number. | Per Stripe's terms |
| Twilio | Text messages. Active. | Recipient phone numbers, the short message text, and delivery and reply metadata. What is never in that text is the reason for a visit, a diagnosis or a result: a message says something is waiting and the portal holds the rest, because a text is read on a lock screen by whoever is holding the phone. | Per Twilio's terms |
| Amazon SES | Sign-in links, reminders and alerts. Active. | Recipient addresses, the short message text, and delivery, bounce and complaint metadata. It sends from a subdomain of its own rather than from the mailbox we reply from, so a delivery problem with one cannot take down the other. The same rule about contents applies: the subject and the body carry no clinical information. | Per AWS's terms |
| Google Workspace | The mailbox we reply from | The reply thread with anybody who writes to us, and the alert that an enquiry arrived, which carries a reference number and no personal data. | United States |
| Cloudflare | Domain names only | Nothing. It answers the question "which server is vetmira.com". No request passes through it: your browser connects to our server, and our server holds the certificate. | Not applicable |
A demo tenant does not send. Its messages are rendered and recorded exactly as a real one's are, then stopped at the last step: the owners in a demo are invented, and that is no reason to text a real number if one is mistyped into it.
Last verified 13 August 2026.
Controls
What is in place
- Owners are added by your practice
- Public sign-up is off, and is off by default for every practice. An owner reaches the portal because you added them and sent a link, so nobody outside your client list can create an account against you. The registration route exists and refuses while the setting is off; turning it on is a deliberate change we would make with you.
- Access by role
- Every screen and endpoint is gated on a named permission, with a test that fails the build if the two drift apart. A role is shown no control it would be refused.
- Two factor, required of administrators, and of everyone else if you say so
- Why those two rules and not one: an administrator can export this clinic and disable its staff, and a nurse forced into it at setup writes the codes on the monitor. When you do require it of the team, nobody is signed out mid-shift and turning it off again never removes anybody's factor.
- Sessions that end when you say so, and on their own
- A password change ends every outstanding session, and signing out ends it on the server rather than only in the browser. Staff idle out after two hours, the owner portal after 48, and both stop at seven days however busy. Staff accounts are disabled, never deleted, and an admin cannot demote the last one.
- The password again, before anything binding
- Signing a consent, approving an estimate, paying and moving an appointment each ask an owner for their password again. Each confirmation covers one action and expires in minutes.
- Notes that cannot be rewritten
- Locked by the database, not the application: a trigger refuses edits and deletes across every field that carries clinical meaning. Corrections are added beside a note, never into it.
- Releases logged separately
- Sending records to another practice, an insurer or an owner is recorded as a disclosure in its own right, so you can answer who was sent what.
- PCI scope
- Payment happens on the processor's own page, which keeps our scope the simplest kind rather than a project.
- Your processor account is yours
- Each practice connects its own. Its own dashboard, its own funds, its own dispute history, and it keeps all three if it leaves.
The legal question
We built to the human-medicine standard
The safeguards on this page are the technical ones HIPAA names for human medicine: encryption in transit and at rest, access by role, an append-only audit log, notes that cannot be rewritten, and multi-factor authentication. Your clients' records get them whether or not a law demands it.
HIPAA does not cover animals, so what binds you is elsewhere: your state's veterinary record confidentiality rules, owner personal data and breach notification law, PCI, and TCPA for text messages. Which of them apply depends on where you operate.
Access
Our access to your records
We run the servers, so we hold the credentials to every practice database. There is no support screen that opens a clinic's records, and anything that needs a look at real data is a screen share, with you driving.
The one thing our operator console does on your behalf is take a full export. It needs a written reason, it is rate limited, and it is logged when requested and when it finishes. It cannot open a chart or take a payment.