Wie wir Schweizer Daten technisch schützen.
Diese Seite ist die öffentliche Zusammenfassung unseres internen Sicherheitsdokuments. Sie beschreibt jede Schicht im Detail — vom Browser des Ausfüllenden bis zum verschlüsselten Backup in Zürich. Keine Marketingformeln, kein Wischiwaschi: echte Architektur-Entscheidungen, dokumentierte Restrisiken, prüffähig.
Zehn Abschnitte. Keine Marketing-Lücken zwischen den Diagrammen.
Jede Aussage auf dieser Seite ist im internen Dokument hinterlegt — mit Abschnittsnummer, betroffener Code-Datei und letztem Audit-Datum.
- 01GrundprinzipienVier Entscheidungen, die alles andere bestimmen.
- 02DatenflussBrowser → TLS → Server → Dashboard.
- 03Schutz-SchichtenDefense in Depth, fünf Lagen.
- 04VerschlüsselungALE versus E2EE, Algorithmen und Schlüsselverwaltung.
- 05Zugriff und MandantenAuth, RLS, Service-Role-Boundary.
- 06StandortExoscale Zürich, eu-central-2.
- 07SubunternehmerVier Vendoren. Zweck. Datenfluss.
- 08BetriebPatches, Backups, Monitoring, RTO/RPO.
- 09Bekannte RestrisikenTransparenz über das, was technisch nicht eliminierbar ist.
- 10DokumenteAVV, ToMs, E2EE-Spec, DSFA.
Vier Entscheidungen, die alles andere bestimmen.
Eine Sicherheitsarchitektur ist die Summe ihrer Voreinstellungen. Unsere vier Default-Entscheidungen — und wie wir sie technisch erzwingen.
Daten verlassen die Schweiz nicht
Alle VMs, Backups und das Object-Storage liegen in Exoscale Zürich (eu-central-2). Keine Replikation, kein CDN-Spiegel ausserhalb der CH.
Server kennt den Inhalt nicht (wenn E2EE aktiv)
Im Pro-Plan werden Antworten bereits im Browser des Ausfüllenden mit ECIES + AES-256-GCM verschlüsselt. Private Schlüssel verlassen den Browser nie.
Mandantentrennung auf DB-Ebene
Row-Level Security in PostgreSQL ist auf jeder Tabelle aktiv — auch wir können nicht versehentlich Mandanten mischen, selbst via direktem SQL nicht.
Restrisiken werden dokumentiert
Was nicht eliminiert werden kann, wird benannt — in known-security-risks.md, mit Bewertung und Kompensationsmassnahme.
Vom Klick auf „Absenden" bis ins Dashboard.
Der Pfad jeder Antwort, mit Verschlüsselungs-Schritt, Zwischenhalt und Speicherort. Bei E2EE-Formularen passiert der Klartext-Schritt ausschliesslich im Browser des Ausfüllenden und im Browser des Admins — nie auf unserem Server.
Antworten werden lokal mit ECIES (P-256) + AES-256-GCM verschlüsselt. Private Key verbleibt nie auf dem Gerät.
Nginx mit Nonce-CSP und ALTCHA-Bot-Check. Keine eigene Logik auf Antwortinhalten.
Speichert ausschliesslich Ciphertext und gewrappte Schlüssel. Bei Nicht-E2EE: zusätzlich ALE mit ENCRYPTION_KEY auf Server-Ebene.
PostgreSQL mit Row-Level Security auf jeder Tabelle. Mandantenübergreifende Reads sind technisch ausgeschlossen.
Tägliche Snapshots, AES-256 verschlüsselt, Aufbewahrung 30 Tage, dann automatische und unwiderrufliche Löschung.
Entschlüsselung lokal im Admin-Browser. Auto-Lock nach 30 Minuten ohne Aktivität.
Fünf Schichten. Jede für sich allein wirksam.
Defense in Depth heisst nicht „eine Wand pro Risiko". Es heisst: selbst wenn eine Schicht versagt, schützen die übrigen vier. Wir konstruieren die App so, als wären die anderen Schichten bereits kompromittiert.
Weiter zur VerschlüsselungNetzwerk
TLS 1.2/1.3 erzwungen, HSTS preload, Nginx-Reverse-Proxy, keine HTTP-Fallbacks.
Anwendung
Nonce-basierte CSP mit strict-dynamic, script-src-attr 'none', Zod-Validierung auf jedem API-Endpoint, HMAC-signierte Webhooks.
Verschlüsselung
Application-Level Encryption (AES-256-GCM) für jede Submission. E2EE auf Wunsch — Server kennt den Inhalt nie.
Datenbank
Row-Level Security auf jeder Tabelle. Service-Role-Key nur serverseitig, nie im Browser. Direkter SQL-Zugriff nur via SSH-Tunnel.
Infrastruktur
Exoscale Zürich, ISO 27001/27017/27018. Docker non-root (UID 1001). SSH nur mit Ed25519-Key + Passphrase, kein Passwort-Login.
Zwei Schichten. Eine immer aktiv. Die zweite optional auf Knopfdruck.
Application-Level Encryption (ALE) ist auf jedem Formular aktiv — keine Konfiguration, kein Plan-Upgrade nötig. Wer Antworten zusätzlich vor uns selbst verbergen will, aktiviert Ende-zu-Ende-Verschlüsselung (E2EE). Der entscheidende Unterschied: wer den Schlüssel besitzt.
Nichts ist „nur Application-Logik".
Jede Autorisierungsentscheidung ist doppelt verankert — einmal in der API-Route, einmal in der Datenbank selbst. Ein Bug in einer Schicht kompromittiert nicht die andere.
Authentifizierung der Formsly-Nutzer
- E-Mail + Passwort über Supabase Auth, bcrypt mit Salt pro User
- TOTP-2FA optional — für E2EE technisch erzwungen
- Keine geteilten Accounts; jeder Zugriff ist einem User zuordenbar
- Edit-Token für Einreichungen: SHA-256-Hash in DB, Klartext nur im E-Mail-Link
Row-Level Security (RLS) auf jeder Tabelle
profiles,forms,submissions,webhooks,form_key_shares,consent_audit,e2e_access_log— alle mit RLS-Policies- Authentifizierter User sieht ausschliesslich eigene Zeilen — auch via direktem SQL
- Mandantenübergreifende Reads sind auf DB-Ebene technisch ausgeschlossen
- Service-Role-Key umgeht RLS — wird ausschliesslich serverseitig in API-Routes verwendet, nie im Browser
Authentifizierung der Infrastruktur
- SSH ausschliesslich mit Ed25519-Key + Passphrase, kein Passwort-Login
- Key auf verschlüsseltem USB-Stick — nicht in Cloud-Diensten
- GitHub, Google, Infomaniak, Stripe: 2FA mit YubiKey (Primary + Backup)
- Supabase-Dashboard nicht öffentlich exponiert — nur via SSH-Tunnel erreichbar
Ein Datacenter. Eine Region. Eine Rechtsordnung.
Wir betreiben Formsly auf dedizierten virtuellen Maschinen bei Exoscale im Rechenzentrum Zürich. Region eu-central-2. ISO 27001, 27017 und 27018 zertifiziert. Es gibt keine sekundäre Region, kein CDN-Edge ausserhalb der Schweiz, keine asynchrone Replikation in andere Rechtsordnungen — bewusste Architektur-Entscheidung.
Vier Subunternehmer. Drei in der Schweiz.
Stripe ist die einzige Abhängigkeit ausserhalb der Schweiz — und sieht ausschliesslich Abrechnungsdaten, nie Formular-Antworten. Neue Subunternehmer durchlaufen Datenschutz- und Sicherheitsprüfung und werden in anbieter-und-transfers.md dokumentiert, bevor sie produktiv gehen.
Sicherheit ist ein Lebenszyklus, kein Launch-Event.
Patches, Backups, Monitoring und Incident Response sind im Tages- und Wochenrhythmus verankert. Jede Zahl unten ist im internen Dokument einer Person und einem Prozess zugeordnet.
Patch-Management
Sicherheits-Updates innerhalb von 7 Tagen nach Bekanntwerden via pnpm audit und Watchlist.
Deployment
Kein Direkt-Push auf main. GitHub Actions baut den Container nach jedem PR-Merge.
Monitoring
Uptime Robot prüft formsly.ch und admin.formsly.ch alle 5 Minuten. E-Mail-Alert bei Ausfall.
Backups
Tägliche Snapshots, AES-256 verschlüsselt, in Exoscale Object Storage Zürich. Danach automatische Löschung.
Wiederherstellung
Recovery-Tests jährlich oder nach Architekturwechseln. Letzter Test: 23. März 2026 — erfolgreich.
Incident Response
Meldung an EDÖB nach Art. 24 nDSG, an Betroffene nach Art. 24 Abs. 2 — Plan in incident-response-plan.md.
Was nicht eliminierbar ist, wird benannt.
Jedes ausgereifte System hat Restrisiken. Wir dokumentieren sie öffentlich, mit Bewertung und Kompensationsmassnahme — die vollständige Liste liegt in known-security-risks.md im Repository.
Zur Dokumenten-Übersicht01Metadaten von Submissions liegen unverschlüsselt in der DB
Felder wie submitted_at, completion_time_seconds, variant_id, consent_given und utm_params werden im Klartext gespeichert. Bewusste Designentscheidung: Diese Felder enthalten für sich genommen keine Identifikatoren — ein Angreifer mit reinem DB-Zugriff sieht Zeitstempel und Zahlen, aber nicht wer was eingereicht hat. Verschlüsselung dieser Felder würde Dashboards, Löschfristen und Analysen verunmöglichen, ohne wesentlichen Sicherheitsgewinn.
02At-Rest-Verschlüsselung auf Infrastruktur-Ebene nicht garantiert
Exoscale verschlüsselt VM-Disks und Block Storage nicht automatisch. Kompensationsmassnahme: alle personenbezogenen Daten werden auf Applikationsebene mit AES-256-GCM verschlüsselt (ALE), bevor sie die Datenbank erreichen. Bei E2EE-Formularen zusätzlich vorher im Browser.
03Stripe als US-Subunternehmer im Bezahlflow
Stripe sieht ausschliesslich Abrechnungsdaten zahlender Kunden — niemals Formularantworten oder Daten von Endnutzern. Übertragung auf Basis von Standardvertragsklauseln (SCCs); DPA via Stripe. Dokumentiert in anbieter-und-transfers.md.
04Browser-Kompromittierung kompromittiert E2EE
E2EE schützt vor Server-Kompromittierung, nicht vor einem kompromittierten Endgerät. Wenn der Browser des Admins infiziert ist, kann der lokal entschlüsselte Klartext extrahiert werden. Kompensation: Auto-Lock nach 30 Minuten, 2FA technisch erzwungen, CSP mit nonce-basiertem strict-dynamic.
05Wer den ENCRYPTION_KEY besitzt, kann alle ALE-Antworten entschlüsseln
ALE schützt vor reinem DB-Zugriff (z. B. Backup-Diebstahl), nicht vor einem kompromittierten Server. Daher die Option auf E2EE für vertrauliche Daten — dort wird der Klartext auf dem Server nie sichtbar, selbst nicht für uns.
Sechs Dokumente. Auf Anfrage. Heute.
Für Datenschutzbeauftragte, Audits und Beschaffungsprozesse. Der AVV ist bereits bei der Registrierung in Ihrem Konto enthalten — kein separater Antrag nötig. Die übrigen Dokumente erhalten Sie auf Anfrage, unterzeichnet via NDA innerhalb von 1 Werktag.
AVV / DPA-Vorlage
Vorlage zur Auftragsverarbeitung gemäss Art. 9 nDSG.
ToMs · Technische und organisatorische Massnahmen
Strukturierter Nachweis nach EDÖB-Leitfaden.
E2EE-Spezifikation
Vollständige technische Spezifikation der Ende-zu-Ende-Verschlüsselung.
DSFA · Datenschutz-Folgenabschätzung
Folgenabschätzung für Verarbeitung sensitiver Daten.
Bekannte Restrisiken
Liste dokumentierter, bewerteter Restrisiken.
Incident-Response-Plan
Meldepflichten, Eskalation, Kommunikation.
Eine Frage, eine Meldung, ein Audit-Termin?
Responsible-Disclosure-Meldungen und Audit-Anfragen gehen direkt an die Person, die diese Seite verantwortet — nicht an einen Bot. Antwort üblicherweise innert 24 Stunden, an Werktagen schneller.
PGP-Fingerprint auf Anfrage