Zum Inhalt springen
Docs

Befehlspalette

Zu einer Seite oder Ansicht springen oder ein Todo per Name finden.

Änderungen

ADR-0016: EU data residency on Cloudflare and Neon

The repository's architectural decision, rationale and consequences.

Markdown

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 the eu jurisdiction 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-storage

The 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 eu for R2 means the bucket cannot be accessed from the global endpoint; every S3-compatible client (including local MinIO fallbacks) reads the jurisdiction-scoped endpoint from STORAGE_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_KEK with a service that enforces regional key access and audit logs; ADR-0017 is the migration surface.
Auf GitHub bearbeitenDie Dokumentation ist auf Englisch.