Debut du chantier des depots prives (docs/depots-prives-conception.md). La face reseau
publie genome: {depot, cle_lecture} ; P95 exige que la cle soit connue de la flotte, et
l'armement refuse une voute qui en remettrait une autre. make forge-cles enregistre
chaque cle en lecture seule sur le seul depot que la face nomme, retire une cle
perimee, ne touche jamais celle du runner du site. Flux SSH vers la forge du site
depuis les seuls runners des locataires (paire runners_locataires).
Rien n'est encore applique sur le terrain ; les depots restent publics.
95 preuves.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7.8 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. Rien n'est changé tant que les décisions D1 à D3 ne sont pas prises.
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).
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
| 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 |
compte les dépôts de l'organisation authentifié, sinon elle ne verrait plus que les deux publics |
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.