Subprocessors
Verheim's subprocessor list — every vendor in the data path with purpose, data scope, jurisdiction, DPA, and Provisioning status.
Scope of disclosure
This page lists every processor in Verheim's data path: any third party that processes personal data on Verheim's behalf, OR that provides infrastructure on which Verheim runs services that process personal data. Verheim publishes this list under NFR-I1 ("every integration vendor processing personal data on Verheim's behalf appears in the published subprocessor list") and NFR-Pr1 (GDPR Art. 28 transparency).
Self-hosted analytics and synthetic monitoring services on Verheim's own infrastructure are explicitly disclosed in the table below but flagged as "not a third-party subprocessor" because they run in-house on Verheim's own VPS, not on third-party infrastructure. The underlying VPS provider is itself listed in the table as a separate row — listing the in-house service does not double-count, it discloses the named service.
At the date of this revision, Verheim's production data path is in the Phase-C provisioning window: the origin VPS, the domain and TLS registration, the CDN pull-zones, the Git-hosted CI gates, and the no-JS smoke required-check are each operator- bound provisioning steps that have not yet completed. The published list discloses the planned data-path graph; the actual data path tracks toward the published list as each step lands. Each row's Provisioning status column makes the planned-vs-active state structurally readable so the page reads honestly at any provisioning state. NFR-Pr4 names a discrepancy between the published list and the actual data path as a notifiable incident — the published list is therefore the disclosure-of-record at every point in time.
Subprocessor table
| Subprocessor | Purpose | Data scope | Jurisdiction | DPA | Provisioning status |
|---|---|---|---|---|---|
| Hetzner | Origin hosting, Gitea, isolated Actions runner, backups | Site source, build artifacts, system logs, IP for rate-limiting, encrypted backups | Germany (DE) | DPA for Hetzner (opens in a new tab) | Planned (D001 pending) |
| Bunny.net | CDN, preview pull-zones, Bunny Shield WAF | Cached site content, IP for edge routing | EU-only routing (multi-EU PoPs) | DPA for Bunny.net (opens in a new tab) | Planned (D003 pending) |
| Gandi | DNS authority, domain registrar | Domain registration data, DNS query logs | France (FR) | DPA for Gandi (opens in a new tab) | Planned (D002 pending) |
| Let's Encrypt (ISRG) | TLS certificate issuance | Public domain names; no personal data | USA (ISRG headquartered US; certificates issued globally) | DPA for Let's Encrypt (ISRG) (opens in a new tab) | Planned (D002 pending) |
| Brevo | Transactional email primary (form-submission acknowledgments, admin notifications) | Recipient email, form submission contents | France (FR) | DPA for Brevo (opens in a new tab) | Planned (Epic 4 pending) |
| Scaleway TEM | Transactional email fallback | Recipient email, form submission contents | France (FR) | DPA for Scaleway TEM (opens in a new tab) | Planned (Epic 4 pending) |
| URIports | DMARC, SMTP-TLS, MTA-STS aggregator | Email-authentication aggregate reports (no personal data) | Netherlands (NL) | DPA for URIports (opens in a new tab) | Planned (Story 3.6 pending) |
| Hetzner Storage Box | Off-site encrypted backups | Encrypted backups of site sources, build artifacts, audit logs | Finland (FI) or Germany (DE) | DPA for Hetzner Storage Box (opens in a new tab) | Planned (D001 pending) |
| Plausible Community Edition | Web analytics | Page views, referrer, user-agent (per ADR-004 zero-PII contract) | Self-hosted on Hetzner — not a third-party subprocessor | n/a (in-house instance) | Self-hosted on Hetzner — not a third-party subprocessor |
| Uptime Kuma | Synthetic monitoring | Site uptime probes (no personal data) | Self-hosted on Hetzner — not a third-party subprocessor | n/a (in-house instance) | Self-hosted on Hetzner — not a third-party subprocessor |
All third-party subprocessors processing personal data are EU-resident; Let's Encrypt (US-incorporated) processes non-personal data only and is included for completeness per NFR-I1.
Schrems II posture
Verheim operates an EU-resident data path. NFR-Pr4 binds Verheim to "no US-processor in the data path for form submissions, analytics, or hosting without documented supplementary measures". Every personal-data-processing vendor in the table above is EU-resident: Hetzner (DE), Bunny.net (EU-only routing across multi-EU PoPs), Gandi (FR), Brevo (FR), Scaleway TEM (FR), URIports (NL), Hetzner Storage Box (FI/DE).
Let's Encrypt (operated by ISRG, US-incorporated) processes non-personal data only — public domain names submitted for TLS certificate issuance — and is therefore disclosed for completeness per NFR-I1 without requiring Schrems II supplementary measures. The carve-out is named on the row in the table above and again in the editorial note that follows the table.
The controller-side disclosure of the same Schrems II contract appears on Verheim's privacy policy under its Transfer posture section. Procurement reviewers and EU regulators may correlate the two disclosures: the privacy policy describes the contractual posture; this page describes the per-vendor implementation.
Vendor-addition discipline
Adding a vendor to Verheim's data path is gated on a documented
review process. Per the contract recorded in
config/security/external-hostnames.txt, vendor
additions require:
-
A pull request via
.gitea/PULL_REQUEST_TEMPLATE/external-hostname.mdcapturing vendor name + DPA URL + data categories + Schrems II posture + theconfig/security/external-hostnames.txtcommit reference; -
CODEOWNERS approval from the
@verheim/securityAND@verheim/privacyreviewer groups; AND -
A simultaneous edit of
config/security/csp-directives.txtif the vendor is fetched at runtime from a browser session, plus a simultaneous edit ofsrc/config/subprocessors.tsso this page reflects the addition.
The PR template and CODEOWNERS routing assets are themselves operator-bound on Verheim's Gitea provisioning. Pre-Gitea- landing, the discipline is honoured editorially via PR description prose mirroring the template fields; post-Gitea- landing, the assets are authored in a coordinated patch alongside the Gitea provisioning step.
Drift-incident contract
A discrepancy between Verheim's actual data path and this published subprocessor list is an incident under NFR-Pr4 and triggers the breach-notification process if personal data is affected. Subprocessor-list update is therefore a mandatory pre-flight step whenever a new vendor enters the data path — the published list must always lead the actual deployment, not trail it.
Drift-detection runs on two channels:
- Automated dist-scan — Story 1.15 ships a
build-time scan that compares every external hostname
referenced in
dist/against theconfig/security/external-hostnames.txtallowlist. This catches runtime-fetched hostname drift (e.g. a third-party script or font URL slipping into the bundle without the corresponding allowlist + subprocessor-list update). - Manual review — at vendor-addition time and
at every retrospective, an operator reviews the actual data
path against this list. Manual review is the only mechanism
that catches non-runtime vendor drift (Hetzner origin, Brevo
SMTP relay, Hetzner Storage Box backups — vendors whose URLs
do not appear in
dist/).
The operational playbook for a confirmed drift incident is
Verheim's docs/operators/runbooks/incident-subprocessor-drift.md
runbook — registered at architecture.md:866 and authored under
the Epic-9 incident-runbook batch. The runbook codifies
detection, immediate response (subprocessor list update + GDPR
Art. 33/34 breach-notification consideration if PII-affected),
and recovery.
Last revision
Last revision: 0440a2a (opens in a new tab) on . The short SHA is the audit-trail value: it pins this published list to a Git commit in Verheim's repository so an EU regulator or procurement reviewer can verify which revision of the list they are reading. The Date matches the page's publication date; the SHA may differ if a post-publication patch updates the page without re-dating the publication.