Skip to content
Trust / SecurityFrankfurt, EU · Updated 29 Sep 2026
Security overview

The parts that touch personal data were built to be audited.

Veil processes the most sensitive material an organisation holds, on behalf of a request it is legally obliged to answer. This page is what a security review usually has to extract over three calls.

Data residency

Everything stays in the European Union.

There is no region setting to get wrong, because there is only one region. Each component below is pinned, not merely defaulted.

Database and authentication

Frankfurt

Row-level isolation per organisation

Object storage

Frankfurt

Private buckets, no public objects

Processing workers

Frankfurt

No public ingress beyond a health check

Web functions

Frankfurt

Pinned at the deployment level

Model inference

European provider

No case, document or account identifier goes with the content

Encryption and purge

A purge destroys the key, not just the rows.

The personal data densest in identifiers is encrypted under a key belonging to your case, and that key is itself wrapped by a key belonging to your organisation.

Encrypted before it is stored

AES-256-GCM, applied on our servers before the data reaches the database. The keys never reach the browser. Decryption happens on our servers in Frankfurt, in the component that processes documents and in the web application's server functions, and the only decrypted content the browser receives is the short excerpt around an entity that a reviewer opens on the review screen, after the server has checked they may see it. None of it reaches a log.

What stays readable, and why

Five things are not encrypted under the case key. The display name of each entity the system finds, which is the fullest spelling of that name, email address or identifier exactly as it appeared in your documents: the review screen shows it so that a reviewer can tell who is who across documents, and encrypting it under the case key is planned but not yet done. The normalised form of a name or identifier, which is what lets the system recognise two spellings as the same person: encrypting it would break that matching or leak the same information anyway, and it is a folded, lower-case form rather than the text as it appeared. The identifiers you declare for the data subject, which detection matches against. The external reference you can give a case to tie it to your own request tracker, which identifies a person if your tracker puts one in it. And the names of the files in a case and of any connected folder they came from. All five are held by our database provider, Supabase, in Frankfurt. Each is covered by every other control on this page, but we would rather say so than let you assume otherwise.

Crypto-shredding

When a case purges, the case key is destroyed along with the rows. Everything encrypted under that key is unreadable from that moment, wherever a copy of it survives, including in a backup. The five things above are deleted with the rows rather than shredded, so a backup taken before the purge still holds them for as long as that backup can be restored, which is seven days. The originals, the generated documents and the bundles are deleted outright.

Encryption in transit

TLS on every hop, including the internal call from the web tier to the component that processes documents, which is authenticated in its own right.

Retention

Cases expire on a clock you set.

Retention is a plan-capped setting, not a support ticket. A released case purges on schedule and leaves an accountability record with no personal data in it.

Default retention after release
30 days
Maximum retention
Up to 90 days by plan
Unreleased cases
Purged at 180 days, with warnings first
What the purge removes
Objects, extractions, entity mentions, the case key
What the purge leaves
A tombstone: reference, dates, counts, quality summary

Access control

Nothing is listable, and nothing is long-lived.

Signed URLs only

Storage is never browsable and holds no public object. Each file is reached through a short-lived link to that one object, issued by a server route that re-checks membership and role at the moment of issue.

Row-level isolation

Every tenant table carries the organisation id and a row-level security policy. Cross-organisation reads are refused by the database, not by application code.

Roles and multi-factor

Owner, admin, member and viewer, with multi-factor authentication available on every plan.

Logging and audit

Logs carry counts. Never content.

No personal data in logs

Loggers accept identifiers, counts, enumerations and durations, and nothing else. The property is enforced automatically on every change rather than remembered by whoever writes the line.

Model calls logged as arithmetic

An inference call is recorded as counts and durations. The prompt, the completion and any recognised text are never written to a log.

Append-only audit trail

