Ferry
Open Source · Apache-2.0 Pre-Release Nie ein Server

Schluss damit, .env-Dateien in Slack zu posten.

Ferry ist ein privater Kanal zwischen Maschinen, denen euer Team schon vertraut — einmal gepaart, per laut vorgelesener Phrase verifiziert, danach immer verfügbar. Schickt eine Datei, ein Geheimnis oder eine Nachricht direkt von einer Maschine zur anderen: keine Cloud, kein Konto, kein Server dazwischen, und nichts, das für immer in einem durchsuchbaren Chat-Verlauf liegen bleibt. Geheimnisse tragen ein TTL und löschen sich nach dem ersten Öffnen; jeder Austausch landet stattdessen in einem inhaltsfreien Audit-Log.

Es ist weder eine Chat-App noch AirDrop. Es ist der Kanal für das, was in keinem von beiden sein sollte — Zugangsdaten, Schlüssel, alles mit einem Ablaufdatum.

Kostenlos und Open Source, Apache-2.0. Ein Daemon, drei Zugänge: die ferry-Kommandozeile, eine VS-Code-Erweiterung, und eine Desktop-App.

 # Maschine A ferry send laptop-b ./build/app.tar.gz ferry send laptop-b ./.env --burn # weg, sobald sie es öffnen 
Desktop-App herunterladen So funktioniert's Quellcode ansehen
316 Docker pulls 19 GitHub release downloads

Pre-Release-Software

Das Übertragungs- und das Speicherformat ändern sich noch, und nichts davon wurde bisher extern auf Sicherheit geprüft. Probiert es aus, verlasst euch nicht darauf — und schickt nichts damit, dessen Verlust oder Leck euch stören würde. Kompatibilität zwischen Versionen wird erst ab 1.0 zugesichert.

Wozu

Slack hat eine hervorragende Suche. Das ist das Problem.

Eine Cloud-Ablage, eine Paste-Seite, Slack, E-Mail — das Geheimnis landet auf der Festplatte eines Dritten, wird indexiert, gesichert, und ist nur ein Datenleck, einen Export oder eine etwas zu gründliche Suche davon entfernt, von jemandem gefunden zu werden, der es nie hätte sehen sollen. Ferry macht nichts davon. Die Daten verlassen eure Maschine und kommen bei der anderen an, und das ist die ganze Reise. Es gibt keinen Server, in den man einbrechen kann, keinen Kanalverlauf zu löschen, nichts vorzuladen.

Der Kompromiss ist real

Ferry funktioniert nur, wenn beide Maschinen sich tatsächlich erreichen können — dasselbe Büronetz, ein Handy-Hotspot, ein VPN. Es gibt kein Relay und wird nie eines geben, also bahnt es sich keinen Weg durchs Internet für euch. Wenn ihr das braucht, ist Ferry nicht das richtige Werkzeug.

Klare Antworten

Was es nicht tut

So funktioniert's

Sicherheit, auf die man zeigen kann

Ein Identitätsschlüssel pro Maschine

Beim ersten Start des Daemons erzeugt, nie im Klartext auf Platte geschrieben. Im OS-Schlüsselbund, oder in einer age-verschlüsselten Datei auf einer Maschine ohne Desktop.

Pairing ist eine bewusste Zeremonie

Jemand liest einen kurzen Code laut vor; dann bestätigen beide Personen, dass auf beiden Bildschirmen dieselbe Verifizierungsphrase steht. Nie übersprungen, nie standardmäßig bestätigt, nie durch „diesem Netzwerk vertrauen“ umgangen.

Der Handshake legt bei Fremden auf

Jede Verbindung beginnt mit einem Noise-Handshake, der jeden Schlüssel abweist, der nicht im Roster steht — bevor auch nur ein Befehl gelesen wird. Auf Transportebene durchgesetzt, nie nur im UI.

Versiegelt mit age, wirklich verbrannt

