Ferry
Open source · Apache-2.0 Pré-version Aucun serveur, jamais

Arrêtez de coller vos fichiers .env dans Slack.

Ferry est un canal privé entre des machines que votre équipe reconnaît déjà — appairées une fois, vérifiées par une phrase lue à voix haute, disponibles ensuite en permanence. Envoyez un fichier, un secret ou un message directement d'une machine à une autre : pas de cloud, pas de compte, pas de serveur au milieu, et rien qui traîne pour toujours dans un historique de chat cherchable. Les secrets portent un TTL et se détruisent à la première ouverture ; chaque échange atterrit dans un journal d'audit sans contenu à la place.

Ce n'est ni une messagerie ni AirDrop. C'est le canal pour ce qui ne devrait être ni dans l'un ni dans l'autre — identifiants, clés, tout ce qui a une date d'expiration.

Gratuit et open source, Apache-2.0. Un démon, trois portes d'entrée : la ligne de commande ferry, une extension VS Code, et une application de bureau.

 # machine A ferry send laptop-b ./build/app.tar.gz ferry send laptop-b ./.env --burn # disparaît dès qu'ils l'ouvrent 
Télécharger l'application de bureau Comment ça marche Lire le code source
316 Docker pulls 19 GitHub release downloads

Logiciel en pré-version

Le format de transport et le format sur disque changent encore, et rien n'a fait l'objet d'un audit de sécurité externe. Jouez avec, n'en dépendez pas — et n'y faites pas passer quoi que ce soit que vous seriez fâché de perdre ou de divulguer. La compatibilité entre versions n'est pas promise avant la 1.0.

Pourquoi

Slack a une excellente recherche. C'est bien le problème.

Un drive cloud, un pastebin, Slack, un e-mail — le secret atterrit sur le disque d'un tiers, se fait indexer, se fait sauvegarder, et n'est plus qu'à une fuite, un export ou une recherche un peu trop poussée d'être trouvé par quelqu'un qui n'aurait jamais dû le voir. Ferry ne fait rien de tout ça. La donnée quitte votre machine et arrive sur la leur, et c'est tout le trajet. Il n'y a aucun serveur à pirater, aucun historique de canal à purger, rien à réquisitionner.

Le compromis est réel

Ferry ne fonctionne que si les deux machines peuvent réellement se joindre — le même réseau de bureau, un partage de connexion, un VPN. Il n'y a pas de relais et il n'y en aura jamais, donc il ne traversera pas Internet pour vous. Si c'est ce qu'il vous faut, Ferry n'est pas l'outil.

Réponses franches

Ce qu'il ne fera pas

Comment ça marche

Une sécurité qu'on peut montrer du doigt

Une clé d'identité par machine

Créée au premier lancement du démon, jamais écrite sur disque en clair. Gardée dans le trousseau de l'OS, ou dans un fichier chiffré avec age sur une machine sans interface.

L'appairage est une cérémonie délibérée

Quelqu'un lit un code court à voix haute ; puis les deux personnes confirment que la même phrase de vérification s'affiche sur les deux écrans. Jamais sauté, jamais « oui » par défaut, jamais contourné par « faire confiance à ce réseau ».

Le handshake raccroche au nez des inconnus

Chaque connexion démarre par un handshake Noise qui rejette toute clé absente de votre roster — avant de lire une seule commande. Appliqué dans le transport, jamais seulement dans l'interface.

Scellé avec age, détruit pour de vrai

Les fichiers sont scellés avec age. Les secrets reçoivent en plus leur propre clé jetable, et « détruire à la lecture » broie la clé enveloppée, puis le chiffré, puis la ligne — une destruction interrompue laisse un chiffré inouvrable, jamais un orphelin ouvrable.

L'expiration tourne sur l'horloge du destinataire

Le TTL et la destruction à la lecture sont mesurés sur l'horloge monotone du destinataire à partir de la livraison — jamais sur un horodatage fourni par l'expéditeur. Si les horloges divergent après un redémarrage, l'élément expire.

Le journal d'audit est sans contenu

Il consigne qu'il s'est passé quelque chose, qui, quel élément, quand, et le résultat — et rien sur ce qu'il contenait.

Le modèle de sécurité complet →

Trois surfaces

Un démon local, trois façons de l'atteindre

Le démon est la seule chose qui parle le protocole pair-à-pair. Tout ce que vous touchez lui parle par un socket local et jamais directement à une autre machine.

