Le rôle dérive l'empreinte à chaud depuis l'autorité, parce qu'un from-zero
régénère l'AC avec une empreinte neuve. Figée en voûte, elle serait périmée
dès la première reconstruction — et une empreinte périmée fait échouer le
bootstrap de chaque hôte.
Or `defaults/main.yml` portait encore un défaut lisant
`vault_step_ca_fingerprint`. Ce défaut était mort : la tâche suivante écrase
le fait sans condition, donc la valeur de la voûte n'avait aucun effet.
Le recensement de voute.py s'y laissait prendre — il cherche la chaîne
`vault_*` sans pouvoir savoir qu'un défaut n'est jamais lu. La « source
unique » avait hérité de l'erreur, et le panneau réclamait un secret
impossible à fournir avant que l'AC n'existe.
Défaut retiré : la clé disparaît du recensement (25 -> 24 exigés), du
gabarit et du panneau. `client_pki_ca_fingerprint_override` reste le moyen
d'épingler une empreinte.
`docs/intrants-communs.md` §H était une troisième copie manuelle de la liste
des secrets, avec les deux mêmes erreurs ; elle renvoie maintenant à
`voute.py lister` et à la preuve P18.
Preuves : 24 OK, 0 échec ; voute.py verifier --strict passe.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Reconstruction complète prouvée (14 VM + sauvegardes + AC supprimées, puis
`make myDay` rebâtit tout ; `make valider` entièrement vert). Bugs corrigés :
- client_pki : empreinte du root CA dérivée dynamiquement de l'autorité
(au lieu d'une valeur figée en Vault) — une AC régénérée a une empreinte neuve.
- serveur_keycloak : assignation de rôle tolérante aux utilisateurs absents
(annuaire vide sur un from-zero).
- serveur_prometheus : ne scrute que les hôtes ACTIFS (client_metrique ∩ hotes_actifs).
- nftables résolu : compatible Docker — remplace la seule table setops_flux (pas de
flush ruleset, préserve les tables Docker) + forward autorise docker0/established.
Sans ça, forward policy drop coupait Collabora (conteneur).
Ajoute playbooks/proxmox/supprimer_vm_debian.yml (suppression par VMID, garde-fous).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Le garde 'creates:' sautait la ré-émission même quand les SAN voulus changeaient
(ex: nouvelle exposition -> client_pki_sans mis à jour). Contourné 3× à la main ce
soir. Corrigé : on lit les SAN du cert existant (openssl) et on ré-émet si le cert
est absent OU si un SAN voulu manque, puis on recharge les consommateurs
(client_pki_reload_services). Idempotent (SAN à jour -> sauté) + dérive détectée,
prouvés. ansible-lint production : 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- client_pki : root_ca.crt en 0644 (un cert racine est PUBLIC ; requis pour
que les clients TLS non-root — keycloak, forgejo… — puissent vérifier).
- serveur_keycloak : db-url-properties sslmode=verify-full + sslrootcert.
Incident maîtrisé : 1er essai, keycloak (user keycloak) ne pouvait pas lire
root_ca 0600 → SSO down → restauré en <1 min → corrigé (0644) → verify-full OK.
Prouvé : realm 200, sslmode=verify-full, aucune erreur SSL/DB.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bug latent de flotte : cert-renewer rechargeait un service nommé d'après le
cert (%i = FQDN, inexistant) au lieu du consommateur réel → nginx/postfix/
dovecot/slapd servaient l'ancien cert jusqu'à expiration. Symptôme : cert
edge périmé en mémoire → échec TLS OIDC → login SSO cassé.
Correctif : client_pki_reload_services (vrais consommateurs), par groupe.
Fix immédiat de l'incident : reload nginx sur l'edge.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
step ca certificate ne recevait aucun --san explicite. Ajout d'une liste
client_pki_sans (FQDN + nom court + IP) et d'une boucle --san dans la
commande. Le cert porte désormais DNS:fqdn, DNS:court, IP:adresse — avec
EKU Server+Client Auth, prêt pour un mTLS bidirectionnel. Vérifié sur
infra-dns-01 (ré-émission).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Les rôles à secrets déclaraient serveur_X_password: "" avec la variable
de voûte seulement en commentaire — aucun mapping réel. Remplir la voûte
ne branchait donc rien (secret vide → assertion échoue).
Les 12 secrets des 8 rôles pointent maintenant vers leur source :
serveur_X_password: "{{ vault_X | default('') }}"
Comportement inchangé si la voûte est vide ; branché dès qu'elle a le
secret. Prouvé : assertion step_ca passe avec vault_step_ca_password.
Chaque instance remplit ses vault_* ; aucun mapping par instance.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>