Dateien werden mit age versiegelt. Geheimnisse bekommen zusätzlich einen eigenen Wegwerfschlüssel, und „nach dem Lesen verbrennen“ zerstört den umhüllten Schlüssel, dann den Chiffretext, dann die Zeile — ein unterbrochener Burn hinterlässt unlesbaren Chiffretext, nie ein offenes Fragment.

Ablauf nach der Uhr des Empfängers

TTL und Burn-after-Read werden ab der Zustellung nach der monotonen Uhr des Empfängers gemessen — nie nach einem vom Absender gelieferten Zeitstempel. Stimmen die Uhren nach einem Neustart nicht überein, läuft das Element ab.

Das Audit-Log ist inhaltsfrei

Es hält fest, dass etwas passiert ist, wer, welches Element, wann, und mit welchem Ergebnis — und nichts über den Inhalt.

Das vollständige Sicherheitsmodell →

Drei Oberflächen

Ein lokaler Daemon, drei Wege dorthin

Der Daemon ist das Einzige, das das Peer-to-Peer-Protokoll spricht. Alles, was ihr anfasst, spricht mit ihm über einen lokalen Socket und nie direkt mit einer anderen Maschine.

Kommandozeile

Die Binaries ferry und ferry-daemon. ferry send, ferry receive, ferry pair, ferry activity — jeder Befehl startet den Daemon beim ersten Gebrauch selbst, außer ferry status, das immer nur die Wahrheit meldet.

VS-Code-Erweiterung

Bringt ihren eigenen Daemon mit — nichts weiter zu installieren. Eine Seitenleiste und ein volles Panel, dieselbe App: Pairing, ein Posteingang, das Sende-Panel und ein Geheimnis-Editor, alles im Editor.

Desktop-App

Eine Tauri-Hülle um dieselbe UI, für Maschinen ohne Editor im Spiel. Der Daemon steckt als eigenes Sidecar im Installer — nichts, was separat läuft.

Pairing lebt in der CLI, nicht im kopflosen Daemon — es braucht einen Menschen, der eine Verifizierungsphrase laut vorliest, und ein Schritt, der strukturell einen Menschen braucht, kann nicht in einem Prozess leben, der strukturell keinen erreichen kann.

Die Oberfläche

CLI, Erweiterung und Desktop-App zeigen dieselbe UI

Eine React-App, drei Hosts. Hier mit Beispieldaten gezeigt.

Ferry — der Dialog zum Pairing eines Geräts
Pairing ist ein Dialog, an dem man nicht vorbeiklicken kann. Ein Code außerhalb des Kanals, dann eine Verifizierungsphrase, die beide Personen auf ihrem eigenen Bildschirm bestätigen — nie übersprungen, nie standardmäßig bestätigt.
Ferry — der Bildschirm Peers / Roster mit Fingerabdrücken und Erreichbarkeit
Das Roster: die Maschinen, mit denen ihr gepairt seid, nach Schlüssel-Fingerabdruck, mit der letzten Erreichbarkeit. Alles, was nicht auf dieser Liste steht, wird beim Handshake abgewiesen.
Ferry — der Sende-Bildschirm mit der Transaktionsübersicht
Eine Datei, ein Geheimnis oder eine kurze Nachricht an einen Peer senden. Die Übersicht zeigt die TTL, ob es beim ersten Öffnen verbrennt, und dass es mit age über einen Noise-XK-Transport versiegelt ist.
Ferry — der Posteingang mit einem wartenden Geheimnis zur Annahme
Was angekommen ist. Ein Geheimnis wird angeboten, nicht aufgedrängt — ihr nehmt es an oder lehnt es ab, bevor es irgendwo geschrieben wird.
Ferry — das Aktivitätsprotokoll inhaltsfreier Audit-Ereignisse
Das Aktivitätsprotokoll: was passiert ist, wer, welches Element, wann, und mit welchem Ergebnis — einschließlich einer abgelehnten Auth-Anfrage und eines abgelaufenen Outbox-Elements — und nichts über den Inhalt.
Ferry — ein Nachrichtenverlauf mit einem gepairten Peer
Kurze Notizen mit einem Peer, als Verlauf zugestellt wie alles andere — über dieselbe gepairte, mit Noise verschlüsselte Verbindung, kein separates Chat-Backend.
Ferry — Einstellungen, die Identität dieses Geräts und der Laufzeitstatus des Daemons
Dieses Gerät: der Identitäts-Fingerabdruck, die Auto-Accept-Richtlinie, die Sprache, und die eigene Laufzeit des Daemons — Listen-Port, Datenverzeichnis, Discovery- und Transport-Zustand — alles über denselben lokalen Socket gelesen, den auch alles andere benutzt.

