# RET-04 – Prüfprotokoll: WORM-Speicher-Garantie (Append-only) Voraussetzung RET-01 – bereits Fertig. ## Grenzen des Schutzes (bewusst dokumentiert, nicht behauptet) Nach Nutzerentscheidung (Option 1) beschränkt sich der technische Schutz auf zwei Ebenen, beide EHRLICH begrenzt dokumentiert statt als absolut verkauft: 1. **Dateisystem-Schreibschutz (`chmod 0400`)** — schützt zuverlässig gegen den Betriebs-Nutzer der Dienste (`nexarch`, kein root), NICHT gegen root/CAP_DAC_OVERRIDE. Ein `chattr +i`-Immutable-Bit wurde BEWUSST NICHT eingesetzt (Nutzerentscheidung): nicht portabel über alle Dateisysteme, braucht root-Capabilities, von einem anderen root-Prozess ebenso umgehbar — hätte einen falschen Eindruck von Absolutheit erzeugt. 2. **Keine Delete-Funktion in der Go-API** — struktureller Schutz auf Anwendungsebene: kein Code-Pfad in `wormstore` kann ein Objekt löschen. Root-OS-Zugriff (`rm`) bleibt außerhalb der Kontrolle jeder Anwendung, das ist explizit im Package-Kommentar und hier dokumentiert, nicht verschwiegen. Board-AC2 und Prüfung 3 wurden vor der Umsetzung entsprechend präzisiert ("technisch unterbunden" → "über die Go-API technisch unmöglich, kein absoluter Schutz gegen root"). ## Umsetzung - `archive/migrations/0007_worm_objects.up/down.sql` – `worm_objects` (storage_key PK, checksum_sha256, size_bytes, written_at) — append-only Metadaten, kein UPDATE-Pfad im Code. - `archive/internal/wormstore.Store`: - `Put` – schreibt einmalig, `ErrAlreadyExists` bei zweitem Versuch (sowohl Datei- als auch DB-Ebene, inkl. Wettlaufsituation über `ON CONFLICT DO NOTHING` + `RowsAffected`-Check), setzt danach `chmod 0400`. - `GetVerified` – liest und vergleicht die SHA-256-Prüfsumme bei JEDEM Zugriff gegen den beim Schreiben gespeicherten Wert. - **Kein `Delete`** — bewusst, siehe oben. ## Prüfungen | # | Prüfung | Ergebnis | |---|---|---| | 1 | Direkter Überschreibversuch am Speicherpfad wird abgewiesen | **bestanden** – `TestPut_DirectOverwriteAttemptIsRejected`: API-Ebene (`ErrAlreadyExists`) real getestet; zusätzlich ECHTER Nachweis auf 131 als Nicht-Root-Nutzer (`sudo -u nexarch`, dem tatsächlichen Betriebsnutzer der Dienste): direkter Schreibversuch auf eine `chmod 0400`-Datei schlägt real mit "Permission denied" fehl, Inhalt bleibt unverändert. Der Automatik-Test selbst läuft auf 131 als root (`os.Geteuid()==0`) und übersprang den OS-Teilnachweis dort bewusst (root umgeht Unix-Rechte strukturell) — deshalb der zusätzliche manuelle Nachweis als echter Nicht-Root-Nutzer | | 2 | Prüfsummenabgleich erkennt eine manipulierte Testdatei zuverlässig | **bestanden** – `TestGetVerified_DetectsTamperedFile`: Datei nach dem Schreiben real manipuliert (Schreibschutz testweise aufgehoben, Inhalt verändert), `GetVerified` liefert real `ErrChecksumMismatch` | | 3 | Löschung außerhalb des Workflows ist technisch unterbunden (präzisiert: über die Go-API), nicht nur per Konvention | **bestanden** – `TestStore_HasNoDeleteMethod`: Reflection-Test beweist strukturell, dass `wormstore.Store` KEINE Lösch-Methode besitzt — kein Kommentar/keine Konvention, sondern eine compile-time-nachweisbare API-Grenze | ## Build/Test-Ergebnis (192.168.1.131) ``` go build ./... -> clean go vet ./... -> clean golangci-lint run ./... -> 0 issues go test ./... -p 1 -> alle Archive-Pakete bestanden (inkl. wormstore) ``` ## Gesamtergebnis **Bestanden.** Alle drei (vor Umsetzung ehrlich präzisierten) Akzeptanzkriterien und Pflichtprüfungen real erfüllt — inklusive eines zusätzlichen, außerplanmäßigen manuellen Nachweises als echter Nicht-Root-Betriebsnutzer, weil der automatisierte Test auf 131 als root lief und den entscheidenden OS-Teilnachweis sonst nicht ehrlich hätte erbringen können.