Ligne de commande

Les binaires ferry et ferry-daemon. ferry send, ferry receive, ferry pair, ferry activity — n'importe quelle commande démarre elle-même le démon au premier usage, sauf ferry status, qui ne fait jamais que dire la vérité.

Extension VS Code

Apporte son propre démon — rien d'autre à installer. Une barre latérale et un panneau complet, la même appli : appairage, boîte de réception, panneau d'envoi et compositeur de secrets, le tout dans l'éditeur.

Application de bureau

Une coque Tauri autour de la même interface, pour les machines sans éditeur dans la boucle. Le démon est embarqué dans l'installeur comme son propre sidecar — rien à lancer séparément.

L'appairage vit dans la CLI, pas dans le démon sans tête — il faut un humain pour lire une phrase de vérification à voix haute, et une étape qui exige structurellement une personne ne peut pas vivre dans un processus qui structurellement ne peut en joindre aucune.

L'interface

La CLI, l'extension et l'application de bureau affichent la même interface

Une seule app React, trois hôtes. Montrée ici avec des données fictives.

Ferry — la fenêtre d'appairage d'un appareil
L'appairage est une fenêtre qu'on ne peut pas contourner d'un clic. Un code hors bande, puis une phrase de vérification que les deux personnes confirment sur leur propre écran — jamais sautée, jamais « oui » par défaut.
Ferry — l'écran Pairs / Roster avec empreintes et joignabilité
Le roster : les machines avec lesquelles vous vous êtes appairé, par empreinte de clé, avec la dernière fois où chacune était joignable. Tout ce qui n'y est pas est refusé au handshake.
Ferry — l'écran d'envoi avec le récapitulatif de transaction
Envoyer un fichier, un secret ou un court message à un pair. Le récapitulatif indique le TTL, si l'élément est détruit à la première ouverture, et qu'il est scellé avec age sur un transport Noise XK.
Ferry — la boîte de réception avec un secret en attente d'acceptation
Ce qui est arrivé. Un secret est proposé, pas imposé — vous l'acceptez ou le refusez avant qu'il soit écrit quelque part.
Ferry — le journal d'activité d'événements d'audit sans contenu
Le journal d'activité : quoi, qui, quel élément, quand, et le résultat — y compris une demande d'auth refusée et un élément de file expiré — et rien sur ce qu'il contenait.
Ferry — un fil de discussion avec un pair appairé
De courtes notes avec un pair, en fil de discussion et livrées comme tout le reste — sur la même connexion appairée et chiffrée avec Noise, pas un back-end de chat séparé.
Ferry — Paramètres, l'identité de cet appareil et l'état d'exécution du démon
Cet appareil : l'empreinte d'identité, la politique d'acceptation automatique, la langue, et l'état d'exécution du démon lui-même — port d'écoute, répertoire de données, santé de la découverte et du transport — tout lu depuis le même socket local que tout le reste utilise.

Opt-in

GitHub est opt-in, et reste éteint si vous ne l'activez jamais

Par défaut, Ferry ne fait aucun appel réseau à part un transfert direct vers un pair. Deux fonctions peuvent parler à l'API de GitHub — et seulement après que vous ayez mis remote_features_enabled = true et connecté un compte. Rien ne part vers GitHub avant ça, Ferry ne bascule jamais vers GitHub de lui-même, et le laisser éteint ne vous coûte que ces deux fonctions.