Opt-in

GitHub ist Opt-in, und bleibt aus, wenn ihr es nie aktiviert

Standardmäßig macht Ferry keinen Netzwerkaufruf außer einer direkten Übertragung an einen Peer. Zwei Funktionen können mit GitHubs API sprechen — und erst, nachdem ihr remote_features_enabled = true gesetzt und ein Konto verbunden habt. Vorher geht nichts an GitHub, Ferry fällt nie von selbst auf GitHub zurück, und es ausgeschaltet zu lassen kostet euch nur diese zwei Funktionen.

Veröffentlichen (über GitHubs Gist-API)

Ihr entscheidet, pro Element, eine bereits versiegelte Kopie als privates Gist auf GitHub abzulegen und jemandem den Link zu geben — für den Fall, dass ihr nicht ins selbe Netzwerk kommt. Der Kompromiss ist real: der Chiffretext verlässt eure Maschine, Burn-after-Read kann nicht mehr eingehalten werden, und GitHub erfährt den öffentlichen Schlüssel des Empfängers und die Dateigröße.

Team-Roster (von einer URL eurer Wahl)

Weist Ferry auf eine Repo-Datei — jede URL, die ihr kontrolliert. Es holt das signierte Roster, zeigt euch, wer es signiert hat, und das genaue Diff der Hinzufügungen/Entfernungen, und importiert erst nach einer zweiten Bestätigung.

Jeder Austausch mit GitHub ist eine Entscheidung, die ihr für genau diese eine Aktion trefft. Keine Hintergrundsynchronisation, keine Telemetrie, kein automatischer Upload.

Architektur

Der Compiler besitzt die Schichtung

Acht Rust-Crates in einem Cargo-Workspace. Abhängigkeiten zeigen immer nur in eine Richtung, also ist ein Verstoß ein Build-Fehler, keine Code-Review-Gewohnheit.

Abhängigkeitsrichtung

daemon / cli  →  core  →  net / store / crypto  →  proto
crates/proto

Typen, Enums und Fehlercodes. Keine Logik. Die TypeScript-Bindings werden hieraus generiert; die CI schlägt bei jedem Diff fehl.

crates/core

Jede Domänenentscheidung. Ohne Änderung vom Daemon, der CLI oder einem Test-Harness mit gefälschtem Netzwerk aus ansteuerbar — erwähnt nie einen Socket, eine Datenbank oder React.

crates/net · store · crypto

Die Maschinerie: Framing und Transport, SQLite, die geprüften Primitive.

crates/daemon · cli

Verdrahten alles und sonst nichts.

crates/remote

Die einzige Crate, die weiß, dass HTTP existiert — hinter den standardmäßig deaktivierten GitHub-Funktionen.

Wie „fertig“ gemessen wird

Nichts zählt, bis es auf zwei echten Maschinen gelaufen ist

Ferry führt ein Verifizierungsregister: eine Zeile pro nutzerseitigem Ablauf, und eine Zeile wird erst grün, wenn sie auf zwei echten Maschinen in einem echten Netzwerk durchlaufen wurde, einschließlich einer Trennung und Wiederverbindung, wo relevant. Code, der kompiliert, Unit-Tests, die durchlaufen, und das Zwei-Knoten-Harness, das durchläuft, verdienen alle eine niedrigere Note — sie sagen etwas über die Zustandsmaschine aus, nichts über einen Hotspot mit einem schlafenden Laptop dran.

