Gitfed
bastien-mrq/gitfed / FEDERATION.md
FEDERATION.md Code Preview
# 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
GOPRIVATE=git.neuromancer.ovh/* go install git.neuromancer.ovh/bastien-mrq/gitfed/cmd/gitfed-renew-cert@latest
```

`GOPRIVATE` dit à l'outil `go` de sauter le proxy public
(`proxy.golang.org`) et la base de sommes de contrôle pour ce chemin —
nécessaire pour tout module auto-hébergé, pas seulement celui-ci. Pour ne
plus avoir à le préciser à chaque fois : `go env -w GOPRIVATE=git.neuromancer.ovh/*`.

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.