Status
Accepted — ticket 02.
Context
Wundklare processes patient data under the German MDR and DSGVO. Section §1.6
pins the Neon Postgres region to aws-eu-central-1 and the R2 bucket
wundklare-storage to the eu jurisdiction (.eu.r2.cloudflarestorage.com).
The Worker runtime does not have a residency guarantee by default: a Worker
runs on the nearest healthy colo, and placement.region = aws:eu-central-1
is a latency hint, not a residency control.
Decision
- Data at rest lives in the EU. Neon is pinned to
aws-eu-central-1; the R2 bucket is created in theeujurisdiction with the endpoint<account>.eu.r2.cloudflarestorage.com. Backups and snapshots stay in the same region. - The Worker gets
placement = { region: "aws:eu-central-1" }as a latency hint so most invocations stay near the origin. We do not claim this as a residency control. - The honest trust boundary is client-side envelope encryption (ADR-0017): objects and sensitive columns are AES-GCM ciphertext before they leave the device, so Cloudflare's edge TLS termination and any non-EU Worker invocation only ever see ciphertext for clinical bytes. Share links are the one zero-knowledge path (ADR-0018). Server-side decryption only runs in logged system jobs (ARD ADR-06).
- A DPIA follow-up (owned by the service, not this ticket) names Cloudflare and Neon as EU-resident sub-processors and documents the edge TLS decryption as a residual exposure limited to ciphertext.
Operator check (TBD)
Confirm the R2 bucket is in the EU jurisdiction before the first production deploy:
wrangler r2 bucket info wundklare-storageThe output must include an eu jurisdiction and an endpoint ending in
.eu.r2.cloudflarestorage.com. If it does not, re-create the bucket with
wrangler r2 bucket create wundklare-storage --jurisdiction eu; buckets
cannot be moved after creation.
Consequences
- Choosing
eufor R2 means the bucket cannot be accessed from the global endpoint; every S3-compatible client (including local MinIO fallbacks) reads the jurisdiction-scoped endpoint fromSTORAGE_ENDPOINT. - Worker placement is best-effort: observability may show invocations outside the EU for brief periods (fleet health). Because every clinical byte is ciphertext at rest and in transit, this stays within the DPIA.
- A later move to a KMS (TBD) replaces the Worker-held
WUNDKLAR_KEKwith a service that enforces regional key access and audit logs; ADR-0017 is the migration surface.