Zusammenfassung

  • draft-ietf-jmap-object-history-00 erweitert Foo/get um frühere und zerstörte Objektversionen, gestattet Servern aber, schnelle Änderungen zusammenzufassen, Versionen in beliebiger Reihenfolge zu löschen und Historie bei Speicherdruck stillschweigend zu verwerfen.
  • Eine zurückgegebene Momentaufnahme hilft bei der Wiederherstellung. Sie nennt weder Akteur noch Änderungsauftrag, Autorisierungsentscheidung oder Folgewirkung; selbst hasMoreHistory: false bescheinigt keine vollständige Geschichte.

Ein Adressbuch kann die Telefonnummer vor ihrer Löschung wiederbringen. Ein Postfach kann eine Nachricht so zeigen, wie sie unmittelbar vor der Zerstörung aussah. Das ist nützlich: Ein Versehen wird umkehrbar, ohne dass jeder Client sein eigenes Nebenarchiv bauen muss.

Die Felder können jedoch beweiskräftiger wirken, als sie sind. Gleichbleibende Objekt-ID, Versionsnummer und Ersetzungszeit ergeben auf dem Bildschirm eine ordentliche Zeitleiste. Keines davon sagt, wer handelte, welcher Client die Mutation schickte, welche Regel sie erlaubte oder ob eine spätere Wirkung eintrat.

Genau hier verläuft die Grenze von JMAP Object History, das am 15. September unter dem Namen der Arbeitsgruppe eingereicht wurde. Der Entwurf macht alten Zustand abrufbar. Er verwandelt einen Wiederherstellungsspeicher nicht in ein Revisionsjournal.

Gespeicherte Zustände sind keine Ereignisse

Der JMAP-Kern stellt für jeden Objekttyp eine Methodenfamilie bereit: Foo/get, Foo/changes, Foo/set, Foo/query und Foo/queryChanges. Die Synchronisierung des aktuellen Zustands gehört bereits zur Architektur. Foo/changes nennt IDs, die sich zwischen Zuständen verändert haben, liefert jedoch nicht deren alte Werte.

Die Capability urn:ietf:params:jmap:object-history erweitert Foo/get. Mit includeReplaced: true können ersetzte Darstellungen neben dem lebenden Objekt erscheinen. includeDestroyed: true erlaubt Anfragen nach nicht mehr vorhandenen Objekten. Zusammen können beide alle noch gespeicherten Versionen eines zerstörten Objekts liefern.

Jede Version behält dieselbe Objekt-ID. objectHistory.version ordnet sie in der Antwort; objectHistory.replaced nennt den Zeitpunkt, an dem die Darstellung durch Aktualisierung oder Zerstörung ersetzt wurde. Null bezeichnet die lebende Fassung.

Das sind Zustandskoordinaten, keine Ereignisherkunft. Der Ersetzungszeitpunkt sagt nicht, wann die alte Fassung entstand. Die Versionsnummer bezeichnet keine Transaktion. Kein Feld identifiziert Akteur, Sitzung, Gerät, Auftragsinhalt, Autorisierungsrichtlinie, Freigabe, Motiv, Benachrichtigung oder externe Folge.

Aus zwei benachbarten Bildern lässt sich eine Wertedifferenz berechnen. Sie beweisen nicht, dass ein einzelner atomarer Vorgang diese Differenz verursachte.

Das fehlende Zwischenstück wurde womöglich nie gespeichert

Der Entwurf gestattet ausdrücklich, mehrere rasche Aktualisierungen zu einer Version zusammenzufassen. Wird eine Telefonnummer kurz nacheinander dreimal geändert, können nur der Wert vor und nach diesem Zeitraum bleiben. Für die einzelnen Schritte muss kein eigener Historieneintrag entstehen.

Alte Versionen darf der Server zudem in beliebiger Reihenfolge ausdünnen. Lücken in der Sequenz sind gültig; Clients dürfen weder Vollständigkeit noch Kontinuität voraussetzen. Eine Lücke hat damit mindestens zwei mögliche Ursachen: Es entstand nie eine getrennte Version, oder sie wurde später entfernt.

