Trust Center

Every claim here is traceable to code.

Security posture, data retention, sub-processors, and incident response. Forward-looking items say so. Nothing on this page is aspirational copy.

Data flow

Processed and stored in Canada.

Your text travels over TLS to the detection API (Fly.io, Toronto), is scored by Google Vertex AI in Montreal, and the block/allow decision comes back. On that path the prompt is not written to any database. What we do keep, and for how long, is the table below, and each row is enforced in code or config.

On residency, including the part most vendors skip. Storage is Canadian: the API, the dashboard and the database all run on Fly.io in Toronto. Detection is Canadian too, and that is worth stating separately, because it is the half that is most often quietly untrue.

Scoring runs on Google Vertex AI pinned to the Montreal region. Google commits to performing ML processing, explicitly including inference, in the region where the data is stored. That is a stronger guarantee than a provider merely having a Canadian address, and it is the distinction we would encourage you to test on any vendor you assess, including us.

We put it that way because we got it wrong ourselves. Detection previously ran on a deployment type that let our provider serve a request from any region worldwide while the underlying resource sat in Canada. We found it on 30 July 2026, published the failure on this page the same day rather than waiting until it was fixed, and moved detection to Montreal. Our code now refuses to start against a non-regional endpoint, so it cannot recur silently.

Data classWhat it isKept for
Prompt text in flightThe text being scoredNot persisted. Scored, then discarded.
Session entity codesEntity category codes for cross-message detection ("an email was seen"), never values (DB constraint + CI test)24 hours
Redaction mapsOriginal values mapped to tokens, only when you use tokenize/restore30 days, plus on-demand DSAR deletion
Incident capturesRaw prompt text. Off by default. Written only if one of your admins switches it on, and only when a user overrides a block with Send Anyway. Encrypted (server-side key, or client-side zero-knowledge where we never hold the key).Content cleared at 90 days, row at 365
Audit metadataEntity-type codes, platform, was-blocked. Never raw PII.365 days
Usage meteringPer-key request counts for billing. No prompt content.Retained for billing
Operational logsNo prompt or reply text, only lengths, hashes, countsProvider log window
BackupsRolling database snapshots5-day rolling window

Erasure on request: a data-subject erasure hard-deletes audit and incident rows and cascades to the detection API to delete redaction maps immediately rather than waiting out the 30-day TTL. If any step fails, the erasure is reported as failed, never as complete.

Security posture

How it is built.

The decision is server-side

Detection, scoring, combination rules and the block decision all execute in the API. Nothing that calls it can override or weaken that decision, because there is no policy logic on the caller to tamper with. This holds whatever sits in front of the API, so how you deploy does not change the security properties on this page.

Prompts are discarded after scoring

On the detection path, text is sent to the detector, scored, and discarded. It is not written to a database. Session memory stores entity category codes only, enforced by a database constraint and a CI test. One boundary on that claim, stated in full below: your team can deliberately switch on incident capture.

The one way a prompt gets stored, and you control it

There is exactly one path that writes prompt text to a database, and it is off unless an admin on your team turns it on. It fires only when someone overrides a block by clicking Send Anyway, which is the event a governance team actually needs to review. Cancelling stores no text at all. When it is on, content is encrypted before storage, either with a server-side key or in a zero-knowledge mode where we never hold the key. If the encryption key were ever missing, the record is written without content rather than in the clear. Content is erased at 90 days and the row at 365. We would rather show you this switch than have you find it.

Nothing sensitive in logs

No prompt or reply text is ever logged. Unreadable detector replies are logged as a length and a hash prefix, never content. Retention sweeps and erasures log counts only.

Encrypted in transit and at rest

TLS everywhere, including the database connection. Provider disk encryption at rest on Fly.io and Google Cloud. Opt-in incident content gets application-layer encryption on top (server-side key, or client-side zero-knowledge where we never hold the key). Application-layer encryption of redaction maps is in progress and stated as roadmap, not claimed as shipped.

Fail-safe by design

An unreadable detector reply fails closed (blocks). An upstream outage returns HTTP 503 within seconds instead of hanging or silently allowing.

Access is one person, disclosed

