Sub-Processor List
Public-facing transparency artefact (GDPR Art. 28(2) + Art. 30) and Annex A of every DPA the platform signs. Maintained in-repo so changes go through PR review; published as a webpage on
restartix.pro. Last revised 2026-09-04.
Counsel-review status
This is a developer-drafted v1. Counsel reviews wording and confirms transfer mechanisms in scope of the F11.0.5 engagement. Not for external publication until D7 close letter.
What this is
A sub-processor is any third party that processes personal data on the platform's behalf to support the service. GDPR Art. 28(2) requires the controller (the clinic) to authorise sub-processors and the processor (the platform) to publish the list. Adding, removing, or replacing a sub-processor triggers notice to every controller on the platform.
Three terms keep distinct (per glossary):
- Sub-processor — third party processing personal data on the platform's instructions (this page).
- Curated provider / Cat A — third-party API the platform calls under platform credentials (overlaps with sub-processor when the call involves personal data; see external providers).
- Connected account / Cat B — third party the clinic connects under clinic credentials (not a platform sub-processor; the clinic remains its own controller-processor relationship with that party).
This list covers sub-processors only. Cat B services (e.g. clinic's own Google Calendar, clinic's own SMS provider) appear in the clinic's own sub-processor disclosure, not ours.
Notice mechanism
Material changes to this list (adding a sub-processor, replacing one, changing the category of data shared, changing transfer mechanism) trigger:
- 30 days' notice to every controller via the in-app notification system + email to the registered admin contact.
- A controller's objection right. A controller that objects to a new sub-processor may terminate the relevant DPA in accordance with the DPA's termination terms (typically 30 days from objection).
- A change-log entry below with the effective date.
No-notice changes are reserved for security-incident response (e.g. emergency CDN swap) and are notified after the fact within 7 days.
Current sub-processors
| # | Provider | Role | Hosting / data location | Transfer mechanism | DPA |
|---|---|---|---|---|---|
| 1 | Clerk | Identity provider (sign-up, authentication, session) | United States | SCCs (Module 2) + TIA — see TIA | clerk.com/legal/dpa |
| 2 | Bunny.net | Video CDN, video storage (treatment-plan exercise videos), HLS streaming, Stream API | EU (Slovenia + EU edges) | EU-only; no Art. 44 transfer | bunny.net/dpa |
| 3 | Amazon Web Services (AWS) | Hosting (RDS Aurora, ECS Fargate, S3, ALB), email delivery (SES) | EU (eu-central-1 / Frankfurt). Single-region | EU-only at runtime; SCCs + TIA for the parent-company access surface — see TIA | aws.amazon.com/service-terms + AWS BAA via Artifact |
| 4 | Cloudflare | CDN, WAF, DDoS protection, custom-hostname routing (Cloudflare for SaaS) | Global edge (PoPs in EU + worldwide) — terminating TLS, caching public assets, proxying request paths | SCCs (Module 2) + TIA — see TIA | cloudflare.com/cloudflare-customer-dpa |
| 5 | Sentry | Application error tracking | EU region (Frankfurt) | EU-only; no Art. 44 transfer | sentry.io/legal/dpa |
| 6 | Daily, Co. | Live video consultations (WebRTC media, room + join-token management) | Media servers pinned to EU (geo = eu-central-1); control plane and corporate operations in the United States | SCCs (Module 3), incorporated by reference — see TIA T4 | daily.co/legal/data-processing-addendum — in force via the Terms of Service |
Notes per entry follow in §"Per-provider detail."
Sub-processors NOT in scope
These are referenced elsewhere in platform documentation but process no personal data today:
- Anthropic / OpenAI — AI capabilities are foundation-scaffolded (1C.8) but no AI feature ships at launch. Will be added when an AI feature is enabled.
- Stripe / Netopia / Euplatesc / Twilio — payment and SMS providers gated behind features deferred from the current scope (F12 billing engine; SMS not built).
- Anti-spam / DMARC reporting service — not in scope; SES bounce/complaint handling is the substitute.
- FGO — Romanian e-invoicing (RO VAT + e-Factura via ANAF). Not engaged: the invoicing capability is an interface only, its implementation ships with the F12 billing engine, and F12 is deliberately out of scope. No data reaches FGO today. It moves back into the table above in the same PR that ships the implementation.
Per-provider detail
1. Clerk
- What we use it for: sign-up, authentication (password + OAuth), session management, JWT issuance. Also operates the inbound webhook (Cat D) that mirrors Clerk user events into our
humansandpatientstables. - Data categories transferred: email, name, phone (E.164), DOB (when collected at sign-up), authentication metadata (last login, IP, user-agent, session expiry), OAuth provider tokens (when patient authenticates with Google/Apple).
- Data NOT transferred: patient health data (VAS, RPE, adherence), CNP, clinical records, exercise logs. Clerk never sees Art. 9 special-category data.
- Hosting location: United States. Clerk is a US company without an EU instance at the time of writing.
- Transfer mechanism: EU Commission 2021 Standard Contractual Clauses, Module 2 (controller-to-processor). TIA per EDPB six-step methodology in TIA.
- Retention: Clerk retains the authentication record while the account is active + 30 days after account deletion (per their terms). Account deletion on our side cascades to Clerk via the management API.
- Sub-sub-processors: AWS (US regions), Google Cloud (US regions), Twilio (SMS OTP if enabled — not enabled at launch). Disclosed by Clerk.
- Why this provider: consolidated identity surface across three apps + OAuth complexity + production-grade session management. Alternatives evaluated (Auth0, Supabase Auth, in-house) — see decisions.md. The Romanian-counsel-confirmable position is that the EU-data-residency cost of consolidating identity into one US-based provider is offset by the security cost of fragmenting auth across three apps.
2. Bunny.net
- What we use it for: Bunny Stream for HLS video delivery of exercise videos and treatment-plan video content; Bunny Storage for the underlying video object store; Bunny CDN for delivery edge.
- Data categories transferred: video objects (no personal-data content in the video files themselves — these are pre-produced exercise demonstration videos, not patient-recorded content); playback request logs (URL, timestamp, IP, user-agent) limited to whatever Bunny retains by default.
- Data NOT transferred: patient profile, clinical data, CNP, authentication data. The video viewer in Portal is an iframe that loads a signed playback token; the patient identity is not transmitted to Bunny in the URL.
- Hosting location: EU (Bunny is Slovenia-headquartered; the storage region we use is EU; edges are global).
- Transfer mechanism: EU-EU; Art. 44 GDPR transfer rules do not apply to the storage region. Edge nodes outside the EEA may serve cached public assets but no personal data is keyed to those nodes.
- Retention: controlled by us; we set lifecycle on Storage. Stream playback logs retained by Bunny per their terms (~30 days for raw logs).
- Why this provider: evaluated against Cloudflare Stream, Mux, Vimeo. Bunny offered the best EUR-priced bandwidth-per-GB at the expected scale (5,000 patients × ~10 sessions × ~5 minutes × 1080p). decisions.md carries the choice.
3. AWS
- What we use it for:
- RDS Aurora PostgreSQL (Multi-AZ in production) — primary platform database.
- ECS Fargate — runtime for all 6 services (API + 3 Next.js apps + telemetry + composer).
- S3 — telemetry session blobs (F10), pg_dump backups, audit-log warm-tier archives.
- ALB + ACM — public ingress + TLS termination.
- SES — transactional email delivery (the platform's outbound mail channel; see 1A's
email.Channelcapability). - KMS — column-level encryption key for
auth_secretandpii_regulatedcolumns. - CloudWatch — metrics, logs, alarms.
- Data categories transferred: every data category the platform processes — this is the host. Patient identifiers, health data, CNP (encrypted at column level for the
pii_regulatedclass), audit log, telemetry, email content. - Hosting location:
eu-central-1(Frankfurt), single-region. ⚠️ Cross-region replication of backups into a second EU region has been discussed as a DR improvement (eu-west-1oreu-north-1) but is not configured — no replication exists in any environment. - Transfer mechanism: runtime data stays in the EU. AWS as a US parent corporation has theoretical access via legal process under the CLOUD Act; SCCs (Module 2) + the additional safeguards described in the TIA (column-level encryption with platform-controlled KMS keys for the most-sensitive columns, narrow IAM, organisation-level CloudTrail, AWS BAA) form the safeguard stack. See TIA.
- Retention: controlled by us for the live database (RDS automated backups 35 days; PITR window 35 days; audit log 6+ years per data retention). The Layer-2
pg_dumpbackups are NOT deletable by us. They land in an S3 bucket under Object Lock in COMPLIANCE mode with a 7-year retention and no expiration rule (infra/modules/storage-backups/main.tf) — neither an administrator nor AWS can delete an object inside that window. This is a deliberate ransomware and insider-deletion control, and it is the reason the erasure position in §Erasure and the backup tier is what it is. - Sub-sub-processors: none beyond AWS itself for the services we use; AWS contracts directly for the entire stack.
- AWS BAA accepted: to be confirmed in AWS Artifact pre-launch. BAA is HIPAA-oriented (US framing) but is the closest equivalent to "AWS as designated processor for special-category health data" — we accept it as part of the production-launch checklist.
4. Cloudflare
- What we use it for:
- DNS for
restartix.proand tenant custom-hostname routing via Cloudflare for SaaS. - WAF + DDoS on the ingress path before ALB.
- CDN for public static assets (marketing site, public icons, public exercise demo previews).
- Cache — public-cacheable assets only. Authenticated request paths are pass-through with
Cache-Control: private.
- DNS for
- Data categories transferred: request metadata (IP, user-agent, URL, headers, TLS metadata) flows through Cloudflare for every request. Cloudflare terminates TLS and re-establishes TLS to our origin; this is a structural property of using a CDN at the edge.
- Data NOT transferred for caching: request bodies, response bodies, and headers of authenticated requests are not cached; they pass through. Cookies marked
Secure; HttpOnly(including the Clerk session cookie) are not retained by Cloudflare beyond request servicing. - Hosting location: Cloudflare runs a global edge network. Requests from Romania typically terminate at EU PoPs (Bucharest, Sofia, Frankfurt, Vienna). Routing decisions are operational, not contractual.
- Transfer mechanism: SCCs (Module 2) for Cloudflare's US parent + TIA addressing edge-routing and US-legal-process scenarios. See TIA. Cloudflare's Data Localization Suite (EU-only routing) is a consideration — pricing and applicability under evaluation; if adopted, the TIA section updates.
- Retention: edge-cache TTLs governed by
Cache-Controlheaders we set. Cloudflare's access logs retained per their terms (typically ≤ 30 days at our plan tier). - WAF posture: the open question of "Cloudflare WAF-for-SaaS add-on vs. AWS WAF on ALB" is in June launch plan, open decisions. Either way Cloudflare remains in scope as DNS + CDN; the WAF choice affects only the WAF inspection point.
5. Sentry
- What we use it for: application error tracking. ⚠️ Deployed on the Patient Portal only. The API, Clinic, Console, telemetry and media services are not wired to it.
- Data categories transferred: stack traces, error messages, request URLs and navigation breadcrumbs (scrubbed — see below), release SHA, environment. No user identifier is sent at all, pseudonymous or otherwise.
- PII redaction: the SDK runs with
sendDefaultPii: false, which stops it attaching IP addresses, cookies, headers, request bodies and user identifiers in the first place. AbeforeSendhook then closes the residual leak that setting does not cover — secrets carried in URLs (sign-in tickets, the legacy-handoff token, authentication handshake parameters), which would otherwise surface in the request URL and in navigation and fetch breadcrumbs. Any stray PII found in error content is treated as a code bug and fixed at source. - Hosting location: Sentry's EU region (Frankfurt). Selected at org-creation time and immutable.
- Transfer mechanism: EU-only data residency. Sentry's US parent has documented data-isolation between regions; we rely on that contract.
- Retention: event retention per our plan tier (typically 90 days for event details, longer for issue aggregates). Configurable down to 30 days for higher sensitivity if counsel recommends.
Not yet engaged — FGO
Not engaged. Retained here as the intended shape of the entry, to be moved into the table above when the F12 billing engine ships the implementation. Nothing is transferred today.
- What it would be used for: Romanian e-invoicing — RO VAT calculation, e-Factura submission to ANAF. Defaults for clinics on the platform that issue invoices in Romanian jurisdiction. (At launch — RestartiX-the-clinic does not bill patients because the launch program is free; FGO is still in scope because RestartiX-the-platform may issue invoices to itself or to early third-party clinics on a paid tier.)
- Data categories transferred: legal-entity invoice data — clinic name, CNP/CIF, address, invoice line items, totals, tax. No patient health data flows to FGO; invoice line items reference subscription products at the platform level, not patient-level clinical events.
- Hosting location: Romania.
- Transfer mechanism: EU-EU; no Art. 44 transfer concerns.
- Retention: governed by Romanian fiscal record-keeping rules (10 years per Codul Fiscal Art. 78). FGO retains for at least this period.
- Special status: FGO submission to ANAF is statutorily required, not optional. The lawful basis for the transfer to FGO + ANAF is GDPR Art. 6(1)(c) (legal obligation), not consent.
6. Daily, Co.
- What we use it for: live video consultations between a patient and a clinician (F5.5). The platform creates a private room per consultation, mints a short-lived per-participant join token, and receives room-lifecycle webhooks. The vendor-specific surface is confined to a single adapter and the underlying schema is provider-agnostic, so the sub-processor is replaceable without a data-model change.
- Data categories transferred:
- Live audio and video of a rehabilitation consultation. This is Art. 9 special-category health data — a patient discussing and demonstrating their condition. It is the only sub-processor that receives Art. 9 data in the clear, and it is why this entry carries the heaviest safeguards.
- In-call display name (
user_name) — a given name or the clinician's name, chosen by the platform. - An opaque participant reference (
user_id) that the platform derives; it is what comes back on every webhook and is what makes attribution possible without telling the provider who the participant is. - Room reference, participant cap, token expiry, and connection metadata (IP, device, network quality) inherent to a WebRTC session.
- Data NOT transferred: patient identifier,
patient_profile_id, CNP, email, phone, DOB, clinical record, appointment content, form answers, adherence data. - Hosting location: media servers are pinned to the EU. The room's
geoproperty is set from platform config (eu-central-1, Frankfurt) and the provider adapter refuses to create a room whengeois unset rather than defaulting — a room created without a region is a room whose media may land anywhere. The control plane (api.daily.co— room creation, token minting, webhook delivery) and the account itself are in the United States. - Transfer mechanism: 2021 SCCs, Module 3 (processor-to-sub-processor) — the module that fits our position exactly, since the clinic is the controller and we are its processor. The DPA needs no separate signature. Daily's Terms of Service §4 incorporates it by reference, and the DPA itself provides that "by entering into the Agreement, Data Exporter is deemed to have signed these Standard Contractual Clauses incorporated herein, as of the Effective Date of the Agreement". Accepting the Terms when the account was created therefore brought both the Art. 28 contract and the Art. 46 transfer tool into force. DPA §6.2 selects the module from the parties' actual roles: Module 2 where the customer is a controller, Module 3 where the customer is itself a processor — which is us. See TIA T4.
- Recording: rooms are created without recording enabled and the platform never calls a recording API, so no consultation media is stored at the provider. The
video_recordingconsent instrument exists but is not published, and no code path turns recording on. See the open item below on making this explicit rather than inherited from the account default. - Retention: no consultation media is stored by us or by the provider. Room and token records expire (
eject_at_room_expis true, so expiry ends a call in progress rather than merely refusing new joins). Provider-side connection logs are retained per Daily's terms. - Sub-sub-processors: Daily publishes its own list at daily.co/legal/sub-processors — AWS and Oracle for hosting, Cloudflare and Twilio for network traversal, plus Sentry, BigQuery, Stripe and WorkOS. Two entries there need reading rather than skimming: Deepgram (transcription) and OpenAI (LLM chat completions) are listed under the WebRTC product. They belong to Daily's AI features, which we do not enable and which cannot engage on a room that is never recorded and never routed to a transcription pipeline — but a controller reviewing that page will see them and will ask. The answer is that our integration calls room creation, token minting and webhook receipt, and nothing else.
- Why this provider: evaluated against Whereby and a self-hosted LiveKit deployment; the schema supports both
dailyandwherebyso the choice is reversible. Daily's EUgeopinning and per-participant token model were the deciding factors.
Open items before a third-party clinic is onboarded
The contract is in force, so these are narrower than they first looked — but they are real:
The account is shared with the legacy system, and this is not abstract. Consultations run through the same Daily account as
restartix-leo. That account held 13,228 meetings when it was last inspected (2026-08-09), almost all of them leo's, with real patient names visible as in-call display names.The consequence that matters here is that provider webhooks are account-wide: our endpoint receives delivery for leo's live consultations, carrying those names. Nothing is stored — the handler discards any room this platform did not derive, before the event is even constructed — but receiving is processing, and the filter doing that work was written to ignore "rooms the same account might host", a hypothetical at the time. It is now the only thing between another system's patient data and our
payloadcolumn, and it is load-bearing by accident.This is an Art. 32 segregation problem, and it also leaves the DPA in force attached to whichever legal entity accepted the Terms on that account — worth confirming rather than assuming, even though the same company stands behind both systems. Moving to a platform-owned account resolves all of it, needs no code change, and should not wait for the first clinic.
Sub-processor notice is owed to every controller before a third-party clinic is onboarded with video consultations. Only RestartiX-the-clinic is on the platform today, so nothing is outstanding to an external party yet.
Recording-off is inherited, not asserted. The room adapter declares an
enable_recordingproperty but never sets it, so "off" comes from the provider's default rather than from our request. It should be sent explicitly, so the control is ours and is visible in the request we make.
Erasure and the backup tier
A sub-processor list that promises deletion has to say what "deleted" means against a backup tier that cannot be edited.
When a patient exercises Art. 17, the platform anonymises the live record (Art. 17(3)(c) applies to medical records — see GDPR mechanics) and the change propagates to every runtime system and to every sub-processor above within the notice period. It does not reach back into the Layer-2 pg_dump archive, which is Object-Locked in COMPLIANCE mode for 7 years and is technically immutable for that period.
This is the standard EDPB position on backups — restoring a backup is itself processing, and the erasure is re-applied on restore rather than performed inside the archive. The commitments that follow from it:
- Backups are not used for any purpose other than disaster recovery. There is no analytical, operational, or support read path into them.
- A restore is an incident-response event, logged, and followed by re-application of every erasure and anonymisation recorded since the dump was taken, before the restored system serves traffic.
- The archive expires on its own schedule; nothing extends it.
The erasure confirmation we give a controller therefore covers the live systems and the sub-processors, and states the backup position explicitly rather than implying the data is gone everywhere.
Change log
| Date | Change | Notice given |
|---|---|---|
| 2026-05-15 | Initial v1 list drafted | n/a (pre-launch) |
| 2026-09-04 | Daily, Co. added as a sub-processor for live video consultations, with the corresponding TIA T4. | ⚠️ Owed. 30 days' notice to every controller. Only RestartiX-the-clinic is on the platform today, so no external notice is outstanding — but this is the entry that must go out before a third-party clinic is onboarded |
| 2026-09-04 | FGO moved out of the active table. It was listed as sub-processor #6; the invoicing capability is interface-only and its implementation ships with F12, which is out of scope, so no data reaches it. Daily renumbered 7 → 6. | n/a (removal — no new recipient) |
| 2026-09-04 | Sentry entry corrected: deployed on the Portal only, not across all services, and it sends no user identifier (sendDefaultPii: false) rather than a hashed one. AWS cross-region replication removed — it is not configured in any environment. | n/a (correction) |
| 2026-09-04 | AWS retention corrected: the Layer-2 pg_dump archive is Object-Locked (COMPLIANCE, 7 years, no expiration), not lifecycle-managed to Deep Archive. New §Erasure and the backup tier. | n/a (correction, no new recipient) |
Appendix: data-categories key
| Category | Examples |
|---|---|
| Account identifiers | email, name, phone, DOB, locale |
| Authentication metadata | last login, IP, user-agent, session expiry, OAuth tokens |
| Health data (Art. 9) | VAS pain, RPE, adherence (session completion, exercise drop-off), free-text patient comments to specialists |
| National ID (Romania) | CNP — when collected; encrypted at column level (pii_regulated) |
| Financial / fiscal | invoice line items, VAT, CIF |
| Operational telemetry | request logs, error stack traces, application metrics |
| Video assets | exercise demonstration videos (no patient-recorded content at launch) |