Auch die Nummer ist zwischen Anfragen absichtlich schwach. Server sollten konsistente Werte liefern, doch Clients dürfen sich nicht darauf verlassen. Die Zahl sortiert vor allem Versionen desselben Objekts in einer Antwort. Als dauerhafte Audit-Ereignis-ID würde sie eine Eigenschaft beanspruchen, die der Text nicht zusichert.

Diese Freiheit hält Speicheranforderungen realistisch. Sie macht „alles, was geschah“ ohne eigenständiges Ereignissystem zu einer unbeantwortbaren Frage.

hasMoreHistory ist ein Abrufhinweis, kein Vollständigkeitszertifikat

historyLimit begrenzt die Gesamtzahl und fordert die neuesten Einträge an. Wird die Grenze für eine angefragte ID erreicht, meldet hasMoreHistory: true, dass in diesem Augenblick noch ältere gespeicherte Einträge verfügbar sind. Bei mehreren Objekten verrät die Antwort nicht, welches betroffen ist; sie müssen einzeln abgefragt werden.

True gilt nur vorübergehend. Der Entwurf warnt, dass ältere Einträge vor der nächsten Anfrage verschwinden können. Das Flag beschreibt momentane Abrufbarkeit und reserviert nichts.

False ist noch schwächer. Üblicherweise bedeutet es, dass alle gespeicherten Einträge für die angefragten IDs zurückgegeben wurden. Der Server darf jedoch false melden, obwohl mehr Historie existiert, wenn deren Ermittlung nicht effizient ist. Es bedeutet weder, dass jede Änderung erfasst wurde, noch dass nichts entfernt oder jede weiterhin vorhandene Fassung gefunden wurde.

Eine Oberfläche, die false in „vollständiger Audit-Trail“ übersetzt, verkehrt den Vertrag. Belastbar ist nur: In dieser Antwort wurde keine weitere gespeicherte Historie gemeldet.

Null als Dauer verspricht keine ewige Aufbewahrung

Ein Konto mit dieser Capability veröffentlicht maxHistoryDuration. Eine Zahl ist das maximale Alter in Sekunden nach der Ersetzung, jenseits dessen eine Version bereits verworfen sein kann. Null bedeutet, dass der Server keine zeitbasierte Grenze setzt.

Null bedeutet nicht dauerhaft. Der Sicherheitsabschnitt berücksichtigt Speicherdruck und erlaubt stilles Verwerfen bei Kapazitätsgrenzen. Zeit ist ein Aufbewahrungsparameter, Gesamtvolumen ein anderer. Ein Objekttyp kann die Schnittstelle unterstützen, ohne eine einzige Vorversion zu halten. Dann liefert der Server weiterhin das aktuelle Objekt mit objectHistory und kann alle lebenden Objekte als Version 1 kennzeichnen.

Die Capability belegt somit eine Schnittstelle, keinen Mindestbestand an Beweisen. Beschaffung und Compliance brauchen eigene Anforderungen an Mindestdauer, Löschhinweise, Export, Integrität und Legal Hold.

Wiederherstellung und Rechenschaft brauchen verschiedene Belege

Für die Wiederherstellung passt das Modell. Ein Client kann über Email/changes zerstörte IDs ermitteln, sie an Email/get übergeben, gelöschte Objekte anfordern und den letzten Zustand vor der Zerstörung anzeigen. Nutzer gewinnen Inhalte zurück, ohne dass das Protokoll sie als weiterhin lebend ausgibt.

Für Rechenschaft fehlen entscheidende Angaben. Ein belastbarer Beleg verbindet authentifizierten Akteur und Sitzung, Ursprungsclient und Gerät, genauen Mutationsauftrag, bedingtes Zustandstoken, angewandte Richtlinienversion und Entscheidung, angenommene Servertransaktion, Vorher- und Nachher-Hashes, dauerhafte Ereignis-ID, Benachrichtigungszustellung und beobachtetes Ergebnis.

