Add FEDERATION.md: practical guide to a real cross-instance grant
Step by step, using the Thomas scenario as the worked example: prerequisites (they need their own instance, not an account on yours), granting access, the trust-approval step that's easy to miss and was the actual root cause behind a real "Permission denied (publickey)" report, getting a certificate via gitfed-renew-cert (now installable directly, see the previous commit), and automating renewal. Linked from both READMEs and back-linked from HOW_IT_WORKS as the practical counterpart to its conceptual model.
5 files changed
+134 −2
A
FEDERATION.md
+126 −0
M
README.fr.md
+1 −0
M
README.md
+1 −0
M
docs/HOW_IT_WORKS.en.md
+3 −1
M
docs/HOW_IT_WORKS.md
+3 −1
FEDERATION.md
@@ -0,0 +1,126 @@
+# Faire fonctionner la fédération entre deux instances
+
+Guide pratique pour donner accès à un dépôt de ton instance à quelqu'un
+qui a **sa propre instance gitfed ailleurs**, étape par étape, avec les
+pièges les plus courants. Pour le modèle complet (certificats, CA,
+confiance) expliqué en détail, voir
+[`docs/HOW_IT_WORKS.md`](docs/HOW_IT_WORKS.md) — ce document-ci est le
+"comment faire", pas le "pourquoi c'est sûr".
+
+## Le principe en une phrase
+
+Chaque instance a sa propre autorité de certification. Pour donner accès
+à quelqu'un d'une autre instance, tu n'as jamais besoin de connaître sa
+clé SSH ni de lui créer un compte — tu fais confiance à *son instance*,
+qui vérifie que c'est bien lui et signe un certificat de courte durée
+pour le prouver.
+
+## Prérequis
+
+- **Toi** : une instance gitfed qui tourne (la tienne), avec le dépôt à
+ partager.
+- **La personne à qui tu donnes accès** : sa **propre** instance gitfed
+ qui tourne quelque part (voir [`INSTALL.md`](INSTALL.md) si elle n'en a
+ pas encore), avec un compte + une clé SSH enregistrée **sur son
+ instance à elle**, pas sur la tienne.
+
+Si cette personne n'a pas et ne veut pas gérer sa propre instance, la
+fédération n'est pas le bon outil — crée-lui plutôt un compte local
+directement sur ton instance (Admin → Utilisateurs), plus simple pour ce
+cas-là.
+
+## Étape par étape
+
+Exemple avec Thomas, qui a son instance sur `thomas.exemple`.
+
+### 1. Thomas doit avoir un compte + une clé sur *son* instance
+
+Pas sur la tienne. Voir la section "Bootstrap du premier compte" de
+[`deploy/k8s/README.md`](deploy/k8s/README.md) ou [`INSTALL.md`](INSTALL.md)
+s'il vient de l'installer.
+
+### 2. Tu accordes l'accès sur ton dépôt
+
+Depuis **Paramètres du dépôt → Collaborateurs**, avec le principal
+complet — `thomas@thomas.exemple`, pas juste `thomas`.
+
+### 3. Approuve la confiance envers son instance — l'étape qu'on oublie
+
+Accorder l'accès à un domaine que ton instance ne connaît pas encore
+déclenche automatiquement une demande de confiance, mais **elle reste en
+attente tant que tu ne l'approuves pas toi-même** :
+
+1. Va sur **Admin → Trust store** (un badge apparaît dans la barre de
+ navigation tant qu'une confiance est en attente, depuis la v1.2.5).
+2. Approuve `thomas.exemple`.
+
+Tant que ce n'est pas fait, Thomas aura un simple
+`Permission denied (publickey)` en essayant de cloner — rien dans le
+message ne pointe vers cette étape, c'est le piège le plus courant.
+
+### 4. Thomas obtient un certificat depuis *son* instance
+
+Le nom d'utilisateur dans l'URL SSH n'a aucune importance — seule la clé
+ou le certificat présenté compte. Thomas installe l'outil de
+renouvellement (build direct, sans cloner le dépôt) :
+
+```sh
+go install git.neuromancer.ovh/bastien-mrq/gitfed/cmd/gitfed-renew-cert@main
+```
+
+Puis récupère la clé d'hôte de **sa propre** instance et demande un
+premier certificat :
+
+```sh
+ssh-keyscan -p 2222 thomas.exemple 2>/dev/null | cut -d' ' -f2-
+gitfed-renew-cert \
+ -host thomas.exemple:2222 \
+ -key ~/.ssh/id_ed25519 \
+ -host-key "ssh-ed25519 AAAA...(la clé récupérée ci-dessus)"
+```
+
+Ça écrit `~/.ssh/id_ed25519-cert.pub` — OpenSSH le présente ensuite
+automatiquement à chaque connexion SSH.
+
+### 5. Thomas automatise le renouvellement (recommandé)
+
+Le certificat est volontairement de courte durée (24-48h selon la config
+de son instance) — sans automatisation, il devra relancer la commande
+manuellement avant chaque expiration. Un timer réglé une fois pour
+toutes règle le problème : voir l'exemple systemd/launchd donné en
+réponse à "il faut installer quoi côté client" dans l'historique de ce
+projet, ou demande-le si besoin.
+
+### 6. Thomas clone
+
+```sh
+git clone ssh://git@git.neuromancer.ovh:2222/<toi>/<dépôt>.git
+```
+
+## Dépannage
+
+- **`Permission denied (publickey)`** — dans l'ordre le plus probable :
+ 1. Le domaine de Thomas est toujours en attente dans Admin → Trust
+ store (voir étape 3) — la cause la plus fréquente.
+ 2. Thomas n'a pas encore de certificat valide (étape 4), ou celui
+ qu'il a a expiré (pas de timer, voir étape 5).
+ 3. Le principal accordé à l'étape 2 ne correspond pas exactement au
+ domaine réel de l'instance de Thomas (faute de frappe, sous-domaine
+ différent, etc.).
+ 4. Thomas n'a pas de compte/clé sur *sa propre* instance (étape 1) —
+ sans ça, aucun certificat ne peut jamais lui être délivré.
+- **La confiance n'apparaît jamais dans Trust store** — vérifie que le
+ domaine saisi à l'étape 2 sert bien un `/.well-known/gitfed.json`
+ valide (`curl https://thomas.exemple/.well-known/gitfed.json`) ; sans
+ ça, l'octroi échoue immédiatement avec une erreur explicite plutôt que
+ de créer une entrée en attente.
+
+## Politique de confiance
+
+Par défaut (`trust_policy: "whitelist"` dans la config de ton instance),
+chaque nouveau domaine reste en attente jusqu'à approbation manuelle —
+c'est le comportement décrit ci-dessus. Une politique `"auto-trust"`
+existe (confiance immédiate à la première rencontre, façon SSH TOFU) mais
+n'est pas recommandée au-delà d'un usage perso/test : elle retire le seul
+point de contrôle qu'un admin a sur qui peut potentiellement accéder à
+son instance.
README.fr.md
@@ -63,6 +63,7 @@ instance en fonctionnement.
| Doc | Contenu |
|---|---|
| [`INSTALL.md`](INSTALL.md) | Installation étape par étape sur un VPS tout neuf, d'une machine vide jusqu'à une instance qui tourne — sans supposer k3s/cert-manager déjà en place. |
+| [`FEDERATION.md`](FEDERATION.md) | Comment faire fonctionner la fédération pour de vrai : prérequis, octroi d'accès, l'étape d'approbation de confiance qu'on oublie facilement, et obtention d'un certificat. |
| [`docs/HOW_IT_WORKS.md`](docs/HOW_IT_WORKS.md) | Le modèle de fédération/identité de bout en bout : certificats, magasin de confiance, ACL, un vrai push détaillé étape par étape. |
| [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) | Comment le code est organisé : les quatre binaires, les paquets `internal/`, pourquoi il existe un socket RPC d'administration, la topologie Kubernetes. |
| [`docs/security/AUDIT.md`](docs/security/AUDIT.md) | L'audit de sécurité pré-production et ce qui en a été corrigé. |
README.md
@@ -59,6 +59,7 @@ instance.
| Doc | What's in it |
|---|---|
| [`INSTALL.md`](INSTALL.md) *(French)* | Step-by-step install on a brand new VPS, from an empty machine to a working instance — no k3s/cert-manager assumed already set up. |
+| [`FEDERATION.md`](FEDERATION.md) *(French)* | How to actually get two instances collaborating: prerequisites, granting access, the trust-approval step that's easy to miss, and getting a certificate. |
| [`docs/HOW_IT_WORKS.en.md`](docs/HOW_IT_WORKS.en.md) | The federation/identity model end to end: certificates, trust store, ACLs, a real push walked through step by step. |
| [`docs/ARCHITECTURE.en.md`](docs/ARCHITECTURE.en.md) | How the code is organized: the four binaries, the `internal/` packages, why there's an admin RPC socket, the Kubernetes topology. |
| [`docs/security/AUDIT.md`](docs/security/AUDIT.md) *(French)* | The pre-production security audit and what was fixed as a result. |
docs/HOW_IT_WORKS.en.md
@@ -6,7 +6,9 @@ This document explains gitfed's central mechanism: how two instances that
have never met can let their users collaborate without a shared account
ever existing between them. For the bigger picture (files, code,
deployment), see the [README](../README.md); for the detail of each Go
-package, see [`ARCHITECTURE.en.md`](ARCHITECTURE.en.md).
+package, see [`ARCHITECTURE.en.md`](ARCHITECTURE.en.md); for the practical
+how-to (setting up a real federated collaboration step by step), see
+[`../FEDERATION.md`](../FEDERATION.md) *(French)*.
---
docs/HOW_IT_WORKS.md
@@ -6,7 +6,9 @@ Ce document explique le mécanisme central de gitfed : comment deux instances
qui ne se connaissent pas peuvent laisser leurs utilisateurs collaborer sans
qu'aucun compte ne soit jamais partagé entre elles. Pour le contexte plus
large (fichiers, code, déploiement), voir le [README](../README.fr.md) ; pour
-le détail de chaque paquet Go, voir [`ARCHITECTURE.md`](ARCHITECTURE.md).
+le détail de chaque paquet Go, voir [`ARCHITECTURE.md`](ARCHITECTURE.md) ;
+pour le mode d'emploi pratique (mettre en place une vraie collaboration
+fédérée étape par étape), voir [`../FEDERATION.md`](../FEDERATION.md).
---