La bordure devient un artefact dérivé, comme le devis switch — et le chemin
qui y mène est enfin déclaré.
`make devis-opnsense` (+ preuve P24) dérive la politique de bordure du
registre des flux : les flux `pair: externe`, que `resoudre_flux.py` saute
volontairement parce qu'ils relèvent de la frontière et non du pare-feu
d'hôte. Aucun port, aucune adresse, aucun nom d'hôte dans le générateur.
Le lien manquait dans tous les fichiers : le devis switch ne contenait pas
une seule `ip route`. Un réseau underlay portant `passerelle_sortie` le
déclare — il vit dans l'underlay et non dans un tenant parce que la
frontière route vers TOUS les supernets tenants par le même saut, donc il
ne peut dériver d'aucun `index`. `devis-reseau` en tire deux routes :
l'aller (sortie générale) et le retour vers l'administration, dont l'absence
a coûté la passe de déploiement du 2026-07-29 — la réponse revient au
pare-feu par une autre interface que celle où l'état a été créé, et se fait
jeter en silence.
Les réseaux d'administration viennent de l'intrant `nftables_admin_ssh` :
même source unique que la garde anti-lockout des nftables et l'alias
SETOPS_ADMIN. Les trois pare-feux et les routes ne peuvent plus diverger.
La frontière est réglable depuis la console (section « Frontière » du
panneau Intrants) ; les identifiants d'API restent interdits d'écriture par
le GUI et vivent dans la voûte.
Correctifs de la même passe :
- le panneau refusait d'enregistrer les intrants de la frontière : le
garde-fou confondait une référence de voûte `{{ vault_* }}` préservée
avec un secret soumis. Il regarde désormais la valeur, pas le nom.
- `supprimer_vm_debian.yml` ne chargeait que `proxmox.vault.yml` pour ses
secrets ; retirer ce reliquat aurait cassé `make detruire`. Aligné sur le
playbook de clonage, voûte unique en dernier.
- documentation : la voûte est unique, `proxmox.vault.yml` n'est qu'un
reliquat de compatibilité.
Preuves : 24 OK, 0 échec. Cas de rejet du validateur d'underlay exercés un
par un ; résolution du jeton Proxmox vérifiée en exécution réelle.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| affirmations.md | ||
| plan-de-recette.md | ||
| preuve-2026-07-20.md | ||
| preuve-2026-07-22.md | ||
| preuve-2026-07-23.md | ||
| preuve-2026-08-01.md | ||
| protocole-operateur-independant.md | ||
| README.md | ||
Audit de conformité — mode d'emploi
Ce dossier contient le dispositif qui garde Set-OPS honnête : il ne doit jamais affirmer plus que ce qu'il prouve.
Les pièces
| Fichier | Rôle |
|---|---|
affirmations.md |
Le registre : chaque affirmation publique du dépôt (README, AGENTS, QUICKSTART, docs, wiki, aide make, GUI) tracée vers une commande de preuve et un statut (✅/🟡/❌/⚪), plus le journal des traitements (ce qui a été corrigé, quand, comment). |
scripts/prouver.py |
Le harnais : un orchestrateur mince qui rejoue les preuves automatisables du registre en appelant l'outillage existant (les mêmes scripts que make verifier). Il ne réimplémente aucune validation. |
preuve-AAAA-MM-JJ.md |
La pièce justificative : le rapport horodaté produit par make prouver. Rejouable et présentable (audit, certification, revue). |
protocole-operateur-independant.md |
L'épreuve humaine : le protocole qui met AFF-002 (« exploitable sans IA ») à l'épreuve d'un sysadmin qui n'est pas l'auteur. Aucune commande locale ne peut prouver cette affirmation ; produit un rapport operateur-independant-AAAA-MM-JJ.md. |
Produire une preuve
make prouver
Cela exécute chaque preuve et écrit docs/audit/preuve-<date>.md. La commande sort en
erreur (rc≠0) si une preuve automatisable échoue — utilisable en garde-fou (CI locale,
pré-commit). Une preuve SAUTÉE (⚪) n'est pas un échec.
Prérequis Vault
La preuve P15 (inventaire Ansible complet, ansible-inventory --list) déchiffre le
group_vars de l'instance. Sans ANSIBLE_VAULT_PASSWORD_FILE, elle est automatiquement
sautée (⚪) avec la mention du prérequis — le reste du harnais reste vert, car les
validateurs Python lisent le plan et l'inventaire directement, sans secret. Pour l'inclure :
export ANSIBLE_VAULT_PASSWORD_FILE=~/.config/setops-vault-pass
make prouver
Ce que couvre make prouver
| # | Preuve | Ce qu'elle établit |
|---|---|---|
| P01 | Lint (ansible-lint) |
0 violation, profil production. |
| P02 | Tests unitaires | inventory_host — cas nominal + refus. |
| P03 | Diff-vide du plan | l'inventaire est généré depuis le plan (diff vide). |
| P04 | Groupes ↔ playbooks | chaque groupe opérationnel a son playbook homonyme. |
| P05 | Dépendances de groupes | graphe cohérent, aucune entrée orpheline. |
| P06 | Validateurs de registres | serveurs / applications / bases / domaines valides. |
| P07 | GUI | node --check du JS du GUI. |
| P08 | Orchestration | couches + graphe : aucun cycle, aucune arête en arrière. |
| P09 | Flux réseau | schéma + matrice d'audit cohérents. |
| P10 | Handlers ↔ notify | tout notify pointe vers un handler du même rôle. |
| P11 | Syntaxe | --syntax-check de tous les playbooks (via make syntaxe). |
| P12 | Runbooks cités | les fichiers docs/ référencés existent. |
| P13 | Invariants structurels | LICENSE, socle en forme dossier, pas de couches parallèles, SSH clé-only, nftables désactivé par défaut. |
| P14 | Chemins d'inventaire | aucun instance/inventories/lab/group_vars codé en dur. |
| P15 | Modèle public socle |
ses registres (domaines/serveurs/applications/bases) valident. |
| P16 | Inventaire Ansible (voûte) | ansible-inventory --list — sauté sans mot de passe Vault. |
| P17 | Tous les modèles d'instance | chaque modèle découvert valide (pas seulement socle). SETOPS_MODELES=../Set-OPS-Modeles inclut les modèles assemblés privés. |
| P18 | Gabarit de voûte complet | vault.yml.example couvre exactement les secrets que le plan exige (rôles actifs + bases + group_vars). |
| P19 | GUI couvre le plan | tout champ présent dans un plan réel est éditable par le GUI (nomenclature tolérée : le seed index est désormais un intrant ; l'adressage est dérivé, donc rien à éditer). |
| P20 | Adressage dérivé du seed | aucune nomenclature ne stocke d'adressage (supernet, sous-réseau, passerelle, VLAN) : tout se dérive du seul index. Attrape toute rechute vers l'écriture manuelle. |
| P21 | Fédération sans collision | aucune paire d'instances fédérées ne partage un index (mêmes VLAN/VMID sur le trunk). Le garde-fou du multi-instances ; vue avec make instances. |
| P22 | Plan de recette à jour | docs/audit/plan-de-recette.md (les 78 gestes manuels, générés des exercices du wiki) est à jour — il ne peut pas dériver du wiki. Régénérer : make plan-recette. |
| P23 | Underlay sans collision | la fabric physique (underlay.yml : mgmt/iSCSI/Ceph, cluster-global) n'empiète pas sur la plage tenant — VLAN < 1000 et sous-réseaux hors des supernets 10.(10+index).0.0/16. Sautée si underlay.yml absent. Vue : make underlay. |
P17, P18, P19 ferment les angles morts du harnais : il ne vérifiait qu'une instance et le seul modèle
socle. P17 aurait attrapé l'hôte fantôme d'integral; P18, les neuf secrets absents du gabarit Chezlepro ; P19, les champsliens/websocketque le GUI ne savait pas écrire. Chacune a une CLI dédiée (scripts/modeles.py,voute.py,couverture_gui.py) utilisable seule.
Le rapport relie chaque preuve aux affirmations qu'elle couvre (colonne « Affirmations »), et liste à part les déclarations d'intention (⚪ invérifiables localement : AFF-036, 091, 096, 007) — assumées comme intentions, jamais présentées comme prouvées.
Ajouter une preuve
- Ajouter (ou corriger) l'affirmation dans
affirmations.mdavec sa commande de preuve. - Ajouter une entrée à la liste
PREUVESdescripts/prouver.py: soit une ou plusieurs commandes (cmds, toutes doivent renvoyer 0), soit une fonction nativefuncrenvoyant(ok, détail)pour un invariant simple. Renseignerrefsavec les ID d'affirmations. - Ne pas réimplémenter de logique de validation : appeler l'outillage existant
(
scripts/*.py,ansible-lint, ciblesmake). Le harnais orchestre, il ne valide pas.
Rapport avec make verifier
make verifier inclut désormais les preuves : il enchaîne ses vérifications au fil de
l'eau (lint, tests, cohérence, syntaxe — arrêt au premier échec) puis termine par
python3 scripts/prouver.py --verifier — les preuves du registre sans écrire de rapport
(pour ne pas écraser la pièce justificative committée). Ainsi, make verifier échoue si une
preuve échoue.
make prouver (sans --verifier) reste le mode pièce justificative : il exécute tout,
horodate et écrit docs/audit/preuve-<date>.md. Les deux réutilisent le même
outillage. (Quelques vérifications se recouvrent entre les deux étapes — coût assumé : la
sortie détaillée de verifier est conservée, et prouver ajoute les preuves manquantes.)