Legal
Security Statement — Zoravet (NIS2 / Cyberbeveiligingswet themes)
Company details: Jensen Software, KvK 96526181. This statement is written for clinics — our business customers — who increasingly ask their software suppliers to describe their security measures, including against the themes of the EU NIS2 Directive and its Dutch implementation, the Cyberbeveiligingswet. It is a transparency document, not a certification and not a contract; the binding data-protection commitments live in the Data Processing Agreement.
1. Scope and entity status (honest position)
- What this covers: the Zoravet platform operated by Jensen Software — the Flutter pet-owner app, the React clinic portal, the Spring Boot backend, and the cloud infrastructure that runs them.
- NIS2 / Cyberbeveiligingswet applicability: Zoravet is a small SaaS provider. We do not claim to be a designated “essential” or “important” entity under NIS2 / Cyberbeveiligingswet, and we believe direct regulatory scope is unlikely for an organisation of our size and sector. Formal confirmation of entity classification with legal counsel — including whether a clinic customer’s own NIS2 status carries any supplier obligations down to us contractually — is in progress.
- Why we publish this anyway: clinics that are themselves in scope (or that simply take supply-chain security seriously) reasonably ask suppliers to evidence sound security practice. This statement is our good-faith answer, aligned with NIS2’s risk-management themes (Art. 21): governance, access control, encryption, backup/continuity, incident handling, supply-chain security, and vulnerability handling.
- Out of scope: clinic-side security (clinic devices, clinic networks, clinic staff behaviour) is the clinic’s responsibility. This statement covers Zoravet’s side.
2. Risk-management approach
- Security is treated as a design constraint, not an afterthought. The platform is built multi-tenant with isolation between clinics enforced by the software mechanism itself (see section 3), so a configuration mistake fails closed rather than exposing another clinic’s data.
- Infrastructure is defined as code (Terraform) and version-controlled, so the security configuration of the production environment is reviewable and reproducible rather than hand-built.
- Changes go through a build process with review before merge, and the platform is developed against an explicit backlog of hardening items that are prioritised before onboarding real clinics.
- Maturing areas (built, gated for go-live — stated honestly):
- Application-level observability: request latency/error-rate metrics per endpoint group, database connection-pool saturation, scheduled-sweep outcomes and notification-send failures are instrumented, with structured JSON logging carrying a request-correlation id. Alarm thresholds (5xx rate, p95 latency, a silent scheduled sweep, connection-pool exhaustion) and an operations dashboard are defined in the infrastructure-as-code. This layer is built but not yet switched on in production — enabling it is a deliberate go-live step, not an oversight. Basic infrastructure alarms (application errors, unhealthy instances, database CPU and free storage — see section 5) are configured and active today.
- Data retention enforcement: the Dutch fiscal 7-year retention floor, and shorter operational-data windows (e.g. a 2-year window for the notification log), run as a scheduled purge job. It executes today in dry-run mode by default (counts only, deletes nothing) and is disabled by default — both switches are deliberately off until validated against production data, and will be enabled at go-live. This is a built, tested, currently-dormant-by-design enforcement mechanism, not an unenforced promise.
- Load/scale testing is planned but not yet complete. We do not claim a 24/7 security operations centre or SOC 2 / ISO 27001 certification, and neither is on a committed roadmap today. An independent penetration test has not been performed, and we do not claim otherwise.
3. Access control, authentication and tenant isolation
- Authentication is handled by Keycloak (OpenID Connect / OAuth2), self-hosted by Zoravet on our own EU infrastructure. Both the pet-owner app and the clinic portal authenticate through it; the backend validates signed tokens on every request.
- Role-based access control (RBAC): users hold roles and fine-grained permissions (for example, separate permissions for finance, inventory, messaging). Staff see only the functions their role grants. Access follows least-privilege.
- Tenant isolation between clinics is the platform’s central security property. Each clinic is a separate tenant; queries are automatically constrained to the caller’s clinic by a database-filter mechanism that is enforced centrally, applies on every execution path (web requests, background schedulers, event handlers), and fails closed when the tenant context or transaction is not established. Direct record loads are additionally verified on load and rejected if they belong to another clinic.
- Independent isolation audit (July 2026): we ran a dedicated cross-tenant isolation audit with three independent reviewers as a release gate. Outcome: zero confirmed cross-tenant data leaks. The audit also drove targeted hardening (tightening bulk-update and role-assignment paths, and converting the last construction-only-safe entities to mechanism-enforced isolation). Test coverage of this property is being extended across remaining lower-risk endpoints; the behaviour is safe by mechanism, the additional tests are being backfilled.
- Administrative access by Zoravet staff to the production environment is limited to what is needed to operate and support the service. Cloud secrets are held in a managed secrets store (AWS Secrets Manager, KMS-encrypted) rather than in code or configuration files. Multi-factor authentication: Keycloak supports MFA/TOTP; it is not enforced by policy for Zoravet operators or clinic staff.
- Audit logging: actions in the portal (for example, who edited a record and when) and authentication events are logged to support accountability.
- Optional per-clinic network restriction (added July 2026): each clinic can restrict staff portal/API access to an allowlist of its own IP ranges (IPv4/IPv6 CIDR). Enforcement is server-side on staff endpoints only (pet-owner app traffic is unaffected), uses only the load-balancer-verified client address (client-supplied forwarding headers are not trusted), and fails closed for clinics that enable it. Individual staff members can be explicitly exempted by a clinic administrator (“access from anywhere”); everyone else remains bound to the allowlist. A safeguard prevents administrators from locking themselves out when saving the allowlist or removing their own exemption.
4. Encryption
- In transit: all external traffic is served over HTTPS/TLS. TLS terminates at the load balancer using certificates managed by AWS Certificate Manager; plain-HTTP requests are redirected to HTTPS. The load balancer enforces AWS’s
ELBSecurityPolicy-TLS13-1-3-2021-06policy: TLS 1.2 minimum, with TLS 1.3 negotiated where supported; TLS 1.0/1.1 are not offered. Outbound email is sent over SMTP with STARTTLS. - At rest: the production environment is deployed and this is a live fact, not only configured intent. Data is encrypted at rest precisely per service (not a single blanket mechanism):
- the PostgreSQL database (Amazon RDS) has storage encryption enabled, backed by AWS KMS (today the AWS-managed default key
aws/rds, not yet a customer-managed key); - secrets (AWS Secrets Manager) are encrypted with AWS KMS (today the AWS-managed default key
aws/secretsmanager); - document/file storage (S3) uses server-side encryption (SSE-S3, AES-256) — this does not route through AWS KMS; it is AWS-managed encryption without a KMS key.
- the PostgreSQL database (Amazon RDS) has storage encryption enabled, backed by AWS KMS (today the AWS-managed default key
- The local development environment uses stand-ins (MinIO for S3-compatible storage, Mailpit for mail) and is not representative of production security; nothing in this statement refers to development.
5. Backup, recovery and continuity
- Database backups: the production database (Amazon RDS) is configured with automated daily backups retained for 7 days, with point-in-time recovery (PITR) within that window — data loss in a real incident is bounded by RDS’s continuous transaction-log backup, not by the daily snapshot cadence, so our stated recovery-point objective (RPO) is approximately 5 minutes, not 24 hours. Deletion protection is enabled on the database instance.
- Basic operational alerting exists today: infrastructure alarms (application errors / HTTP 5xx, unhealthy service instances, database CPU and free storage) are configured and notify Zoravet by email through a monitoring topic. Deeper application-level observability is on the roadmap (section 2).
- Recovery testing: a documented restore rehearsal procedure has been executed against production (25 July 2026: point-in-time restore of the production database to a disposable scratch instance, schema-integrity and row-count verification — both passed; restore-to-verified measured at 32 minutes). Rehearsals repeat quarterly. Our recovery-time objective (RTO) is under 2 hours for a real-incident recovery; the restore-and-verify portion is now backed by that production measurement. Backups are additionally replicated cross-region (AWS eu-west-1, Ireland) for regional-failure cover.
- Data is stored in the EU (AWS eu-central-1, Frankfurt, Germany).
6. Incident handling and customer notification
- We maintain an internal breach-response approach: detect and triage, contain (revoke access, rotate secrets, isolate), assess scope (which clinics, which data categories, how many data subjects, likely consequences), notify, record, and review. The detailed, executable procedure — severity ladder, per-incident-class triage checklists (data breach / outage / data-integrity anomaly), communication templates, and the post-incident review template — is documented internally.
- Incident owner: Zoravet is currently a single-founder operation. Mart (Jensen Software) is the named incident owner and responder for every severity, notified via the CloudWatch/SNS operational alarms described in section 5. This is stated plainly rather than implying a team or rotation that does not exist; the internal runbook documents the escalation path for when the owner is unavailable.
- Notification to clinics: where a personal-data breach affects a clinic’s data, Zoravet notifies the affected clinic without undue delay and at the latest within 48 hours of becoming aware. This aligns our commitment with the clinic’s own GDPR/AVG breach duties: the clinic, as controller, is responsible for notifying the Autoriteit Persoonsgegevens (and data subjects where required); Zoravet supports the clinic with the information it needs but does not notify the AP on the clinic’s behalf. The precise contractual timing lives in the DPA and is identical to the 48-hour figure above.
- Every breach — including non-notifiable ones — is recorded in an internal log, with a post-incident review.
7. Supply-chain security (sub-processors)
Zoravet keeps its supplier footprint small and EU-first. See the Subprocessors page for the full, current list with purpose, data categories and safeguards.
- Keycloak (authentication) is self-hosted by Zoravet in the EU and is part of our own platform — it is not a third-party sub-processor.
- We impose data-protection obligations on sub-processors equivalent to those we owe clinics, and we notify clinics in advance of adding or replacing a sub-processor so they can object on reasonable grounds. The mechanism and notice period are set in the DPA (30 days).
- This list is kept consistent with the app and portal privacy policies and the DPA. If they ever diverge, the DPA’s maintained sub-processor annex is authoritative.
8. Vulnerability handling and how to report a problem
- We apply security patches to platform components and dependencies as part of ongoing maintenance.
- Responsible disclosure: if you (or your security team) believe you have found a vulnerability in the Zoravet platform, please report it to security@zoravet.nl (falls back to
info@zoravet.nl). Please give us reasonable time to investigate and remediate before any public disclosure. We do not currently operate a paid bug-bounty programme. - We ask reporters not to access, modify, or delete data belonging to clinics or their clients, and to stop at the point a vulnerability is demonstrated.
9. Review and updates
- This statement is reviewed at least annually, and additionally after any material change to the platform’s architecture, sub-processors, or security posture.
- Material changes relevant to clinics are communicated to clinic administrators. See Updates for the change log of this trust center.
Contact
- Zoravet: Jensen Software, KvK 96526181, Oanjelaan 32, 1421 AK Uithoorn, Netherlands
- General / privacy: info@zoravet.nl
- Security reports: security@zoravet.nl