State transitions, entity decisions, bundle downloads, each opening of the unredacted excerpts a reviewer reads around an entity, and settings changes are appended through a single writer and cannot be edited afterwards. Each entry is deleted six years after it is made.

Product integrity

The check that clears a document is not the thing that redacted it.

Verification is independent

Every generated document is checked by a component built and run separately from the redaction itself, so a mistake in the redaction cannot pass its own check. The separation is enforced automatically in our build, not maintained by convention.

Nothing uncleared ships

A document the verification cannot clear is withheld from the bundle rather than released with a warning attached, and the case page flags it to whoever releases the case. Withholding one document does not cost you the rest of the bundle.

Hostile input parsing

Archive, email and office document parsers are treated as an attack surface: guards against malicious archives, per-job memory and time budgets, and fuzzing in continuous integration.

Constrained egress

The component that handles document content has no general outbound network access. It reaches an explicitly allowed set of destinations and nothing else, extended only by a connector your organisation chooses to enable.

Quality gated in CI

Every change that could affect detection quality is measured against a labelled corpus before it can ship. A change that finds fewer of the planted third parties, or that starts removing the data subject, does not merge.

If something goes wrong

The clock is in the contract, and it starts before you ask.

Everything above this section is about prevention. This is what we owe you when prevention has failed, and none of it is new here: each point restates a clause you already signed, linked underneath so you can read the binding version rather than our summary of it.

The clock is contractual

Clause 6.1 of the Data processing agreement commits us to notifying you without undue delay, and in any event within 48 hours, after becoming aware of a personal data breach affecting your personal data. It is a term of the agreement rather than a service target, and it runs whether or not you have asked. Clause A2.7 commits us to a written procedure behind it, which is where the moment awareness begins is defined and recorded, so the start of the clock is a fact in a record rather than somebody's recollection of a weekend.

A suspicion starts it, not a confirmation

Clause 6.4 is the trigger this product specifically has. If the independent verification finds a surface we had decided to redact in a bundle you have already released, we treat that as a suspected personal data breach and notify you under clause 6.1, rather than waiting until we know how far it went. The same finding before release is the ordinary path and not a breach: the document is withheld from the bundle, which is what the section above this one describes.

You decide, we supply

Notifying a supervisory authority or the affected data subjects is your decision as controller, and clause 6.3 leaves it there. Our job is what clause 6.2 sets out: the nature of the breach, the categories and approximate numbers of data subjects and records concerned, the likely consequences, and the measures taken or proposed, given to you in phases if phasing is the only way to get you the first part while you can still act on it.

How to reach us out of hours

One address, and it is the same one in every document we publish: security@pritect.ai. The Coordinated disclosure policy says what to put in a report and what we do with it. Clause 5.1 of the Acceptable use policy already routes a released bundle that still carries somebody else's personal data to that address as a priority one incident. And clause 4.4 of the Coordinated disclosure policy says plainly that where a report shows customer personal data has been exposed, the clock in the first point above runs on its own, independently of anything else happening with the report.

Sub-processors

Who else touches the data.

The complete list. The authoritative version, with the transfer position and the notice period for changes, is the sub-processor list in the trust centre.

Supabase

Database, authentication and object storage

Frankfurt, EU

Fly.io

Document processing workers

Frankfurt, EU

Vercel

Web application hosting. Its server functions decrypt the short excerpts a reviewer opens on the review screen

Frankfurt, EU

Mistral AI

Entity detection and optical character recognition

EU

Stripe

Billing. Never receives document content

EU

Resend

Account email: sign-in links, password resets, invitations and service notices. Never receives document content

EU West 1, EU

Google

Analytics on the public pages only, after you accept the analytics category. Never receives document content, and nothing at all from behind sign-in

Global, including the United States, under Standard Contractual Clauses

Pritect Veil / Get startedGet started · See pricing

Your next access request does not have to eat a week.

Open a case, declare the subject, drop the documents in. Veil redacts, raises what it is not sure of, and shows you its working.