Ein vollständiger Zyklus aus pairen → senden → verbrennen → öffnen läuft heute zwischen zwei Daemons auf einem Host, und zwischen zwei Containern in einem Multicast-Netzwerk in der CI. Jeder Ablauf wird so durchlaufen, bevor er als funktionierend gilt.

350+ Rust-Tests · Zwei-Knoten-Harness im Speicher · CI-Lauf mit zwei Containern · Builds für Windows + macOS

Beschaffung

Eine Release-Pipeline, fünf Wege, drankommen

Jeder Kanal unten kommt aus derselben getaggten Release. Wählt, was passt — eine Archivdatei laden, ein Image ziehen, oder selbst bauen.

Kommandozeile

.tar.gz (Linux/macOS) oder .zip (Windows) mit ferry + ferry-daemon drin, Ausführungsrecht intakt. Entpacken, auf den PATH legen.

Releases →

Docker

docker pull ghcr.io/firaslamouchi21/ferry, gespiegelt auf Docker Hub. CLI und UI in einem Image, keine Rust- oder Node-Toolchain nötig.

Image ansehen →

Desktop-App

.deb / .AppImage / .rpm unter Linux, .dmg unter macOS, .msi / ein Setup-.exe unter Windows — der Daemon steckt drin. Vorerst unsigniert; was das bedeutet.

Release-Notizen & Prüfsummen →

VS-Code-Erweiterung

Noch nicht im Marketplace — die .vsix eurer Plattform aus der Release nehmen und code --install-extension ferry-.vsix. Bringt ihren eigenen Daemon mit.

Releases →

aus dem Quellcode bauen

 git clone https://github.com/firaslamouchi21/Ferry cd Ferry cargo build --release -p ferry-daemon -p ferry cargo test --workspace bash testing/local-two-peer.sh 

oder die Einzeiler-Variante: ./dev.sh baut Daemon + CLI und öffnet die UI dagegen — ohne Docker, ohne mehrere Terminals.

Ein erster Durchlauf

Vom Terminal aus, von Anfang bis Ende

 ferry daemon start ferry pair listen --name laptop-a ferry pair connect 192.168.1.20:53124 482913 --name laptop-b ferry send laptop-b ./.env --burn ferry receive list ferry receive open <item-id> --out ./.env 

ferry send schreibt das Element nur in eine lokale Warteschlange; der Daemon liefert es aus, sobald die andere Maschine wieder da ist. Eine kopflose Maschine — ein CI-Runner, ein NAS — bewahrt ihre Identität in einer verschlüsselten Datei und wird vor dem Deployment von einem Laptop aus gepairt.

Mitwirken

Eine grobe Änderung, die die Invarianten respektiert, lässt sich leicht mergen

Es gibt eine kurze Liste von Dingen, bei denen Ferry nicht nachgibt — nie ein Server, Roster beim Handshake durchgesetzt, Pairing immer ein Code plus eine bestätigte Phrase, echter Zustand für jedes Element, inhaltsfreies Audit-Log, Kryptografie nur aus geprüften Primitiven. Eine Änderung, die eines davon still bricht, wird zurückgeschickt, egal wie nützlich sie ist; alles andere ist willkommen.

Apache-2.0, und auch als paketierte Builds verkauft — Beiträge kommen unter denselben Bedingungen herein, mit einer DCO-Bestätigung (git commit -s).

Contact

Mit Firas über Ferry sprechen

Ein Bug, eine Idee, ein Sicherheitsbedenken, oder ihr wollt helfen, Ferry Richtung v2 zu bringen — das geht direkt in Firas' Posteingang, und ihr bekommt eine automatische Bestätigung. Für Sicherheitslücken die Adresse in SECURITY.md statt dieses Formulars nutzen.