Publier (vers l'API gist de GitHub)

Vous choisissez, élément par élément, de déposer une copie déjà scellée sur GitHub en gist privé et de donner le lien à quelqu'un — pour quand vous ne pouvez pas être sur le même réseau. Le compromis est réel : le chiffré quitte votre machine, la destruction à la lecture ne peut plus être honorée, et GitHub apprend la clé publique du destinataire et la taille du fichier.

Roster d'équipe (depuis une URL que vous choisissez)

Pointez Ferry vers un fichier de dépôt — n'importe quelle URL que vous contrôlez. Il récupère le roster signé, vous montre qui l'a signé et le diff exact des ajouts/retraits, et n'importe que sur une seconde confirmation.

Chaque échange avec GitHub est un choix que vous faites pour cette action précise. Aucune synchro en arrière-plan, aucune télémétrie, aucun envoi automatique.

Architecture

Le compilateur possède le découpage en couches

Huit crates Rust dans un seul workspace Cargo. Les dépendances ne pointent jamais que dans un sens, donc une violation est une erreur de build, pas une habitude de revue de code.

direction des dépendances

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

Types, enums et codes d'erreur. Zéro logique. Les bindings TypeScript en sont générés ; la CI échoue sur tout diff.

crates/core

Chaque décision de domaine. Pilotable depuis le démon, la CLI, ou un harnais de test à faux réseau sans changement — ne mentionne jamais un socket, une base de données, ni React.

crates/net · store · crypto

La mécanique : framing et transport, SQLite, les primitives auditées.

crates/daemon · cli

Câblent le tout et rien d'autre.

crates/remote

La seule crate qui sait que HTTP existe — derrière les fonctions GitHub désactivées par défaut.

Comment se mesure « terminé »

Rien ne compte tant que ce n'est pas passé sur deux vraies machines

Ferry tient un registre de vérification : une ligne par flux visible par l'utilisateur, et une ligne n'est verte qu'une fois le flux exécuté de bout en bout sur deux vraies machines sur un vrai réseau, y compris une déconnexion et une reconnexion quand ça compte. Le code qui compile, les tests unitaires qui passent, et le harnais à deux nœuds qui passe méritent tous une note inférieure — ils renseignent sur la machine à états, pas sur un partage de connexion avec un portable en veille dessus.

Un vrai cycle appairer → envoyer → détruire → ouvrir fonctionne aujourd'hui entre deux démons sur un même hôte, et entre deux conteneurs sur un réseau multicast en CI. Le passage sur deux machines physiques et un audit de sécurité externe restent à faire. C'est pour ça que c'est une pré-version, et c'est dit ici plutôt que découvert plus tard.

350+ tests Rust · harnais à deux nœuds en mémoire · run CI à deux conteneurs · builds Windows + macOS

Se le procurer

Un seul pipeline de release, cinq façons de l'obtenir

Chaque canal ci-dessous sort de la même release taguée. Choisissez celui qui vous convient — téléchargez une archive, tirez une image, ou compilez vous-même.

Ligne de commande

.tar.gz (Linux/macOS) ou .zip (Windows) avec ferry + ferry-daemon dedans, bit exécutable intact. Extrayez, posez sur votre PATH.

Releases →

Docker

docker pull ghcr.io/firaslamouchi21/ferry, miroir sur Docker Hub. CLI et interface dans une seule image, aucune toolchain Rust ou Node.

Voir l'image →

Application de bureau

.deb / .AppImage / .rpm sur Linux, .dmg sur macOS, .msi / un .exe d'installation sur Windows — le démon est embarqué dedans. Non signé pour l'instant ; voyez ce que ça implique.

Notes de version & sommes de contrôle →

Extension VS Code

Pas encore sur le Marketplace — prenez le .vsix de votre plateforme dans la release et code --install-extension ferry-.vsix. Apporte son propre démon.

Releases →

compiler depuis les sources

 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 

ou la commande unique : ./dev.sh compile le démon + la CLI et ouvre l'interface contre eux, sans Docker ni jonglage de terminaux.

Un premier lancement

Depuis le terminal, du début à la fin

 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 écrit juste l'élément dans une file locale ; le démon le livre la prochaine fois que l'autre machine est là. Une machine sans tête — un runner CI, un NAS — garde son identité dans un fichier chiffré et se fait appairer depuis un portable avant d'être déployée.

Contribuer

Un changement brut qui respecte les invariants se merge facilement

Il y a une courte liste de choses sur lesquelles Ferry ne cédera pas — jamais de serveur, roster appliqué au handshake, appairage toujours un code plus une phrase confirmée, un état réel sur chaque élément, journal d'audit sans contenu, crypto uniquement à partir de primitives revues. Un changement qui en casse une discrètement est renvoyé, aussi utile soit-il ; tout le reste est bienvenu.

Apache-2.0, et aussi vendu en builds packagés — les contributions entrent aux mêmes conditions, avec une attestation DCO (git commit -s).

Contact

Parler de Ferry avec Firas

Un bug, une idée, une inquiétude de sécurité, ou l'envie d'aider à faire avancer Ferry vers la v2 — ça arrive directement dans la boîte de Firas et vous recevrez un accusé automatique. Pour les vulnérabilités, utilisez l'adresse du fichier SECURITY.md plutôt que ce formulaire.