Trust
The controls, the evidence behind each one, and TollRelay's sub-processors.
TollRelay is not certified. Certification is the audit scheduled at incorporation, and until it completes the honest claim is the one above: these controls are implemented as marked, here is the evidence, and no third party has yet reviewed it.
Controls
Reviewed 15 September 2026 against the scaffold on develop.
| Control | Status | Implementation | Evidence |
|---|---|---|---|
| Tenant isolation | Built | Forced row-level security on every table that carries organisation_id, in both planes and on the control plane's receipts. One sanctioned access path. The Workers connect as a login role that is a member of the application role. | The row-level security proof in packages/db/test, run in CI; the deploy's login-role privilege check. |
| Regional residency | Partial | Every organisation carries a region, encoded in every identifier. Five databases across Frankfurt and Virginia. The residency test reads the region map. The cross-region alarm is planned. | infra/neon/provision.test.ts; the region column and the id prefixes. |
| No money held | Built | No code path takes a payment, holds a balance, settles to a seller or enforces a mandate on its own. The verify route refuses a voucher, a word that names nothing in v3.1. Amounts are integers in the database and decimal strings on the wire. | apps/api/test/app.test.ts; the contract's money tests. |
| Signing keys | Partial | Per-plane signer Worker, keys in the Secrets Store bound read-only, public halves only at the JWKS, two entrypoints so the directory caller cannot sign. Provisioning waits on the founder. | The key inventory below, once keys exist; the revocation drill, once written. |
| Machine key custody | Built | A machine's private key is returned once at creation and never stored; only the public half is in the plane. | The plane schema and the no-personal-data catalogue test, which refuses a private column. |
| Change control | Built | Every change to an organisation, an identity, a mandate or a key writes an append-only receipt row. | The append-only proof in CI. |
| Fail-closed credentials | Built | A missing or malformed credential answers 401 with the challenge; a write without an Idempotency-Key answers 400; a missing secret throws before any handler runs. | apps/api/test, apps/auth-region/test. |
| Personal data in errors | Built | Validation errors name fields, never values. No email, name, wallet or key material in a body or a log line. | apps/api/test asserts the value is absent. |
| Transport and headers | Built | Custom domains with the edge provider's certificates, HSTS with preload, nosniff, frame denial, a hash-listed content security policy on the site and a strict one on the dashboard. | packages/config/security-headers.mjs, apps/web/src/lib/csp.test.ts. |
| Secrets | Built | No secret in code, CI or an environment file. gitleaks blocks the pull request. One CI identity by OIDC; Workers read bindings only. | The secret scan results from every run. |
| Access control | Planned | Roles owner, admin, finance, support with expiring memberships are in the schema. The step-up before revoking a key and the access review export are planned. | The access review export, once it exists. |
| Incident and availability | Planned | The incident runbook commits to notice within twenty four hours. The status page is a placeholder. | docs/runbooks/incident.md; the status history once the page exists. |
| Backups | Planned | The provider's daily snapshots and a nightly encrypted export, once the projects exist. | docs/runbooks/backups.md; the restore drill log. |
| Sub-processors | Built | Seven named suppliers, listed with what each receives. | docs/security/sub-processors.md. |
| Accessibility | Built | WCAG 2.2 AA by construction: the contrast gate over every token pair in both themes and axe over every route in both themes. | bun run gate:contrast, bun run gate:axe, in CI. |
Key inventory
No signing key exists yet. The table fills when the founder provisions the Secrets Store.
| Key | Plane | Region | Purpose | Generated | Rotation |
|---|---|---|---|---|---|
| None yet. | |||||
SOC 2 and ISO 27001 mapping
The controls above map to trust services criteria and Annex A controls as follows. The auditor confirms the mapping; it is stated so the build has something to prove.
| Control | SOC 2 | ISO 27001:2022 Annex A |
|---|---|---|
| Tenant isolation | CC6.1, CC6.3 | A.5.15, A.8.3 |
| Regional residency | CC6.1, P4.1 | A.5.31, A.8.10 |
| No money held | CC2.2 | A.5.34 |
| Signing keys | CC6.1, CC6.7 | A.8.24 |
| Machine key custody | CC6.1, CC6.7 | A.8.24 |
| Change control | CC8.1 | A.8.32 |
| Fail-closed credentials | CC6.1, CC6.6 | A.8.5 |
| Personal data in errors | CC7.2, P6.1 | A.8.15 |
| Transport and headers | CC6.7 | A.8.20, A.8.24 |
| Secrets | CC6.1 | A.8.24 |
| Access control | CC6.2, CC6.3 | A.5.16, A.5.18 |
| Incident and availability | CC7.3, CC7.4, A1.2 | A.5.24, A.5.26, A.5.30 |
| Backups | A1.2 | A.8.13 |
| Sub-processors | CC9.2 | A.5.19, A.5.21 |
Sub-processors
Seven suppliers will process data on TollRelay's behalf. Each row says what that supplier sees. Anything not on this list does not receive customer data. Certifications belong to the supplier and are published on the supplier's own trust page.
Written 15 September 2026 against the scaffold. Reviewed quarterly; any addition or removal is a change to this file, to the trust page and to the customer notice in the same pull request.
| Sub-processor | What it sees | Region | Next review |
|---|---|---|---|
| Cloudflare | Every request to every surface: address, headers, path, and the bytes served. Runs every Worker and holds the signing keys in its Secrets Store bound to the signer. | Global network. Data, keys and logs are pinned to region. | 15 December 2026 |
| Neon | All stored data. The control plane holds registries and keyed hashes. The identity databases hold people. The planes hold organisations, machines, mandates, spend, receipts. | Control and European databases in Frankfurt. United States in Virginia. | 15 December 2026 |
| Infisical | Secrets only. It never sees customer data. | European cloud. | 15 December 2026 |
| Didit | The business verification: the organisation's legal identity, its beneficial owners and the sanctions screen. TollRelay stores the result as a state, never the documents. | Per their trust page. | 15 December 2026 |
| Stripe | Subscription and invoice data for a paying organisation or verifier: the buyer's name, email, billing address and card, which TollRelay never holds itself. | United Kingdom entity, processing globally. | 15 December 2026 |
| Resend | Outbound email: the recipient address, the subject and the body of every sign-in message, and the delivery result. | European region on the sending domain. | 15 December 2026 |
| A sanctions list provider | The keyed hash of a wallet or a legal name screened at first sight. Chosen with the sanctions issue; named here when it is. | To be recorded. | 15 December 2026 |
What none of them see
The private half of a machine key: it is returned once to the organisation and never stored anywhere. The private half of a TollRelay signing key: held by one supplier, the edge provider, in its Secrets Store, bound read-only to the signer.
Retention
| Row | Bound | Enforced |
|---|---|---|
| An idempotency key | Twenty four hours after the write | The column is set on every row; the maintenance role prunes. |
| An invitation | Seven days, or acceptance | Deleted on acceptance; expired rows pruned. |
| A verification code | Ten minutes | better-auth's own expiry. |
| A spend row | As long as the organisation | Append-only; exported on request; deleted with the organisation. |
| A KYB check | As long as the organisation | A state and a session reference, never a document. |