Dateien werden verschlüsselt, bevor sie das Gerät verlassen. Geräte synchronisieren sich direkt miteinander oder über alles, was Bytes ablegen kann: ein S3-Bucket, ein lokaler Ordner, ein Verzeichnis, das iCloud oder Dropbox transportiert. Keiner davon sieht Dateinamen oder Inhalte, und keiner braucht Sperren oder atomare Updates.
In Rust geschrieben. CLI, FUSE-Mount, Web-Oberfläche sowie C-, Python- und Go-Bindings.
i/d7a1…/000412-9f3c…-18204 i/2b90…/000098-71e0…-6112 p/3f/3f8a…-6291456 p/c2/c2d4…-5833728 n/0007-e41b…-2097152 r/d7a1…-epoch3
docs/ contract-2026.pdf 2 Versionen notes.md 2 Konflikt-Heads photos/ 2026-09/IMG_4471.heic beim Lesen geholt projects/cipherfs/ README.md Papierkorb: old-drafts/ (14 Dateien)
Links: Objektnamen aus Geräte-ID, Sequenznummer, Länge und Chiffrat-Hash. Rechts: der Dateibaum, den ein Gerät nach dem Entschlüsseln zeigt, mit Versionszahlen, Konflikten und Papierkorb. Zwischen beiden gibt es keinen Server.
Inhalte, Dateinamen und sensible Metadaten werden verschlüsselt, bevor sie das Gerät verlassen. Lesen prüft die Integrität; ein falsches Passwort, Manipulation oder Beschädigung schlagen deutlich fehl. Schlüssel und Klartext erreichen weder Logs noch Speicher.
Offline-Änderungen werden synchronisiert, sobald wieder Verbindung besteht. Unterbrochene Übertragungen werden wiederholt, und eine wiederholte Übertragung wendet nie eine alte Version erneut an oder belebt sie wieder. Gleichzeitige Änderungen bestimmen die aktuelle Version nach einer Regel; jede andere Version bleibt erhalten.
Kleine Dateien bleiben günstig. Große Dateien werden in Blöcke zerlegt, gestreamt und nach Byte-Bereich geholt. Niemand wählt einen Modus, und das Überschreiten einer Größenschwelle ändert nie die Semantik.
Verschlüsselung, Dateimodell, Speichertransaktionen und Synchronisationsregeln liegen im Kern. CLI, Mount, Web-Oberfläche und Sprach-Bindings passen nur den Zugriff an. Sie führen keine eigene Datenbank und erfinden keine Regeln.
Jedes Gerät hält den vollständigen gemeinsamen Index. Inhalte werden standardmäßig auf jedes Gerät synchronisiert; ein Telefon oder ein Laptop mit wenig Platz kann ein Teilgerät sein, das nur angeheftete Ordner und kürzlich Gelesenes behält.
Geräte verbinden sich direkt miteinander. Speicher halten nur Chiffrat-Objekte. Verlauf, Papierkorb und Konflikte sind Sichten auf eine gemeinsame Versionskette, auf jedem Gerät sichtbar. Jedes Gerät hat eine eigene Identität und kann widerrufen werden.
Jede Datei hat eine stabile Identität; ihr Pfad ist nur ein Attribut. Jedes Gerät hängt an sein eigenes signiertes Log an, und andere Geräte prüfen Mitgliedschaft, Hash-Kette und kausale Abhängigkeiten, bevor sie zusammenführen. Ein Löschen ist eine Tombstone-Version, ein Verschieben eine Version mit neuem Pfad, ein Konflikt sind zwei oder mehr Heads ohne kausale Ordnung.
Verzeichnisse und Mounts zeigen nur die aktuelle Version; Konfliktkopien werden nicht geschrieben. Eine Version verlässt den gemeinsamen Verlauf nur durch ein explizites Löschen oder die Aufbewahrungsrichtlinie des Repositories (standardmäßig 365 Tage). Zuerst bleibt sie 30 Tage im Wartezustand, in dem jedes Gerät abbrechen kann.
Clients, die die Repository-Schlüssel halten und Klartext lesen. Jedes hat ein langlebiges Schlüsselpaar, einen lesbaren Namen und die Rolle Voll oder Teil. Ein neues Gerät koppelt sich mit einem kurzen Code oder QR-Code; ohne vorhandenes Gerät tritt es mit dem Wiederherstellungsschlüssel bei.
Brauchen nur vier Operationen: unveränderliches Objekt schreiben, nach Name lesen, nach Präfix auflisten, löschen. Objekte sind inhaltsadressiert und nur anhängend, gepackt zu 4 bis 8 MiB. Ein noch nicht vollständig angekommenes Objekt gilt als „noch nicht da“, nie als „beschädigt“.
Inhaltsschlüssel leiten sich aus einer Schlüsselepoche ab. Das Widerrufen eines Geräts eröffnet eine neue Epoche, deren Schlüssel nur für die verbleibenden Geräte verpackt wird. Das Passwort schützt nur den lokalen Rechner; ein vergessenes Passwort wird mit dem Wiederherstellungsschlüssel zurückgesetzt, und das Gerät behält seine Identität.
Ein dauerhaft laufender Rechner ist das Vollgerät. Der Mac ist ein Teilgerät mit Mount. Er behält nur angeheftete Ordner und kürzlich gelesene Inhalte; alles andere erscheint weiterhin im Finder und wird beim Öffnen vom Vollgerät oder einem Speicher geholt. Über dem Cache-Budget werden Inhalte, die nachweislich anderswo existieren, automatisch freigegeben. Unsynchronisierte lokale Schreibvorgänge und offene Dateien werden nie freigegeben.
Geprüft auf macOS 27 mit FUSE-T: Der Mount trägt .metadata_never_index, ist von Time Machine ausgeschlossen, das Durchblättern aller Ordner im Finder ließ den Cache unverändert, und das Lesen einer nicht verfügbaren Datei im Offline-Zustand schlägt sofort fehl, statt zu hängen.
Nicht als stabile Version. Die bestätigten Anforderungen sind umgesetzt und jede hat Abnahmebelege, aber das Datenformat und die API dürfen sich noch ändern, es gab kein externes Sicherheitsaudit, und ein Kompatibilitätsversprechen wurde nie gegeben. Heute eignet es sich für den Autor und wenige Personen, die Formatänderungen akzeptieren.
Prüfergebnisse mit Stand 12. Oktober 2026. Die Zahlen sind tatsächliche Ausführungen je Feature-Kombination.
| Prüfung | Ergebnis | |
|---|---|---|
| Rust-Tests auf dem Host, Standard-Features | 672 bestanden / 0 fehlgeschlagen | bestanden |
| Rust-Tests auf dem Host, alle Features | 700 bestanden / 0 fehlgeschlagen | bestanden |
| Container-Lauf, Rust | 754 bestanden / 0 fehlgeschlagen / 2 ignoriert | bestanden |
| C-Laufzeit / Python / Go race | 15 / 10 / gesamtes Paket | bestanden |
| Frontend-Build, Web-Smoke-Test | 24 Prüfungen | bestanden |
| Echter FUSE-T-Teil-Mount, Finder-Durchsicht | Cache 54.288 → 54.288 B | bestanden |
| Abnahmematrix der Anforderungen | R01–R62 auf Tests abgebildet | erledigt |
Das Passwort kommt aus CIPHERFS_PASSWORD oder einer interaktiven Abfrage. S3-Zugangsdaten werden aus Umgebungsvariablen gelesen und nie in den gemeinsamen Index geschrieben.
cipherfs init --path ~/vault cipherfs put --vault ~/vault --source ./notes.txt --target docs/notes.txt cipherfs store add directory --vault ~/vault --dir ~/Library/CloudStorage/Dropbox/cfs cipherfs sync directory --vault ~/vault --store-dir ~/Library/CloudStorage/Dropbox/cfs cipherfs role set partial --vault ~/vault --read-cache-bytes 2147483648 cipherfs pin add --vault ~/vault --path docs cipherfs mount --vault ~/vault --mount-point ~/CipherFS --background cipherfs devices list --vault ~/vault cipherfs safe-to-remove --vault ~/vault cipherfs history --vault ~/vault --path docs/notes.txt cipherfs export --vault ~/vault --target ~/plain-copy --history
Rust-Anwendungen verwenden SyncedVault: put, put_from_reader, get, get_to_writer, get_range, delete, list. Ein erfolgreiches Schreiben bedeutet, dass die Daten lokal dauerhaft gespeichert sind; eine Hintergrundaufgabe übernimmt Synchronisation, Wiederverbindung und Wiederholungen. Der Speicherbedarf hängt nicht von der Objektgröße ab.
| Zweck | Algorithmus |
|---|---|
| Inhalts-AEAD | XChaCha20-Poly1305 (optional AES-256-GCM, ChaCha20-Poly1305) |
| Blockbildung | FastCDC, min/avg/max 1 / 4 / 8 MiB, Einheit höchstens 16 MiB |
| Inhaltsadressierung | BLAKE3 |
| Geräteidentität | ed25519-Signaturen, X25519-Verpackung, zugleich P2P-Knoten-ID |
| Lokales Passwort | Argon2id verpackt lokales Schlüsselmaterial; wird nie synchronisiert |
| Transport | QUIC (Iroh); HTTPS zu Speichern nach Bedarf |