Back

Security overview

What is in place, how it is enforced, and where the limits are. Written for the director, IT lead or board member deciding whether to trust PartnerVault with confidential records.

What we optimise for

PartnerVault holds children's case records and families' financial disclosures. We treat every document as confidential by default, every uploaded file as potentially hostile until proven otherwise, and every access as something that must be attributable to a named person afterwards.

This page lists what is actually in place today. Where a control has a known limit, the limit is stated. Nothing here is a roadmap.

Identity and sessions

  • Two-step verification (TOTP authenticator app) is required for every account — staff, administrators and partners — before any document is visible. It cannot be disabled by an organisation.
  • Sensitive actions on the server require a session that has completed two-step verification in the current session, not merely a remembered login.
  • Sessions end after 30 minutes of inactivity.
  • Access is by named invitation only. Invitation links are single-use and stored only as one-way hashes, so a database read cannot recover a live link. Re-sending an invitation invalidates the previous one.

Tenant and partner isolation

Every organisation, workspace, document, version, checklist and activity record carries the identifier of the organisation it belongs to, and Postgres row-level security policies decide what a signed-in user can see. The application does not get to skip that check; neither does a bug in it.

  • A partner is a member of the specific workspaces they were invited to and nothing else. A partner who works with two agencies sees each agency's workspace separately and neither agency sees the other's.
  • Organisation-level administration is a separate, explicit role.
  • An automated tenant-isolation suite signs in as two agencies' staff, a shared partner and an outsider and probes the database directly. It runs on every code change and blocks the change if any cross-tenant read or write succeeds.

Uploaded files

  • Every upload is quarantined on arrival and cannot be downloaded, exported or read by any feature until a malware scan clears it. This is enforced by a database trigger as well as in the application, so a member who can edit their own file record still cannot publish an unscanned file.
  • Scanning uses ClamAV running on infrastructure we operate, reached only through a Cloudflare Tunnel protected by a Cloudflare Access service token and a second bearer token. Files are never sent to a third-party scanning vendor.
  • If the scanner is unreachable, files wait. They are retried with backoff for about a day and, if still unverifiable, are marked “could not be checked” and must be uploaded again. They are never released unscanned.
  • The stored file's real size and SHA-256 hash replace whatever the browser claimed. A file whose contents do not match its declared type is rejected.
  • Downloads are served as attachments with a strict Content-Security-Policy, so a document can never execute in the portal's origin.

Honest limit: ClamAV catches known malware, macro-bearing Office files and known PDF exploits well; it is weaker than commercial engines against novel, targeted malware. We chose it because every stronger alternative works by uploading the file to a vendor, which these documents cannot tolerate. The engine is one HTTP call and can be supplemented.

Audit trail

Uploads, downloads, views, invitations, membership changes, scan verdicts, AI settings changes and administrative actions are written to an append-only activity log with the acting user, the organisation, and a timestamp. Records are attributed to the organisation that owns the workspace, not to the actor's home organisation, so a partner's actions appear in the right agency's trail.

Organisation administrators can export the complete trail as CSV (up to 50,000 rows per export, formula-safe for spreadsheets). Each export is itself logged.

Retention and deletion

  • A trashed document, all its versions and its stored bytes are permanently removed 30 days after trashing. An administrator can purge earlier.
  • Blocked, rejected and unverifiable files are removed after 30 days; uploads abandoned mid-transfer after 24 hours.
  • A scheduled job enforces this hourly. The windows are constants in the source code, and the policy is written down.
  • Stored files are not included in database backups, so a purged file is not recoverable from a backup. That is intentional.

AI features: what a model can and cannot see

AI features are off for every workspace until an organisation administrator turns them on for that workspace. The check happens on the server before a document is downloaded from storage or any text is read, so a browser cannot ask for a summary of a workspace that has not opted in. Quarantined files are never read.

  • When enabled, only text extracted from documents (and page images for scanned files) is sent to the model, together with the user's question or instructions. Original files are not uploaded.
  • Document text is treated strictly as material to be read, never as instructions. It is sanitised at ingestion and fenced as data in every prompt; the assistant has no tools and cannot take actions.
  • Model output is treated as untrusted: it cannot render clickable links or fetch images, and users are told to check anything they act on against the cited file.
  • Turning AI off for a workspace deletes the extracted-text copies it kept, immediately, and records that in the activity log.
  • Each organisation has a monthly AI spend ceiling with a circuit breaker.

Requests go through an AI gateway to the underlying model provider. Before enabling AI on a workspace holding confidential material, confirm with us that the provider commitment in force is no training on customer data and no retention beyond the request.

Honest limit: extraction cannot see white-on-white or off-page text in a PDF, and prompt containment lowers the risk of a document manipulating the model; it cannot prove the model will obey.

Platform and edge

  • Data is stored in the United States in Postgres and encrypted object storage on Supabase; the application runs on Cloudflare Workers behind the customer's own Cloudflare zone with Full (strict) TLS, WAF and rate limiting.
  • Every response carries a strict Content-Security-Policy with nonce-stamped scripts (no inline script allowance), plus the standard hardening headers.
  • Every server-function input is schema-validated before it reaches the database. Replayed or duplicated requests are claimed once in the database before any work happens. Each organisation has a write-rate ceiling, and a suspended organisation cannot write at all.
  • Concurrent edits to the same workspace are detected rather than silently overwriting one another.

Incidents

We maintain a written incident and breach-notification runbook covering containment (suspending an organisation or account, revoking sessions, rotating the scanner and cron credentials), evidence preservation from the audit trail, and notification of the affected organisation. If you become aware of a security issue, write to the address below and we will acknowledge within one business day.

Independent review

The codebase was hardened in 22 reviewed pull requests, each with its own verification record, and a review handoff document lists every control, how it was verified, and the known limits. We share it, and the underlying documents on AI data flow, retention and incident response, with prospective customers on request.

Questions or a security concern?

Write to [email protected]. We can share the review handoff document, the AI data-flow disclosure, the retention policy and the incident runbook.

Contact us