PII Shield is operated by a single person with MFA on every production account (GitHub, Fly, Google Cloud, Clerk, Stripe), secrets held only in provider secret stores, and no customer PII touched in operations outside the audited DSAR path. We disclose the bus factor rather than hide it; wind-down terms are in the incident-response doc.

Connecting

What your IT team has to do.

Less than most vendors ask for, because the service is a single stateless HTTPS call that returns a decision.

One outbound destination

One HTTPS endpoint to allowlist. We never open a connection into your network, so there is no inbound rule, no VPN and no tunnel to approve.

One key, scoped to you

Keys are issued from the dashboard and stored hashed, and a key resolves to your team so your custom terms and policy apply and nobody else's do.

Straight about the state of this: per-key enforcement and rate limiting on the detection endpoint are the work in front of us and are not switched on yet. What that does and does not mean matters. The detection path holds no state, reaches no customer record and writes nothing to a database, so what is exposed is our own cost and model quota, not your data and not another tenant's. The paths that do touch stored data already require a signed token today.

Nothing to host

No appliance, no agent on your servers, no certificate exchange, nothing to patch. If you want to try it before any of the above, the endpoint speaks ordinary JSON and you can call it from a terminal.

Sub-processors

Who else touches data.

We notify customers before adding a sub-processor that touches their data. The AI sub-processor sees prompt text in order to score it. Nobody stores it on the detection path, and per Google Cloud's Vertex AI terms prompts are not used to train their models.

Each vendor below states whether its data terms are actually in force, rather than one blanket sentence covering all five. We read each vendor's own agreement to establish this. Most bind automatically as part of the terms we accepted at signup, so there is nothing separate to execute. One does not, and it says so.

Google Cloud (Vertex AI)

Montreal (northamerica-northeast1). Google commits to performing inference in the region where data is stored.

AI detection engine. Prompt text in transit for the scoring call; not retained by us.

Data terms: Yes, incorporated into the Google Cloud agreement

Read their terms

Fly.io

Toronto (yyz); US entity

Application + database hosting. Data at rest (Postgres) and the runtime.

Data terms: Not yet. Fly pre-signs and it activates on our counter-signature, which is being done now. We would rather say so than let you find it.

Read their terms

Clerk

US

Dashboard authentication. Dashboard user identity (email, auth), not prompt data.

Data terms: In force. Incorporated into the Agreement, effective on its effective date.

Read their terms

Stripe

US / global

Billing / payments. Billing contact and payment data (Stripe-held), not prompt data.

Data terms: In force. Forms part of the Agreement we accepted.

Read their terms

Resend

US

Transactional email. Recipient email address and message content we send.

Data terms: In force. Binding on entering the Agreement.

Read their terms
Incident response

The 72-hour commitment.

On confirming a personal-data breach that affects customer data, we notify affected customers without undue delay and within 72 hours of confirmation, with the nature of the breach, the data classes involved, the likely consequences, and the mitigation taken.

This aligns with PIPEDA breach-of-security-safeguards obligations and the GDPR Article 33 standard. Because prompts are not stored and session data is metadata-only, the blast radius of most incident classes is structurally limited, and investigations use metadata (counts, hashes, timestamps), not your content.

Certifications

The honest SOC 2 answer.

No, and at this price we will not pretend to. Here is our security overview, sub-processor list and data-flow, and we will sign your DPA. SOC 2 is on the roadmap once revenue supports the audit cost. If SOC 2 is a hard requirement today, we are not your vendor yet.

A completed CAIQ-Lite self-assessment (the industry-standard middle ground) and a pre-answered security questionnaire are available on request, alongside the full trust pack.

On the DPA

We do not publish our own. Send us yours and we will sign it, subject to review. That is deliberate rather than a gap: at this size a bespoke agreement we authored is a document your legal team would replace with their own anyway, and we would rather spend the time on your paper than on ours. Our five sub-processors are listed above and ready to be named and approved at signature.

Want the full pack?

Security overview, retention tables, sub-processor detail, incident-response plan and the CAIQ-Lite self-assessment. We send it as-is, no NDA required.

Request the trust pack