Object History kann die Vorher- oder Nachher-Darstellung beitragen. Den Rest füllt es nicht aus. Den Akteur aus dem Besitzer abzuleiten ist unsicher. Autorität aus einer sichtbaren Zustandsänderung abzuleiten überspringt die angewandte Regel. Eine Außenwirkung aus dem gespeicherten Wert abzuleiten verwechselt Annahme in der Steuerungsebene mit Ausführung und Beobachtung.

Wo Verantwortlichkeit zählt, müssen Wiederherstellungsschnappschüsse mit einem nur ergänzbaren Ereignisjournal verbunden werden. Ein Speicher darf nicht zwei widersprüchliche Verträge vortäuschen.

Historischer Zugriff ist nicht bloß heutiger Zugriff

Historie schafft eine schwierige Autorisierungsfrage. Wer das aktuelle Objekt nicht lesen darf, darf auch dessen Historie nicht lesen. Haben sich Berechtigungen verändert, soll der Server nur Fassungen liefern, für die der Anfragende seinerzeit ein Leserecht gehabt hätte.

So sieht eine neu berechtigte Person keine Werte aus einer Zeit ohne Recht. Zugleich muss der Server genügend historischen Autorisierungskontext bewahren. Eine gegenwärtige Zugriffsliste allein kann die richtige Antwort womöglich nicht rekonstruieren.

JMAP Sharing trennt bereits Principal, beabsichtigte Freigabe und wirksamen Zugriff. Object History ergänzt die Zeit: Das Recht auf eine alte Fassung hängt von einem damaligen Recht ab, nicht nur von der heutigen shareWith-Karte. Eine ausgelieferte Fassung zeigt, dass der Server ihre Offenlegung beschlossen hat; ohne separates Protokoll erklärt sie den Entscheid nicht vollständig.

Richtige Historie darf absichtlich unvollständig sein

Eine alte Fassung kann genau jene Information bewahren, die Nutzer oder Verwaltung entfernen wollten. Eine gelöschte Telefonnummer kann in der Kontakthistorie sichtbar bleiben. Deshalb empfiehlt der Entwurf eine administrative Möglichkeit, Historie bestimmter Objekte aus Datenschutz- oder Compliance-Gründen zu löschen.

Das ist kein zu verschweigender Fehler. Wiederherstellung, Rechenschaft, Löschung und Speicherökonomie ziehen in verschiedene Richtungen. Jede Datenklasse muss benennen, welches Ziel Vorrang hat, wer eine Bereinigung freigibt, ob ein manipulationsfester Löschbeleg bleibt und welche unabhängigen Audit-Fakten nach der Inhaltslöschung fortbestehen.

„Unveränderliche Historie“ auf einer löschbaren Schnittstelle wäre ein gefährliches Versprechen. Wiederherstellung abzuschalten, weil sie kein forensisches Journal ist, wäre ebenso falsch. Speicher und Grenzen müssen getrennt werden.

Annahme durch die Arbeitsgruppe ist kein Betrieb

Das September-Dokument ist nahezu textgleich mit dem individuellen Entwurf vom März. Der Protokollkörper erhielt keinen neuen Betriebsnachweis. Die wesentliche Änderung ist der Name der JMAP-Arbeitsgruppe.

Datatracker führt es als WG Document bei I-D Exists. Verantwortlicher Area Director, Shepherd und Telechat fehlen. In der Zusammenfassung bleibt der vorgesehene Status leer, während der Entwurfskopf Standards Track nennt. Es ist weiterhin ein Internet-Draft, kein RFC; die eingefrorenen Quellen belegen weder laufende Implementierung noch Aufbewahrungsregel eines benannten Dienstes.

Diese Reifegrenze trägt die Betriebslehre. Ein Registereintrag kann Implementierungen koordinieren. Nur Nachweise aus laufenden Systemen zeigen, welche Versionen erfasst, verdichtet oder gelöscht wurden, wer berechtigt war und ob die Wiederherstellung gelang.

Quellen