Anlage 2: Technische und organisatorische Maßnahmen
Stand: 17. August 2026
Diese Anlage ist Bestandteil des Auftragsverarbeitungsvertrags zwischen dem Kunden und der Unbogify GmbH, Zelterstr. 10, 10439 Berlin, die den Dienst unter dem Namen Steerd betreibt. Ziffer 4 jenes Vertrags bezieht sie ein.
Sie ist als Beschreibung dessen geschrieben, was das System tut, nicht als Zusicherung dessen, was es erreicht, und wo eine Maßnahme fehlt, steht das hier. Der Abschnitt Bekannte Lücken am Ende gehört zur Anlage und ist kein Anhang zu ihr: Der Kunde hat ein Recht darauf zu erfahren, was nicht vorhanden ist, und eine Behauptung, die ein Sicherheitsfragebogen aufdeckt, ist weniger wert als ein Eingeständnis, das er nicht aufdecken müsste.
Zu den Dateinamen in dieser Anlage. Viele der unten beschriebenen Maßnahmen nennen die Datei im Code des Auftragsverarbeiters, die sie umsetzt. Diese Namen sind kein Bestandteil dieser Anlage und begründen keine Pflicht; sie sind Belegstellen. Sie stehen hier, weil eine konkrete Aussage mehr wert ist als eine allgemeine, und weil sie es dem Auftragsverarbeiter erlauben, seine eigenen Aussagen zu überprüfen, wenn sich der Code ändert. Ein Kunde, der das Prüfrecht aus Ziffer 10 des Vertrags ausübt, kann sich jede davon nachweisen lassen. Sie sind bewusst keine Verweise: Das Repository ist nicht öffentlich, und ein Link, den der Leser nicht öffnen kann, gehört nicht in einen Vertrag.
- Verantwortlicher: der Kunde, also der Freelancer oder das Unternehmen, das Steerd nutzt
- Auftragsverarbeiter: Unbogify GmbH, Zelterstr. 10, 10439 Berlin
- Dienst: Steerd, eine All-in-one-Plattform für Freelancer und kleine Unternehmen: Kontakte und
Vertriebspipeline, Lebensläufe, Zeiterfassung, Reisekosten, Dokumente sowie Rechnungsstellung einschließlich E-Rechnung. Die Pflege von Kundenbeziehungen ist ein Modul davon und nicht das ganze Produkt. Die Leistungsbeschreibung bestimmt den Umfang der Verarbeitung, deshalb nennt sie die ganze Liste und nicht den Teil, mit dem das Produkt angefangen hat.
1. Pseudonymisierung und Verschlüsselung (Art. 32 Abs. 1 lit. a DSGVO)
Verschlüsselung bei der Übertragung. Der gesamte Verkehr läuft über HTTPS. TLS endet am Reverse-Proxy vor der Anwendung; Zertifikate werden automatisch ausgestellt und erneuert. Postfachverbindungen setzen TLS zwingend voraus (apps/api/src/lib/email/sources/imap.ts).
Verschlüsselung im ruhenden Zustand, geheimes Material. AES-256-GCM mit einem zufälligen 96-Bit-IV je Vorgang; das Authentifizierungs-Tag wird daneben gespeichert (apps/api/src/lib/crypto/aead.ts). Die Schlüssel sind Datenschlüssel je Team, die ihrerseits von einem Hauptschlüssel umschlossen werden (apps/api/src/lib/crypto/team-keys.ts, apps/api/src/lib/crypto/master-key.ts). Dadurch lassen sich die verschlüsselten Daten eines Kunden unwiederbringlich machen, ohne die eines anderen zu berühren. So verschlüsselt werden:
- IMAP-Passwörter und Postfacheinstellungen, versiegelt als ein Blob (mailbox_credentials)
- Gmail-Token und andere OAuth-Token (mailbox_credentials, integration_credentials). Die Tabelle
account der Authentifizierungsbibliothek hat standardmäßig Klartextspalten für Token; ein Schreib-Hook setzt alle fünf bei jedem Schreibvorgang auf null, sodass dort überhaupt kein OAuth-Token gespeichert wird (apps/api/src/lib/auth-account-tokens.ts)
- Dokumente, Anhänge zu Datensätzen, Reisebelege und finalisierte Rechnungs-PDFs, verschlüsselt,
bevor sie den Objektspeicher erreichen (apps/api/src/routes/files.ts, routes/attachments.ts, services/trip-receipts.ts, services/invoice-finalize.ts)
Schlägt eine Entschlüsselung fehl, etwa wegen eines falschen Schlüssels oder manipulierten Geheimtextes, so wird ein Fehler ausgelöst; unvollständige Daten werden nicht zurückgegeben.
Vier Einzelheiten, nach denen ein Sicherheitsfragebogen ausdrücklich fragt:
- Das Verfahren nimmt und liefert Bytes, sodass eine 25 MB große Datei nie zu einer Zeichenkette
aufgebläht wird.
- Das vollständige 128-Bit-GCM-Tag ist erforderlich: Ein gekürztes Tag wird abgelehnt und nicht
stillschweigend gegen weniger Bits geprüft.
- Der umschlossene Schlüssel bindet **sowohl die Generation des Hauptschlüssels als auch die ID des
besitzenden Teams als zusätzliche authentifizierte Daten**, sodass er weder unter einer anderen Generation des Hauptschlüssels noch im Datensatz eines anderen Teams wiedereingespielt werden kann (master-key.ts).
- Beim Wechsel des Hauptschlüssels werden **die Teamschlüssel neu umschlossen, ohne einen einzigen
Blob neu zu verschlüsseln** (apps/api/src/jobs/rotate-kek.ts, rotate-team-dek.ts). Hauptschlüssel werden je Umgebung vergeben; Staging und Produktivbetrieb teilen sich nie einen.
Was "verschlüsselt im ruhenden Zustand" nicht abdeckt, ausdrücklich gesagt. Gewöhnliche Datensätze in Postgres, also Kontakte, Projekte, Rechnungen und Zeiteinträge, liegen in einfachen Spalten und sind durch Zugriffskontrolle geschützt, nicht durch Verschlüsselung auf Anwendungsebene. Ob die zugrunde liegenden Datenträger und die Objektspeicher-Buckets bei Hetzner eine anbieterseitige Verschlüsselung im ruhenden Zustand tragen, ist in diesem Repository nicht belegt, und genau so steht es hier, statt "verschlüsselt im ruhenden Zustand" mehr bedeuten zu lassen, als es abdeckt. Der Bucket für die Sicherungen ist eine eigene Frage und ist bestätigt serverseitig mit AES-256 verschlüsselt (Abschnitt 4).
Es deckt auch nicht jedes Objekt im Objektspeicher ab, und das wird leicht falsch gelesen. Die Verschlüsselung auf Anwendungsebene gilt für die oben genannten Blob-Namensräume. Sie gilt nicht für den Namensraum uploads, dessen Objekte bewusst im Klartext geschrieben und gespeichert werden (apps/api/src/routes/uploads.ts, services/contacts-vcard.ts). Die fünf Zwecke, die er trägt, sind Kontoavatare, Kontaktavatare, Mitarbeiteravatare, Lebenslauffotos und Rechnungslogos (apps/api/src/lib/uploads-purposes.ts); er enthält damit Fotografien der betroffenen Personen des Kunden. Auch erzeugte Exportarchive liegen im Klartext (apps/api/src/lib/files/export.ts), was der Grund für den Hinweis in Abschnitt 6 ist, dass sie Daten betroffener Personen enthalten, und für die 30-Tage-Frist über ihnen. Zwischengespeicherte Website-Symbole liegen unter einem eigenen Präfix favicons/, ebenfalls im Klartext, und sind keine personenbezogenen Daten. All das ist durch Zugriffskontrolle geschützt und unterliegt derselben fehlenden anbieterseitigen Zusicherung wie die Postgres-Datensätze oben; deshalb steht es hier und nicht in einer Fußnote. Festgehalten als Bekannte Lücken, Nummer 13.
Hashing. API-Schlüssel und CardDAV-Anwendungspasswörter werden ausschließlich als SHA-256-Hashes gespeichert und in konstanter Zeit verglichen; der Klartext wird einmal bei der Erstellung angezeigt und ist danach nicht wiederherstellbar (apps/api/src/db/schema/api-keys.ts). Kontopasswörter werden von der Authentifizierungsbibliothek gehasht.
Geheimnisse werden nie protokolliert. Verschlüsselungsschlüssel werden erst bei Bedarf gelesen und aus der Protokollausgabe ausgenommen.
2. Vertraulichkeit (Art. 32 Abs. 1 lit. b DSGVO)
Mandantentrennung. Jede Anwendungstabelle mit Kundendaten ist über team_id einem Team zugeordnet, und jede Abfrage filtert auf das Team des Aufrufers. Lesezugriffe über Mandantengrenzen hinweg sind zusätzlich durch validateFKRefs abgesichert, das vor jedem Schreibvorgang erneut prüft, ob ein referenzierter Datensatz zum Team des Aufrufers gehört.
Zugriffskontrolle. Rollenbasierte Berechtigungen je Teammitglied, mit einer ausdrücklichen Positivliste vergebbarer Berechtigungen (apps/api/src/db/schema/rbac.ts). Administrative Ansichten wie das Audit-Protokoll sind Team-Administratoren vorbehalten; Mitglieder erhalten 403.
Authentifizierung. Sitzungs-Cookies für die Anwendung, dazu API-Schlüssel mit begrenztem Umfang für den programmatischen Zugriff. Ratenbegrenzungen gelten je IP-Adresse, je Schlüssel und für fehlgeschlagene Authentifizierungen.
Schutz vor Server-Side Request Forgery. Vom Nutzer angegebene Postfach-Hosts werden über DNS aufgelöst und abgelehnt, wenn sie auf private, Loopback-, Link-Local- oder CGNAT-Bereiche zeigen, einschließlich der Metadatenadresse der Cloud. Die Verbindung wird anschließend an die geprüfte IP-Adresse gebunden, sodass eine zweite DNS-Antwort sie nicht umlenken kann (apps/api/src/lib/net/net-guard.ts).
Fremde Ressourcen werden selbst ausgeliefert. Schriftarten und Länderflaggen kommen vom eigenen Ursprung, sodass das Laden der Anwendung keine Anfrage an ein fremdes CDN auslöst.
Trennung der Umgebungen. Staging und Produktivbetrieb haben getrennte Datenbanken, getrennte Verschlüsselungsschlüssel und getrennte Objektspeicher-Buckets in getrennten Projekten beim Anbieter, sodass eine Zugangsberechtigung aus der einen Umgebung die Daten der anderen nicht erreicht.
Erreichbarkeit im Netz. Postgres und Valkey werden von der Steuerungsebene des Hostings verwaltet und haben keinen öffentlichen Port; die Firewall des Hosts weist eingehenden Verkehr grundsätzlich ab, mit dem Shell-Zugang als einziger Ausnahme.
Umgang mit Geheimnissen. Betriebsgeheimnisse liegen in einem selbst betriebenen Passwortspeicher und werden im Moment der Verwendung abgerufen, statt auf die Festplatte geschrieben zu werden. Es gibt bewusst keine Klartextgeheimnisse in Umgebungsdateien auf irgendeinem Rechner: Die Werkzeuge greifen über einen Hook auf den Speicher zu, und die Konfigurationsverwaltung holt sie zum Zeitpunkt der Ausbringung. Der Hauptschlüssel des Produktivbetriebs, der die Schlüssel aller Teams umschließt, ist dort hinterlegt und liegt nicht in der Datenbank. Das schneidet in beide Richtungen: Eine Wiederherstellung der Datenbank allein bringt ihn nicht zurück, weshalb eine entwendete Sicherung nicht genügt, um verschlüsselte Daten zu lesen; und ginge der Schlüssel verloren, wären diese Daten dauerhaft unlesbar.
Zugriff von Beschäftigten. Der eine Teil dieser Anlage, der Menschen beschreibt und nicht Code, und das Erste, wonach eine Sicherheitsprüfung eines Kunden fragt.
Administrativer Zugriff auf den Produktivbetrieb bedeutet zweierlei, das auf eines hinausläuft: Shell-Zugang zum Host und Anmeldung an der Steuerungsebene des Hostings. Die Steuerungsebene hält jede Umgebungsvariable des Produktivbetriebs und kann in den laufenden Containern Befehle ausführen; Zugang zur Steuerungsebene ist damit faktisch voller Datenbankzugriff. Es gibt keine engere "Anmeldung an der Produktivdatenbank", die sich beschreiben ließe, und eine solche zu beschreiben würde die Trennung überzeichnen.
Der Zugriff ist einzelnen Personen zurechenbar: Auf den Produktivsystemen liegt je Person ein benannter Schlüssel, daneben der Schlüssel, den die Steuerungsebene für sich selbst verwendet. Datenbank und Cache haben keinen öffentlichen Port, und die Firewall des Hosts weist eingehenden Verkehr grundsätzlich ab; die einzige Ausnahme ist der Shell-Zugang.
Drei Dinge zum Zugriff von Beschäftigten sind nicht vorhanden, und sie stehen hier, statt zu fehlen:
1. Eine Zugangsberechtigung auf einem Produktivsystem ist nicht zugeordnet. Ein dort vorhandener Schlüssel lässt sich keiner benannten Person zuordnen, und die Konfigurationsverwaltung gleicht diese Liste nicht ab, sodass allein das laufende System darüber Auskunft gibt. Der Schlüssel wurde nicht entfernt. 2. Eine Zwei-Faktor-Authentifizierung ist nicht bestätigt, weder für die Anmeldung an der Steuerungsebene noch für die Konsolen des Hosting- und des Cloud-Anbieters. Ob sie erzwungen wird, ist nirgends festgehalten; deshalb behauptet diese Anlage es nicht. 3. Verpflichtungen auf Vertraulichkeit nach Art. 28 Abs. 3 lit. b DSGVO bestehen für die Personen mit diesem Zugriff, aber der Nachweis, wer diese Personen sind, ergibt sich aus der Konfiguration des Zugriffs und wird nicht als eigenes Dokument geführt.
Die erste dieser drei Lücken ist diejenige, auf die eine Sicherheitsprüfung am meisten Wert legt, und sie steht deshalb hier, statt gefunden zu werden. Sie ist auch der Grund, warum Ziffer 10.6 des Vertrags von sich aus offenlegt, dass der Auftragsverarbeiter weder nach ISO 27001 noch nach SOC 2 zertifiziert ist: Eine förmliche Regelung der Zugriffsverwaltung ist genau das, was eine solche Zertifizierung verlangen würde, und eine solche gibt es noch nicht.
3. Integrität (Art. 32 Abs. 1 lit. b DSGVO)
Fortschreibendes Audit-Protokoll. Sicherheitsrelevante Vorgänge eines Teams, etwa der Lebenszyklus von API-Schlüsseln und Änderungen an Rollen, werden in audit_log geschrieben, und zwar in derselben Transaktion wie der Vorgang selbst. Schlägt der Protokolleintrag fehl, wird auch der Vorgang zurückgerollt; eine stille Lücke kann so nicht entstehen (apps/api/src/services/audit.ts).
Getrenntes Protokoll sicherheitsrelevanter Ereignisse. Kontobezogene Ereignisse wie Änderungen von Passwort und E-Mail-Adresse werden in auth_events festgehalten, bewusst getrennt vom Audit-Protokoll des Teams und dort nie sichtbar.
Integrität des Exports. Datenexporte enthalten eine manifest.json mit einem SHA-256 je Datei, und der Export lässt sich allein aus dem Archiv heraus vollständig nachprüfen (apps/api/src/lib/files/export.ts).
4. Verfügbarkeit und Belastbarkeit (Art. 32 Abs. 1 lit. b und c DSGVO)
Die Anwendungscontainer sind zustandslos und jederzeit neu startbar; Health-Endpunkte steuern den Verkehr, sodass ein Container, der nicht startet, keine Anfragen erhält. Der Objektspeicher enthält teils verschlüsselte Blobs und teils Objekte im Klartext; Abschnitt 1 sagt, welche davon welche sind.
Sicherungen der Datenbank. Die Produktivdatenbank wird nächtlich um 03:45 UTC gesichert, und die Sicherung wird in einen Objektspeicher hochgeladen, der bei einem anderen Anbieter liegt als die Datenbank selbst: Die Datenbank läuft bei Hetzner, die Sicherungen landen in Amazon S3 eu-central-1 (Frankfurt am Main). Beides liegt in Deutschland. Getrennt wird hier nach dem Anbieter und nicht nach der Rechtsordnung: Eine Sicherung beim selben Anbieter wie das Original überlebt den Ausfall dieses Anbieters nicht.
Eigenschaften des Sicherungsspeichers, alle in Infrastructure-as-Code festgelegt und nicht bloß vereinbart:
- Aufbewahrung 90 Tage, geregelt durch eine Lebenszyklusregel des Speichers und nicht durch das
Werkzeug, das die Sicherungen schreibt, sodass ein falsch konfigurierter Erzeuger die Frist nicht verkürzen kann.
- Verschlüsselt im ruhenden Zustand (AES-256, serverseitig).
- Nicht öffentlich erreichbar, und nur über TLS erreichbar.
- Versioniert, sodass ein Überschreiben die vorherige Kopie nicht vernichtet.
- Die Zugangsberechtigung, die Sicherungen schreibt, kann sie nicht löschen. Sie hat überhaupt
keine Löschberechtigung, geprüft am aktiven Schlüssel. Ein kompromittiertes Produktivsystem kann der Sicherungshistorie also etwas hinzufügen, sie aber nicht auslöschen.
Was das nicht leistet, ausdrücklich gesagt. Es handelt sich um nächtliche logische Sicherungen und nicht um fortlaufende Archivierung: Es gibt keine Point-in-Time-Recovery, der schlimmste Datenverlust bei einem Ausfall der Datenbank ist also die Zeit seit der letzten nächtlichen Sicherung. Sicherungen hochgeladener Dokumente und Anhänge sind eine bekannte Lücke, weil dieser Speicher zwar versioniert, aber nicht gesondert gesichert wird (Bekannte Lücken, Nummer 6).
Die Sicherungen sind als echte Artefakte überprüft, und die Wiederherstellung wurde am 10. August 2026 geprobt. Eine Sicherung gilt nicht deshalb als erledigt, weil der Auftrag Erfolg gemeldet hat: Für beide Umgebungen wurde eine gespeicherte Sicherung aus dem Sicherungsspeicher geholt und darauf geprüft, ob sie tatsächlich die Tabellen der Datenbank enthält und nicht bloß eine strukturell gültige leere Datei ist, was der Fehlerfall ist, der sonst unbemerkt bleibt. Darüber hinaus wurde die Produktivsicherung inzwischen vollständig wiederhergestellt, und zwar aus dem Artefakt im Sicherungsspeicher und nicht aus einer Kopie auf dem Server, den sie schützt: Die Zeilenzahlen stimmten mit dem Produktivbetrieb überein, die Anwendung startete gegen die wiederhergestellte Datenbank und beantwortete eine Anfrage, und der Weg über den Verschlüsselungsschlüssel war Teil desselben Tests, denn eine Wiederherstellung, die Datensätze zurückbringt, die niemand entschlüsseln kann, ist keine. Ein falscher Schlüssel wurde als Kontrolle versucht und scheiterte erwartungsgemäß. Was Art. 32 Abs. 1 lit. c DSGVO verlangt, steht damit nicht mehr nur auf dem Papier: Der an jenem Datum geprobte Weg wurde ausgeführt und gemessen. Das ist die Aufzeichnung eines Tests an einem Datum und keine dauerhafte Zusicherung; der folgende Absatz sagt, welche Teile der Fähigkeit der Test nicht erreicht hat.
Zwei Einschränkungen dieser Aussage, beide bewusst. Die Probe stellte in eine getrennte Testdatenbank wieder her und nicht über eine laufende, sodass der Schritt, der ein laufendes System überschreibt, weiterhin nur beschrieben und nicht erprobt ist. Und sie fand statt, als die Produktivdatenbank noch klein war; sie belegt also, dass das Verfahren funktioniert, und nicht, wie lange es bei Kundendatenmengen dauert. Beides ist in Bekannte Lücken, Nummer 4, festgehalten.
Die Überwachung der Sicherungen ist unvollständig. Eine fehlgeschlagene Sicherung löst eine Meldung aus. Ein Sicherungsplan, der stillschweigend aufhört zu laufen, nicht. Derzeit erkennt nichts das Ausbleiben einer Sicherung, sondern nur ihr Fehlschlagen (Bekannte Lücken, Nummer 5).
5. Überprüfung und Bewertung (Art. 32 Abs. 1 lit. d DSGVO)
Die kontinuierliche Integration läuft bei jedem Pull Request und ist eine Pflichtprüfung für main. Sie prüft das gesamte Repository auf Stil und typprüft und testet die betroffenen Pakete statt aller: Das Build-Werkzeug vergleicht mit der Basis des Pull Requests und führt die geänderten Pakete sowie die von ihnen abhängigen aus, sodass eine Änderung an gemeinsam genutztem Code weiterhin die API und die Web-Anwendung testet. Hier steht bewusst "betroffen" und nicht "die vollständige Suite", weil beides in einem offenlegungswürdigen Fall auseinandergeht: Eine Änderung, die überhaupt kein Paket berührt, etwa an einem Workflow oder an der Dokumentation, ergibt null Pakete und meldet eine grüne Testprüfung, die nichts ausgeführt hat. Die zugrunde liegenden Suiten umfassen 3.141 API-Tests in 339 Dateien und 1.642 Web-Tests, gezählt am 09.08.2026 mit einem Werkzeug, das Tests auflistet, ohne sie auszuführen.
Dieselbe Pflichtprüfung trägt Sperren, die einen Merge blockieren, der eine zerstörerische Datenbankmigration ohne ausdrückliche Bestätigung einführt, lesesperrende Migrationssperren ohne schriftliche Entscheidung, einen veralteten Schnappschuss des öffentlichen API-Schemas oder einen Bruch der Reihenfolge von Migrationen.
Änderungen laufen über Pull Requests, und es ist gelebte Praxis, einen vor dem Merge zu prüfen. Das ist eine Praxis und keine erzwungene Kontrolle, und diese Unterscheidung ist der Grund, warum es so formuliert ist. Der Branch-Schutz auf main verlangt das Bestehen der Prüfungen CI und Images; er verlangt keine zustimmende Review, verlangt keine Auflösung offener Kommentare und gilt nicht für Administratoren (abgelesen an der Branch-Protection-API am 09.08.2026). Erzwungen ist also der Teil mit den Prüfungen, und der Teil mit der Review hängt an der Arbeitsweise des Teams. "Jede Änderung wird vor dem Merge geprüft" wäre eine Aussage über die gesamte Vergangenheit, die hier nirgends aufgezeichnet ist und die eine Prüfstelle sich belegen lassen könnte.
Nicht vorhanden, und besser hier gesagt als erfragt: kein Penetrationstest, keine Zertifizierung nach ISO 27001, keine nach SOC 2, kein externes Sicherheitsaudit und keine förmlich terminierte Überprüfung dieser Maßnahmen. Art. 32 Abs. 1 lit. d DSGVO verlangt ein Verfahren zur regelmäßigen Überprüfung und Bewertung der Wirksamkeit, und eine jährliche Überprüfung mit Datum und Unterschrift ist das Mindeste, was dem genügt. Eine solche Überprüfung ist noch nicht terminiert.
5a. Maßnahmen an der Angriffsfläche
- Schutz vor SSRF bei vom Nutzer angegebenen Mail-Hosts und beim Abruf von Website-Symbolen:
DNS-Auflösung, Ablehnung privater, Loopback-, Link-Local- und CGNAT-Adressen einschließlich der Metadatenadresse 169.254.169.254, anschließend Bindung der Verbindung an die geprüfte IP-Adresse, sodass ein DNS-Rebinding sie nicht umlenken kann; der Hostname bleibt allein für die TLS-SNI erhalten (apps/api/src/lib/net/net-guard.ts).
- Ratenbegrenzung je IP-Adresse, je API-Schlüssel und bei fehlgeschlagener Authentifizierung, mit
einem atomaren festen Zeitfenster in Valkey (apps/api/src/lib/rate-limit.ts).
- CORS ist eine ausdrückliche Positivliste und kein Platzhalter.
- Abhängigkeiten: Die Prüfung auf bekannte Schwachstellen läuft **wöchentlich nach Zeitplan und
meldet, statt zu sperren** (.github/workflows/audit.yml, montags 06:15 UTC). Sie eröffnet und aktualisiert eine einzelne Tracking-Aufgabe und blockiert bewusst keinen Merge. Der Grund liegt im Zeitpunkt und nicht im Umfang: Der Fund, um dessentwillen sie existiert, ist eine Meldung, die zu einer Lockfile veröffentlicht wird, die niemand angefasst hat, und eine Prüfung zum Merge-Zeitpunkt würde sie erst beim nächsten Pull Request bemerken, den es in einer ruhigen Woche nicht gibt. Eine Sperre für neu eingeführte Meldungen ist eine eigene, zurückgestellte Frage.
Ausdrückliche Einschränkung. Die Ratenbegrenzung fällt offen aus, wenn Valkey nicht erreichbar ist (apps/api/src/lib/rate-limit.ts), und protokolliert das höchstens alle 30 Sekunden. Ein Ausfall von Valkey nimmt der öffentlichen API damit den Schutz vor Brute-Force-Angriffen, und zwar fast ohne Signal. Das ist eine bewusste Abwägung zugunsten der Verfügbarkeit und ist als Lücke in Abschnitt 3 festgehalten. Ein Sicherheitsfragebogen wird danach fragen; besser, es steht zuerst hier.
5b. Protokollierung und Überwachung
Ehrlich und kurz. Das an das Team gerichtete audit_log und die an den Betrieb gerichtete Tabelle auth_events sind fortschreibend und sind die dauerhafte Aufzeichnung darüber, wer über die Anwendung was getan hat; sie werden 365 beziehungsweise 90 Tage aufbewahrt (Abschnitt 6). Anwendungsprotokolle sind die Standardausgabe der Container.
Eine Fehlerberichterstattung besteht, allerdings nur serverseitig. Die API und der Worker melden unbehandelte Serverfehler an einen selbst betriebenen Empfänger auf eigener Infrastruktur des Auftragsverarbeiters. Drei Erfassungspunkte und keine weiteren: eine Anfrage, deren Fehler mit 500 oder höher beantwortet wird, ein Hintergrundauftrag, der endgültig fehlgeschlagen ist und nicht bloß in einem Versuch, der wiederholt wird, und ein Fehler, der den Start eines Containers verhindert (apps/api/src/lib/observability/report.ts). Ein 4xx wird bewusst verworfen, was bedeutet, dass jede Verweigerung einer Berechtigung dort unsichtbar ist; sie steht stattdessen im audit_log.
Was ein Ereignis mitträgt, und die eine Einschränkung, auf die es ankommt. Das strukturierte Ereignis trägt Typ, Meldung und Stacktrace der Ausnahme, das Muster der Route, die ID des Nutzers und des Teams sowie die Release-Kennung; es trägt bewusst keinen Anfragerumpf, keinen Abfragewert, kein Cookie, keinen Authorization- oder X-API-Key-Header, keine E-Mail-Adresse, keine IP-Adresse und keine lokalen Variablen (sendDefaultPii: false sowie ein Filter in beforeSend in apps/api/src/instrument.ts). Diese Zusage betrifft allein die strukturierten Felder. Konsolen-Breadcrumbs aus dem Vorlauf zum Fehler reisen mit dem Ereignis und werden nicht Feld für Feld gefiltert, sodass alles, was eine Protokollzeile zufällig enthielt, den Empfänger erreicht, was auch immer die obige Aufzählung sagt. Die Anwendung protokolliert mit einer einfachen Konsole, sodass es sich um dieselbe Datenklasse handelt, die die Standardausgabe des Containers ohnehin hält, nur für kürzere Zeit und auf eigener Hardware; es ist aber die ehrliche Grenze des Satzes davor. Die Aufbewahrung beim Empfänger beträgt 30 Tage. Die vollständige Aufstellung dessen, was gesendet wird und was nicht, führt der Auftragsverarbeiter und stellt sie auf Anfrage zur Verfügung.
Auch die Browserseite meldet, in getrennte Projekte gegenüber denen der API. Der Browser des Kunden sendet an /monitoring auf dem eigenen Ursprung der Anwendung, und der Auftragsverarbeiter leitet die Meldung serverseitig weiter; kein Browser eines Kunden nimmt also unmittelbar Verbindung zum Empfänger auf, und im Netzwerkprotokoll des Kunden erscheint keine Anfrage an Dritte. Die Aufstellung für den Browser gehört zu derselben Liste und ist strenger als die der API: Konsolen-Breadcrumbs sind an der Quelle abgeschaltet und werden nicht bloß gefiltert. Zwei Grenzen sind nennenswert, weil beide Wege sind, auf denen ein Fehler für uns unsichtbar bleibt: Eine Meldung über den eigenen Ursprung der Anwendung ist immer noch eine Anfrage, die ein Werbeblocker oder ein Unternehmens-Proxy verwerfen kann, und dort, wo die Anwendung den Fehler behandelt und dem Kunden eine Meldung angezeigt hat, wird überhaupt nichts erfasst.
Alles Übrige in diesem Abschnitt fehlt weiterhin: keine zentrale Aufbewahrung von Protokollen, keine Alarmierung, kein APM und keine Angriffserkennung. "Keine Alarmierung" ist auf die Anwendung zu beziehen: Die einzige Meldung, die es überhaupt gibt, ist die Fehlermeldung des Sicherungsauftrags (Abschnitt 4), die über die Anwendung nichts aussagt und die, wie Bekannte Lücken Nummer 5 festhält, nicht auslöst, wenn der Zeitplan schlicht aufhört zu laufen. Die Fehlerberichterstattung verkleinert die schwächste Maßnahme dieser Anlage; sie schließt sie nicht, und kein Zustand innerhalb des Produkts schlägt von sich aus Alarm. Der Abschnitt steht vollständig hier, weil alles andere eine Behauptung wäre und weil es schlimmer ist, wenn ein Kunde das bei einer Prüfung entdeckt, als wenn er es hier liest. Es fehlt die Alarmierung, nicht die Berichterstattung: Beide Hälften der Fehlerberichterstattung bestehen, und keine von beiden schlägt Alarm. Stacktraces aus dem Browser kommen zudem minifiziert an, weil keine Source Maps an den Empfänger übertragen werden; das kostet Zeit bei der Aufklärung, nicht die Erkennung selbst.
Es wurde kein Überwachungsanbieter hinzugezogen, und genau darum ging es beim Selbstbetrieb. Der Empfänger für Fehlerereignisse läuft auf eigener Infrastruktur des Auftragsverarbeiters in Deutschland, unter demselben Kundenkonto beim Anbieter, das schon die Anwendung, die Datenbank und den Objektspeicher trägt. Keine Zeile kommt zu Abschnitt 8 hinzu, der die Teilmenge der Dritten nach Art. 28 Abs. 4 DSGVO ist. Alle diese Instanzen betreibt der Auftragsverarbeiter selbst, und "der Auftragsverarbeiter" heißt hier Unbogify GmbH: Nightly Build Group ist ein vorgesehener Handelsname derselben Gesellschaft und keine eigene juristische Person, sodass niemand dazwischentritt und keine dieser Instanzen ein Unterauftragsverarbeiter ist.
Was sich geändert hat, ist der Ort, an dem ein Teil der Daten ruht. Fehlerereignisse liegen auf einem zweiten Server: Die Laufzeitdaten der Anwendung bleiben im Übrigen in fsn1 (Falkenstein), während jene in nbg1 (Nürnberg) landen. Beides liegt in Deutschland, ebenso der Objektspeicher und die Sicherungen, es handelt sich also nicht um eine zweite Rechtsordnung; es ist das erste Mal, dass Daten den Anwendungshost verlassen.
Wird stattdessen jemals ein Überwachungsanbieter hinzugezogen, so wird er Unterauftragsverarbeiter, und Abschnitt 8 sowie Anlage 3 ändern sich mit ihm, mit dem Vorlauf von 30 Tagen, den Ziffer 5.2 des Vertrags verlangt.
6. Datenminimierung und Speicherbegrenzung (Art. 5 Abs. 1 lit. c und e DSGVO)
E-Mail. Steerd liest ein verbundenes Postfach nicht von sich aus. Nachrichten werden nur abgerufen, wenn der Nutzer den Importdialog öffnet. Eine importierte Nachricht speichert Absender, Betreff, die ersten 2.000 Zeichen des Textkörpers als reinen Text sowie Metadaten zu Anhängen; die Inhalte der Anhänge und der vollständige Nachrichtentext werden nicht gespeichert (apps/api/src/services/email-ingestions.ts). Bei Gmail wird als einziger Mail-Scope gmail.readonly angefragt, und der Rückruf prüft vor dem Aktivieren der Verbindung, ob dieser Scope tatsächlich erteilt wurde.
Hochgeladene Dateien. Hochgeladene Bilder werden dekodiert und neu kodiert, für jeden Zweck nach WebP mit Ausnahme des Rechnungslogos, das PNG bleibt, weil der Rechnungsgenerator WebP nicht dekodiert. In beiden Fällen entfernt die Neukodierung die EXIF-Daten und normalisiert die Ausrichtung, womit Kamera- und GPS-Metadaten verschwinden (apps/api/src/lib/storage/images.ts). Die Detailfelder des Audit-Protokolls und der Authentifizierungsereignisse tragen ausschließlich unkritische Metadaten, nie Geheimnisse und nie eine neue E-Mail-Adresse im Klartext.
Gegenbeispiel, aufgenommen, weil eine Anlage, die nur Erfolge aufzählt, keine Bewertung ist, und nach der Behebung beibehalten, weil die Behebung erst durch eine Frist erzwungen wurde. Die Gmail-Einwilligung fragte auch calendar.events ab, was im gesamten Code nirgends verwendet wurde (apps/api/src/lib/email/sources/google-config.ts). Es wurde vorsorglich angefragt, um eine erneute Einwilligung zu vermeiden, wenn die Kalenderintegration erscheint: eine vertretbare Produktentscheidung und eine unvertretbare aus Sicht der Datenminimierung, denn wer Gmail verband, erteilte Schreibzugriff auf den Kalender, den nichts ausübte. Am 07.08.2026 entfernt, als die Vorbereitung der Google-Verifizierung die zweite Lesart zur maßgeblichen machte: Jeder angefragte Scope muss im Einsatz nachgewiesen werden.
Aufbewahrung.
| Daten | Frist | Mechanismus |
|---|---|---|
| Ruhende kostenlose Konten: Kontakte, importierte E-Mails, Metadaten zur E-Mail-Aktivität | 365 Tage Inaktivität, nach Warnungen bei 30 und 7 Tagen | apps/api/src/jobs/purge-dormant-accounts.ts |
| Audit-Protokoll des Teams | 365 Tage | apps/api/src/jobs/purge-logs.ts |
| Protokoll sicherheitsrelevanter Ereignisse (enthält IP-Adresse und User-Agent) | 90 Tage | apps/api/src/jobs/purge-logs.ts |
| Grabsteine der CardDAV-Synchronisation | 90 Tage | apps/api/src/jobs/carddav-tombstone-gc.ts |
| Cache für die Idempotenz von Anfragen | 24 Stunden | apps/api/src/lib/http/idempotency.ts |
| Verwaiste Objekte im Speicher | Täglich abgeglichen | apps/api/src/jobs/files-reclaim.ts |
| Exportarchive (im Klartext, enthalten Daten betroffener Personen) | 30 Tage ab Erstellung, durch eine Kontolöschung nicht verkürzt | apps/api/src/jobs/purge-exports.ts |
| Serverfehlerereignisse (Stacktrace, Routenmuster, Nutzer- und Team-ID, Konsolen-Breadcrumbs) | 30 Tage | Einstellung am selbst betriebenen Empfänger (Abschnitt 5b) |
Wie diese Fristen durchgesetzt werden, und wo das endet. Jede Frist oben mit Ausnahme der letzten wird von einer geplanten Aufgabe der Hosting-Plattform ausgeführt und nicht von der Anwendung selbst. Dass der Code existiert, der eine Löschung vornimmt, ist deshalb für sich genommen kein Beleg dafür, dass die Löschung auch läuft. Bei der Zeile zu den Fehlerereignissen verhält es sich umgekehrt: Sie ist eine Aufbewahrungseinstellung am Empfänger, und auch dort setzt die Anwendung nichts durch.
Stand 09.08.2026 sind alle sieben geplanten Aufgaben in beiden Umgebungen vorhanden und aktiv, und die drei Löschläufe zur Aufbewahrung haben jeweils einen Durchlauf abgeschlossen, der das Anwenden seiner Löschungen gemeldet hat. Das ist eine Aussage zu einem Datum und keine dauerhafte Zusicherung, und der Abschnitt Bekannte Lücken hält den Teil fest, der tatsächlich nicht abgedeckt ist: Nichts schlägt Alarm, wenn ein Zeitplan aufhört zu laufen, ein stillschweigend gestoppter Zeitplan wäre also erst sichtbar, wenn jemand nachsieht. Jeder dieser Aufträge löscht nach Alter und nicht schrittweise, sodass ein ausgefallener Tag vom nächsten erfolgreichen Durchlauf nachgeholt wird; ein ausgefallener Monat fiele dem System nicht auf.
Zwei Spalten überdauern die Löschung ruhender Konten bewusst. projects.description und activities.content können denselben 2.000 Zeichen langen Auszug aus einem E-Mail-Text enthalten, geschrieben in dem Moment, in dem der Nutzer einen Import bestätigt (apps/api/src/services/materialize.ts). Sie bleiben unangetastet, weil der Text zu diesem Zeitpunkt die eigene Geschäftsunterlage des Nutzers ist und ihn zu leeren hieße, Unterlagen stillschweigend zu verändern, die der Nutzer für seine eigenen hält. Die vollständige Begründung, das Gegenargument und der Umstand, dass dies eine begründete Voreinstellung und keine abschließend getroffene Entscheidung ist, hält der Auftragsverarbeiter fest und stellt sie auf Anfrage zur Verfügung. Anlage 1.5 des Vertrags sagt dasselbe, und beide dürfen nicht auseinanderlaufen.
7. Unterstützung des Verantwortlichen (Art. 28 Abs. 3 lit. e und f DSGVO)
Auskunft und Datenübertragbarkeit (Art. 15, 20 DSGVO). Der Selbstbedienungsexport aus den Einstellungen erzeugt ein ZIP mit den Datensätzen des Teams als JSON, eine Datei je Tabelle, dazu jedes hochgeladene Dokument und jeden Anhang, mit einem überprüfbaren Prüfsummenmanifest (apps/api/src/lib/files/export-records.ts).
Löschung (Art. 17 DSGVO). Die Kontolöschung in Selbstbedienung entfernt die Teams des Nutzers und deren Inhalte. Einzelne Datensätze werden im Produkt auf Anforderung gelöscht, und diese Löschung ist eine echte Löschung in der Datenbank und kein Kennzeichen: deleteContact entfernt den Datensatz, löscht kaskadierend in fünf abhängigen Tabellen, räumt die Anhänge ab und löscht das Avatar-Objekt (apps/api/src/services/contacts.ts). Eine importierte E-Mail lässt sich einzeln löschen.
Eine Stelle ist eine Ausnahme, und dieser Absatz hat früher bestritten, dass es sie gibt. contacts.archived_at und projects.archived_at sind Spalten für ein weiches Löschen, und ein CardDAV-DELETE vom Telefon archiviert den Kontakt, statt ihn zu löschen (apps/api/src/routes/carddav.ts, archiveForDav). Das ist eine bewusste Entscheidung zugunsten der Sicherheit, weil eine kaskadierende harte Löschung für ein versehentliches Wischen auf dem Telefon zu zerstörerisch wäre, und die Karte verschwindet ohnehin aus dem synchronisierten Adressbuch. Es gehört trotzdem hierher: Eine Löschung, die von einem synchronisierten Gerät ausgelöst wird, lässt den Datensatz bestehen, und die harte Löschung bleibt eine Handlung in der Anwendung.
Löschung oder Rückgabe bei Vertragsende (Art. 28 Abs. 3 lit. g DSGVO). Die Kontolöschung leistet beides: Ein Export wird erstellt und überprüft, bevor der Verschlüsselungsschlüssel des Teams vernichtet wird. Die Rückgabe geschieht also zuerst, und erst danach ist die Löschung unumkehrbar (apps/api/src/services/account-deletion.ts).
8. Unterauftragsverarbeiter (Art. 28 Abs. 4 DSGVO)
| Unterauftragsverarbeiter | Zweck | Ort |
|---|---|---|
| Hetzner Online GmbH | Server, Datenbank, Cache und der selbst betriebene Empfänger für Fehlerereignisse | Deutschland: fsn1 (Falkenstein) für Anwendung und Datenbank, nbg1 (Nürnberg) für Fehlerereignisse (Abschnitt 5b) |
| Hetzner Objektspeicher | Dateien, Anhänge, Reisebelege, Avatare, Lebenslauffotos, Rechnungslogos, Exportarchive | Deutschland (fsn1) |
| Amazon Web Services | Nächtliche Sicherungen der Datenbank, Container-Images | Deutschland (eu-central-1) |
| Amazon Web Services (SES) | Relay für Transaktions-E-Mails; sieht damit jede Empfängeradresse, jeden Betreff und jeden Text | Deutschland (eu-central-1) |
| OpenAI Ireland Ltd | KI-gestützter Import von Lebensläufen und Dokumenten, nur auf Veranlassung des Nutzers: der Inhalt des einen Dokuments, das der Nutzer übergibt | Irland. OpenAI Ireland übermittelt zur Ausführung des Modells weiter an OpenAI OpCo, LLC in den Vereinigten Staaten |
Mit jedem in der Tabelle genannten Unterauftragsverarbeiter besteht ein Auftragsverarbeitungsvertrag. Ziffer 6.3 des Vertrags bietet dem Kunden auf Anfrage eine Kopie des jeweiligen Instruments an, geschwärzt nur soweit dies zum Schutz der Vertraulichkeit Dritter erforderlich ist; das ist der Weg, auf dem der Nachweis erbracht wird, und nicht die Veröffentlichung. Anlage 3 ist die maßgebliche Liste der Unterauftragsverarbeiter; diese Tabelle beschreibt dieselben Anbieter aus dem Blickwinkel der Maßnahmen und darf von ihr nicht abweichen. Nur zwei dieser Verträge mussten eigens geschlossen werden, der Vertrag mit Hetzner und das Selbstbedienungsformular von OpenAI. Die übrigen sind entweder durch Verweis einbezogen, womit der Vertrag bereits gilt und es keine Unterschrift zu leisten gibt, oder es sind eigene, selbst betriebene Instanzen, die überhaupt keine Dritten sind.
Diese Anlage führt nur Anbieter auf, die Daten berühren, die wir auf Weisung des Kunden halten. Stripe, Cloudflare und Google verarbeiten personenbezogene Daten, für die Unbogify selbst Verantwortlicher ist: Abrechnung, Bot-Schutz auf den Formularen der Marketing-Website und Website-Analyse. Sie sind in der Datenschutzerklärung des Auftragsverarbeiters und in der Aufstellung der Anbieter benannt, die nach Anlage 3 keine Unterauftragsverarbeiter sind, und sie stehen hier bewusst nicht. Sie aufzuführen würde ihre Rolle falsch darstellen und dem Kunden ein Widerspruchsrecht über eine Verarbeitung geben, die nicht seine Daten betrifft.
Der selbst betriebene Mailversand, die Steuerungsebene des Hostings und der Empfänger für Fehlerereignisse stehen ebenfalls nicht hier, aus einem dritten Grund: Es sind eigene, selbst betriebene Instanzen und keine Dritten. Sie werfen keine Frage nach Art. 28 Abs. 4 DSGVO auf: Nightly Build Group ist ein vorgesehener Handelsname der Unbogify GmbH und keine eigene juristische Person, sodass ihr Betrieb keinen weiteren Auftragsverarbeiter dazwischenschaltet.
OpenAI steht mit Wirkung vom 07.08.2026 in der Tabelle, dem Tag, an dem der KI-gestützte Import im Produktivbetrieb aktiv wurde. Die Grundlage der Übermittlung ist in Anlage 3 je Empfänger angegeben, und die Übermittlungsfolgenabschätzung, die der Vertrag auf Anfrage zusagt, ist durchgeführt.
Jeder Anbieter, der Daten des Kunden für den Betrieb des Dienstes hält, verarbeitet sie in Deutschland. Anwendung, Datenbank und Cache liegen in fsn1 (Falkenstein), der Objektspeicher in fsn1, der Empfänger für Fehlerereignisse in nbg1 (Nürnberg) und die Sicherungen der Datenbank in eu-central-1 (Frankfurt am Main).
Die eine Ausnahme ist die letzte Zeile der Tabelle, und sie ist gewollt und nicht übersehen. Der KI-gestützte Import übergibt das eine Dokument, das ein Nutzer einreicht, an die OpenAI Ireland Ltd in Irland und nicht in Deutschland; sie übermittelt zur Ausführung des Modells weiter in die Vereinigten Staaten. Deshalb steht hier nicht "jeder Unterauftragsverarbeiter": Für jene Zeile wäre das falsch, und ein Satz, der für vier Zeilen zutrifft und für die fünfte nicht, ist schlechter als gar kein Satz. Anlage 3 nennt Ort und Übermittlungsgrundlage je Empfänger, und beide müssen übereinstimmen.
Übermittlungen in die Vereinigten Staaten stützen sich auf die Standardvertragsklauseln, die in den jeweiligen Verträgen der Anbieter einbezogen sind. Die Datenschutzerklärung im Produkt nennt seit dem 09.08.2026 ebenfalls die Standardvertragsklauseln, sodass beide übereinstimmen. Ob einer der Anbieter zusätzlich nach dem EU-US Data Privacy Framework zertifiziert ist, wurde für Hetzner, AWS und Cloudflare nicht geprüft und wird für sie deshalb auch nicht in Anspruch genommen.
OpenAI ist nicht nach dem EU-US Data Privacy Framework zertifiziert. Geprüft am 07.08.2026 gegen die amtliche Teilnehmerliste, als aktiver wie als inaktiver Teilnehmer und in jeder Schreibweise. Die Suche wurde gegen einen Anbieter gegengeprüft, von dem bekannt ist, dass er geführt wird, sodass das negative Ergebnis ein echtes ist und keine fehlgeschlagene Abfrage. Die Standardvertragsklauseln sind damit der einzige Weg nach Art. 46 DSGVO für diesen Empfänger, und Anlage 3 benennt sie für ihn.
Die eigene Übermittlung des Auftragsverarbeiters an OpenAI ist ohnehin keine Übermittlung in ein Drittland: Vertragspartner ist die in der Europäischen Union ansässige OpenAI Ireland Ltd, und die Weiterübermittlung in die Vereinigten Staaten ist die dieser Gesellschaft. Anlage 3 hält das je Empfänger fest.
Warum Stripe nicht in der Tabelle oben steht. Stripe verarbeitet personenbezogene Daten für die eigene Abrechnungsbeziehung des Auftragsverarbeiters zum Kunden, für die der Auftragsverarbeiter Verantwortlicher ist und nicht der Kunde. Ziffer 5.5 des Vertrags nimmt solche Anbieter von der Liste der Unterauftragsverarbeiter aus, weil ihre Aufnahme ihre Rolle falsch darstellen und dem Kunden ein Widerspruchsrecht über eine Verarbeitung geben würde, die nicht seine Daten betrifft. Stripe ist in der Datenschutzerklärung des Auftragsverarbeiters benannt, und Anlage 3 führt es unter den Anbietern auf, die nach dem Vertrag keine Unterauftragsverarbeiter sind. Für die Software selbst bleibt die Unbogify GmbH Vertragspartner des Kunden.
9. Meldung von Verletzungen (Art. 33 DSGVO)
Der Auftragsverarbeiter unterhält ein dokumentiertes Verfahren für den Umgang mit Verletzungen des Schutzes personenbezogener Daten. Er benachrichtigt den Kunden über eine Verletzung, die im Auftrag des Kunden verarbeitete personenbezogene Daten betrifft, zu den Bedingungen und innerhalb der Frist, die Ziffer 8.2 des Vertrags bestimmt.
Bekannte Lücken, benannt statt verschwiegen
Eine Anlage, die das System zu gut darstellt, ist schlechter als eine, die eine Lücke einräumt, denn die Übertreibung ist ein vertragliches Versprechen.
1. Die Aufbewahrungsläufe laufen, belegt durch ein Datum und nicht durch eine Zusicherung. Geschlossen am 09.08.2026 (Abschnitt 6): Alle sieben geplanten Aufgaben sind in beiden Umgebungen vorhanden und aktiv, und die drei Löschläufe haben jeweils einen Durchlauf abgeschlossen, der seine Löschungen angewendet hat. Was das nicht schließt, ist die Überwachung, also Nummer 5: Nichts erkennt einen Zeitplan, der aufgehört hat zu laufen. Richtig gelesen besagt dieser Punkt also, dass die Aufbewahrungsfristen an einem genannten Datum als laufend überprüft wurden, und nicht, dass ihr Laufen zugesichert ist. 2. Es wurde kein Penetrationstest und kein externes Sicherheitsaudit durchgeführt. 3. Es gibt keine förmliche Regelung der Zugriffsverwaltung für den Zugriff von Beschäftigten auf den Produktivbetrieb (Abschnitt 2). Wer Zugriff hat, ist inzwischen festgehalten und einzelnen Personen zurechenbar, aber die Zwei-Faktor-Authentifizierung ist unbestätigt, die Verpflichtungen auf Vertraulichkeit sind nicht dokumentiert, und eine Zugangsberechtigung auf dem Produktivsystem ist nicht zugeordnet. 4. Die Wiederherstellung aus Sicherungen ist geprobt, zwei Teile davon sind weiterhin ungetestet. Die vollständige Wiederherstellung wurde am 10. August 2026 ausgeführt, einschließlich des Wegs über den Verschlüsselungsschlüssel (Abschnitt 4). Ungetestet bleibt eine Wiederherstellung, die eine laufende Datenbank überschreibt, und eine Wiederherstellung bei Kundendatenmengen: Die Probe nutzte eine getrennte Testdatenbank, während der Produktivbetrieb noch klein war; die gemessene Dauer beantwortet damit keine der Fragen, die während eines Vorfalls bei Kundendatenmengen gestellt würden. 5. Nichts erkennt eine Sicherung, die aufhört zu laufen. Fehlschläge melden sich, Schweigen nicht (Abschnitt 4). Auf dieser Infrastruktur ist das nicht hypothetisch: Der Sicherungsplan einer anderen Datenbank stand einmal 49 Tage still, bei durchgehend aktivierter Fehlermeldung, weil nichts fehlschlug und nichts lief. 6. Hochgeladene Dateien und Anhänge werden nicht gesondert gesichert. Dieser Speicher ist versioniert, ein versehentliches Löschen oder Überschreiben ist also behebbar, aber es gibt keine unabhängige Kopie bei einem zweiten Anbieter wie bei der Datenbank (Abschnitt 4). 7. Es gibt keine Point-in-Time-Recovery für die Datenbank, nur nächtliche Sicherungen (Abschnitt 4). 8. Geschlossen am 07.08.2026: Die Übermittlungsgrundlage des KI-Imports steht fest, und eine Offenlegung bleibt. Der Punkt lautete früher, der KI-Import sende Dokumentinhalte auf ungeklärter Grundlage in die Vereinigten Staaten. Das trifft nicht zu. Vertragspartner des Auftragsverarbeiters ist die OpenAI Ireland Ltd mit Sitz in der Europäischen Union; jene Übermittlung ist damit EU zu EU, und Kapitel V DSGVO greift auf der Ebene des Auftragsverarbeiters nicht ein. Die Weiterübermittlung in die Vereinigten Staaten ist die von OpenAI Ireland selbst, auf Grundlage von deren Vertrag zur Auftragsverarbeitung, und sie haftet weiterhin für ihre eigenen Unterauftragsverarbeiter. OpenAI ist nicht nach dem EU-US Data Privacy Framework zertifiziert, weshalb die Standardvertragsklauseln der einzige Weg nach Art. 46 DSGVO für jene Weiterübermittlung sind; genau die benennt Anlage 3.
Was als Offenlegung und nicht als Lücke bestehen bleibt: Inhalte, die an diese API gehen, werden nicht zum Training von Modellen verwendet und werden beim Anbieter höchstens 30 Tage zur Missbrauchserkennung aufbewahrt; in dieser Zeit sind sie für Beschäftigte des Anbieters und für beauftragte Fachkräfte lesbar, die die Missbrauchsprüfung durchführen. Anlage 3 sagt das ebenfalls, weil es die Zeile ist, nach der Kunden fragen. 9. Es gibt keine Alarmierung für die Anwendung und keine Angriffserkennung (Abschnitt 5b). Die Fehlerberichterstattung selbst ist nicht mehr die Lücke: Unbehandelte Serverfehler aus der API und dem Worker erreichen einen selbst betriebenen Empfänger, und Browserfehler erreichen ihn ebenfalls, wenn auch mit minifizierten Stacktraces, weil keine Source Maps übertragen werden. Es fehlt alles, was dafür sorgen würde, dass eine Meldung bei einem Menschen ankommt: Kein Zustand der Anwendung schlägt von sich aus Alarm, und es gibt keine zentrale Aufbewahrung von Protokollen. "Anwendung" ist dabei der Umfang, und die einzige Ausnahme überhaupt ist die Fehlermeldung des Sicherungsauftrags aus Nummer 5, die einen Auftrag überwacht und nicht das Produkt. Die praktische Folge für Art. 33 DSGVO ist unverändert, und es lohnt sich zu sagen, warum die Berichterstattung daran nichts geändert hat: Eine Meldung entsteht nur dort, wo etwas abgestürzt ist, und ein Zugriff, der gelingt, stürzt nicht ab. Das erste Anzeichen einer Verletzung ist damit weiterhin am ehesten ein Hinweis des Kunden, und das Verfahren des Auftragsverarbeiters für den Umgang mit Verletzungen sagt dasselbe. 10. Die Ratenbegrenzung fällt offen aus, wenn Valkey ausfällt, und zwar fast ohne Signal (Abschnitt 5a). 11. Eine anbieterseitige Verschlüsselung im ruhenden Zustand ist nicht belegt für die Datenträger und Buckets bei Hetzner (Abschnitt 1). Gewöhnliche Datensätze liegen in einfachen Spalten. 12. Geschlossen am 07.08.2026: Die Gmail-Einwilligung fragt nicht mehr zu viel ab. Sie hatte Schreibzugriff auf calendar.events verlangt, den nichts nutzte; der Scope wurde entfernt. Der Punkt behält seine Nummer, statt gestrichen zu werden, damit ein Verweis auf "Nummer 12" aus einer früheren Prüfung weiterhin auf das trifft, worum es ging. 13. Avatare, Lebenslauffotos, Rechnungslogos und Exportarchive erhalten keine Verschlüsselung auf Anwendungsebene im Objektspeicher (Abschnitt 1). Diese erfasst Dokumente, Anhänge, Reisebelege und finalisierte Rechnungen; der Namensraum uploads und die erzeugten Export-ZIPs werden bewusst im Klartext geschrieben. Ob unterhalb davon etwas verschlüsselt, ist genau das, was Nummer 11 als nicht belegt bezeichnet. Für diese Objekte gibt es damit weder eine Schicht, die wir steuern, noch eine, die wir nachweisen können, und die Fotografien, die ein Kunde von seinen eigenen Kontakten und Mitarbeitern hält, gehören dazu. Gefunden bei der vollständigen Durchsicht am 09.08.2026, bei der diese Anlage auch aufhörte zu behaupten, der Objektspeicher enthalte ausschließlich verschlüsselte Blobs. 14. Die Prüfung vor dem Merge ist Praxis und keine erzwungene Kontrolle (Abschnitt 5). main verlangt die Prüfungen für CI und Images und keine zustimmende Review, sodass nichts in der Plattform eine ungeprüfte Änderung aufhalten würde. Das steht hier, weil Art. 32 Abs. 1 lit. d DSGVO ein Verfahren meint, das wir nachweisen müssten, und weil eine Prüfstelle die Behauptung einer erzwungenen Sperre in einer Minute widerlegen kann.