Mesure sur le terrain : chaque runner lit son depot en SSH avec sa cle de deploiement, et la forge lui refuse les autres, alors meme que les depots sont publics. Le role ne clone plus en HTTPS que les depots publics ; les depots instance, tenant et hebergeur passent en SSH, cle d'hote epinglee, commande SSH posee dans leur config git. Avant l'armement, le controleur les apporte en git bundle. La cle d'hote de la forge est declaree au plan du site et offerte par la fiche. genome_etat et genome_pousser lisent l'API authentifies ; la sonde genome-servi compte les publics ; forge_amorcer cree prives les depots des ecosystemes et du site. make forge-etancheite mesure le tout. Les depots restent publics. 95 preuves. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
9 KiB
Dépôts privés sur la forge du site — conception du chantier
Pour qui : le mainteneur qui décide de ce chantier puis le conduit, et quiconque se demande pourquoi un runner ne lit que ses propres dépôts.
Préparé le 2026-10-11. Décisions D1 à D3 prises le même jour par Daniel : les trois recommandations.
1. Le constat
Sur la forge du site, l'organisation genome porte cinq dépôts, tous publics :
| Dépôt | Contenu | Qui en a besoin |
|---|---|---|
set-ops-public |
le moteur | tous les runners |
set-ops-modeles |
les modèles génériques | le runner du site |
site-chezlepro |
la carte de la fabric, le plan du site | le runner du site |
ops-chezlepro |
le plan, l'inventaire et la face de Chezlepro | son runner, le runner du site |
ops-technolibre |
le plan, l'inventaire et la face de Technolibre | son runner, le runner du site |
Mesuré le 2026-10-11 : depuis le runner de Technolibre, git ls-remote sans identifiant lit la
tête de ops-chezlepro (b4fbd85) et de site-chezlepro (51dae24). Chaque locataire peut donc
lire le plan de l'autre, et la carte du site. Aucun n'en a besoin : chaque runner de locataire
ne clone que le moteur et son propre dépôt ; ce que le site lui donne arrive par la fiche déposée
dans son dépôt.
D'où ça vient : le 2026-09-12, à la première reconstruction du site, les dépôts créés privés ont
cassé le clonage anonyme des runners. Ils sont passés publics, avec l'argument que seuls ceux
qui ont franchi la frontière joignent la forge (scripts/forge_amorcer.py). Les autres locataires
en font partie.
2. La cible
- Publics :
set-ops-publicetset-ops-modeles. Ils sont génériques, identiques pour tous. - Privés :
site-chezleproet chaqueops-<locataire>. - Le runner du site lit et pousse tous les dépôts avec sa clé, déjà enregistrée comme clé de
déploiement en écriture par
genome_pousser.yml. Mesuré le 2026-10-11 : il lit les cinq dépôts en SSH, avec une vérification stricte de la clé d'hôte. Rien à créer pour lui. - Le runner d'un locataire lit son seul dépôt, avec une clé de déploiement en lecture
seule : la clé publique de son runner, déjà déclarée au plan (
ssh_baseline_cles_admin) et dont la privée lui est remise à l'armement depuis sa voûte (vault_runner_cle_ssh). - Aucun secret ne change de main. Le locataire publie la clé publique de son runner dans sa
face réseau ; le site l'enregistre sur le dépôt de ce locataire, avec ses propres
identifiants d'administration de la forge (
vault_forgejo_admin, déjà dans sa voûte).
Éprouvé le 2026-10-11 (étape 1)
Clés de lecture enregistrées par make forge-cles, flux posé sur site-forge-01 et à la
frontière. Depuis chaque runner, git ls-remote en SSH, clé d'hôte de la forge épinglée (lue
sur sa machine par l'accès d'administration) :
| Depuis | son dépôt | l'autre locataire | site-chezlepro |
set-ops-public |
|---|---|---|---|---|
| runner de Technolibre | lu (0172dd8) |
refusé | refusé | refusé |
| runner de Chezlepro | lu (74d5567) |
refusé | refusé | refusé |
Le refus vient de la forge (« Deploy Key … is not authorized to read »), alors que les dépôts sont encore publics : une clé de déploiement ne vaut que pour le dépôt qui l'a enregistrée. Conséquence : le moteur, public, continue de se cloner en HTTPS sans identifiant ; seuls les dépôts privés passent par SSH.
3. Le nœud : l'insémination
Le site amorce le runner d'un locataire avant que celui-ci ait reçu sa clé stable (elle
arrive à l'armement, geste humain, après). Pendant l'insémination, le rôle serveur_ops clone
pourtant le dépôt du locataire : avec un dépôt privé, ce clonage échoue. Même chose au premier
déploiement du runner du site, dont la clé est neuve.
Remède proposé : le colis. Quand un runner ne peut pas encore lire un dépôt privé, le
contrôleur qui joue serveur_ops (le runner du site pendant l'insémination, le poste
ailleurs) lui apporte ce dépôt en git bundle. Le mécanisme existe déjà : genome_colis.py porte
le génome du poste au runner du site. Le runner clone le colis, puis pointe origin vers l'URL
SSH de la forge. Ses tirages suivants passent par sa clé, une fois armé.
4. Les décisions à prendre
D1 — Comment le runner d'un locataire lit-il son dépôt ?
- Clé de déploiement en SSH (recommandé). Le runner continue de tirer lui-même ; il garde son
autonomie (émancipation,
makelancé sur le runner, gardeverifier_genome_a_jour). Coût : un flux nouveau, du runner de chaque locataire vers la forge du site, en SSH. - Colis seulement. Aucun flux nouveau, aucune clé de déploiement pour les locataires : le contrôleur apporte toujours le dépôt. Mais le runner ne tire plus son dépôt lui-même, et sa garde de génome n'a plus de forge à laquelle se comparer.
D2 — Sur quelle écoute SSH ?
- Le
sshdde la machine, port 22 (recommandé pour commencer). Le runner du site et le poste l'utilisent déjà pour pousser ; l'utilisateurgity est contraint par la forge. Le flux n'ouvre que les adresses des runners de locataires, pas leurs supernets. - Le serveur SSH intégré de Forgejo, sur un port dédié. Il n'expose pas le
sshdde la machine, mais sa cohabitation avec lesshdexistant reste à éprouver avant de s'y fier.
D3 — La preuve. Ce chantier touche l'insémination : je propose de le prouver par une reconstruction complète de Technolibre (raser, créer, inséminer, armer, monter), dépôts privés, avant de reprendre le lot 3b.
5. Ce qui change dans le code
État au 2026-10-11 : tout ce tableau est écrit, sauf la bascule elle-même. La clé d'hôte de
la forge est déclarée dans le plan du site (forge_ssh_cle_hote), offerte par la fiche
(serveur_ops_forge_cle_hote) et copiée par chaque locataire. Le moteur reste cloné en HTTPS.
| Pièce | Changement |
|---|---|
serveur_ops_depots |
un drapeau prive: true sur les dépôts instance, tenant et hebergeur |
roles/serveur_ops |
URL SSH et clé du runner pour les dépôts privés ; colis du contrôleur quand le runner ne peut pas encore les lire ; clé d'hôte de la forge épinglée |
contexte.py (face) |
la face publie la clé publique de lecture du runner (genome.cle_lecture) |
contexte.py (fiche) |
la fiche du site publie la clé d'hôte SSH de sa forge, que le runner du locataire épingle |
nouvelle cible forge-cles |
le site enregistre, d'après les faces, la clé de lecture de chaque locataire sur son dépôt, et retire celles qui ne sont plus publiées |
forge_amorcer.py |
crée les dépôts privés comme privés |
| flux | serveur_forge_site : entrée SSH depuis les runners des locataires hébergés (paire nouvelle, résolue depuis les faces) ; serveur_ops : sortie correspondante |
genome_etat.yml |
lit la forge par SSH ou authentifié : l'API anonyme répondrait 404 pour un dépôt privé |
sonde-genome-servi |
ne compte plus que les dépôts publics (au moins le moteur) : c'est ce qu'un écosystème neuf clone sans rien détenir ; les privés sont suivis par genome-etat, forge-cles et les runners |
Inchangés : sonde-genome-a-jour (son repère ne compare que set-ops-public), le poste (il
pousse déjà en SSH), la console (etat_forge lit origin, qui deviendra l'URL SSH).
6. Les preuves à écrire
- Hors ligne (
make prouver) : chaque dépôtinstance,tenantouhebergeurest déclaré privé ; chaque face publie une clé de lecture, et cette clé est dansssh_baseline_cles_admin. - Sur le terrain (
make forge-etancheite), avec témoins :- sans identifiant, un dépôt privé refuse et un dépôt public répond ;
- le runner d'un locataire lit son dépôt et ne lit pas celui de l'autre ;
- les clés de déploiement de chaque dépôt sont exactement : runner du site en écriture, runner du locataire en lecture.
- Par reconstruction : D3.
7. L'ordre de bascule
Chaque étape se vérifie avant la suivante, et la bascule se défait d'un appel par dépôt (repasser public).
- Éprouver sur la forge du site, sans rien basculer : enregistrer la clé de lecture du
runner de Technolibre sur
ops-technolibre, ouvrir le flux pour ce seul runner, et mesurer qu'il lit son dépôt en SSH. - Construire le code et les preuves (§5, §6) ;
make verifier. - Déployer sans basculer : flux et frontière (
make frontiere-appliquer CONFIRMER=true, lancé par Daniel), clés de déploiement, remotes SSH sur les trois runners. Les dépôts sont encore publics : chaque runner doit déjà tirer en SSH. - Basculer
site-chezlepro,ops-chezleproetops-technolibreen privé. Mesurer avecmake forge-etancheite, puis la veille des trois consoles. - Prouver par la reconstruction de Technolibre (D3).
- Reprendre le lot 3b : les demandes vivent alors dans le dépôt de chaque locataire, lisibles par lui et par le site seulement.