infra: fait confiance au CA local de Caddy pour l'envoi des artefacts SBOM #78

Merged
lenaic merged 3 commits from gabriel/77-confiance-caddy-ci into develop 2026-09-02 13:42:54 +00:00
Member

Ce que ça change

L'envoi des trois artefacts SBOM échouait systématiquement en CI (« unable to get local issuer certificate » contre le CA auto-signé de Caddy), masqué par continue-on-error. Comme le projet n'aura pas de nom de domaine public d'ici la fin, jamais de certificat ACME reconnu par un magasin de confiance standard : la chaîne récupère désormais le certificat de la forge à chaque exécution (poignée de main TLS, rien de figé dans le dépôt) et le passe à actions/upload-artifact via NODE_EXTRA_CA_CERTS.

Closes #77

Preuve

Non-régression du script de récupération, rejouée en local (serveur TLS jetable, ne dépend jamais de la forge) :

$ tests/ci/test-confiance-caddy.sh
ok     sans argument, échec attendu
ok     un certificat auto-signé récupéré et écrit
ok     le certificat récupéré porte le bon sujet
ok     port fermé, échec attendu, rien écrit

Récupération du CA Caddy : tous les cas d'essai passent.

Sur cette PR (commit 2a9ea0c), la première version cassait dependances-python (échec à 42s) et dependances-dashboard (échec à 11s) — trop rapide pour un blocage réseau, ce n'était pas le certificat mais ${{ github.server_url }}, un contexte jamais utilisé ailleurs dans ce dépôt et que rien ne garantissait peuplé par ce runner. Corrigé (e79bbb0) en adressant la forge en dur, comme partout ailleurs dans le dépôt (bin/fj, ce manuel).

Après correction, les 6 tâches de la chaîne sont vertes sur e79bbb0 :

success  Qualité du code Python                        15s
success  Tests unitaires et couverture                  11s
success  Dépendances du tableau de bord                  8s
success  Images épinglées par version                    3s
success  Aucun secret commité                            3s
success  Dépendances Python et inventaire applicatif  3m32s

dependances-python termine en 3m32s — comparable à la durée constatée quand l'envoi allait jusqu'au bout de la poignée de main TLS avant d'échouer sur le certificat (~3m35s sur la PR #56), cohérent avec un envoi qui va cette fois à son terme plutôt qu'un échec instantané. Je n'ai pas pu inspecter le journal détaillé de l'étape elle-même (API de la forge sans endpoint de logs exposé pour ce test) : un pair qui ouvre la page d'exécution peut confirmer l'absence de unable to get local issuer certificate et que les 3 artefacts sont bien listés en pièces jointes — à cocher dans la relecture.


Relecture

  • Un pair a relu et laissé un commentaire, même court
  • Ses remarques sont traitées, ou une réponse explique pourquoi elles ne le sont pas
  • Les 3 artefacts (sbom-applicatif, sbom-outillage, sbom-dashboard) sont bien téléchargeables depuis la page d'exécution de cette PR

Ce qui suit le code

  • docs/runbooks/ mis à jour, un geste d'exploitation a changé

Où regarder en priorité

  • .forgejo/scripts/confiance-caddy.mjs : première utilisation sans épinglage d'empreinte (confiance à la première connexion). Accepté parce que c'est le même réseau non chiffré que le runner utilise déjà pour joindre la forge — mérite un second avis si quelqu'un voit ça autrement.
  • continue-on-error: true est conservé sur les trois envois d'artefact, mais son commentaire change de sens : garde-fou général désormais, plus correctif du certificat.
  • L'adresse https://10.105.200.41 est en dur dans ci.yml (deux occurrences) plutôt que tirée d'un contexte Actions : ${{ github.server_url }} a cassé la première version de cette PR, voir « Preuve ».
  • Au passage, corrige une incohérence de numérotation : le commentaire ENF-11 sur l'inventaire SBOM était déjà dans le code avant cette PR (ci.yml, docs/runbooks/ci.md) — je m'y suis aligné dans le nouveau texte plutôt que d'introduire une troisième numérotation.
## Ce que ça change L'envoi des trois artefacts SBOM échouait systématiquement en CI (« unable to get local issuer certificate » contre le CA auto-signé de Caddy), masqué par `continue-on-error`. Comme le projet n'aura pas de nom de domaine public d'ici la fin, jamais de certificat ACME reconnu par un magasin de confiance standard : la chaîne récupère désormais le certificat de la forge à chaque exécution (poignée de main TLS, rien de figé dans le dépôt) et le passe à `actions/upload-artifact` via `NODE_EXTRA_CA_CERTS`. Closes #77 ## Preuve Non-régression du script de récupération, rejouée en local (serveur TLS jetable, ne dépend jamais de la forge) : ``` $ tests/ci/test-confiance-caddy.sh ok sans argument, échec attendu ok un certificat auto-signé récupéré et écrit ok le certificat récupéré porte le bon sujet ok port fermé, échec attendu, rien écrit Récupération du CA Caddy : tous les cas d'essai passent. ``` Sur cette PR (commit `2a9ea0c`), la première version cassait `dependances-python` (échec à 42s) et `dependances-dashboard` (échec à 11s) — trop rapide pour un blocage réseau, ce n'était pas le certificat mais `${{ github.server_url }}`, un contexte jamais utilisé ailleurs dans ce dépôt et que rien ne garantissait peuplé par ce runner. Corrigé (`e79bbb0`) en adressant la forge en dur, comme partout ailleurs dans le dépôt (`bin/fj`, ce manuel). Après correction, les 6 tâches de la chaîne sont vertes sur `e79bbb0` : ``` success Qualité du code Python 15s success Tests unitaires et couverture 11s success Dépendances du tableau de bord 8s success Images épinglées par version 3s success Aucun secret commité 3s success Dépendances Python et inventaire applicatif 3m32s ``` `dependances-python` termine en 3m32s — comparable à la durée constatée quand l'envoi allait jusqu'au bout de la poignée de main TLS avant d'échouer sur le certificat (~3m35s sur la PR #56), cohérent avec un envoi qui va cette fois à son terme plutôt qu'un échec instantané. Je n'ai pas pu inspecter le journal détaillé de l'étape elle-même (API de la forge sans endpoint de logs exposé pour ce test) : un pair qui ouvre la page d'exécution peut confirmer l'absence de `unable to get local issuer certificate` et que les 3 artefacts sont bien listés en pièces jointes — à cocher dans la relecture. ``` ``` ## Relecture - [ ] Un pair a relu et laissé un commentaire, même court - [ ] Ses remarques sont traitées, ou une réponse explique pourquoi elles ne le sont pas - [ ] Les 3 artefacts (`sbom-applicatif`, `sbom-outillage`, `sbom-dashboard`) sont bien téléchargeables depuis la page d'exécution de cette PR ## Ce qui suit le code - [x] `docs/runbooks/` mis à jour, un geste d'exploitation a changé ## Où regarder en priorité - `.forgejo/scripts/confiance-caddy.mjs` : première utilisation sans épinglage d'empreinte (confiance à la première connexion). Accepté parce que c'est le même réseau non chiffré que le runner utilise déjà pour joindre la forge — mérite un second avis si quelqu'un voit ça autrement. - `continue-on-error: true` est conservé sur les trois envois d'artefact, mais son commentaire change de sens : garde-fou général désormais, plus correctif du certificat. - L'adresse `https://10.105.200.41` est en dur dans `ci.yml` (deux occurrences) plutôt que tirée d'un contexte Actions : `${{ github.server_url }}` a cassé la première version de cette PR, voir « Preuve ». - Au passage, corrige une incohérence de numérotation : le commentaire ENF-11 sur l'inventaire SBOM était déjà dans le code avant cette PR (`ci.yml`, `docs/runbooks/ci.md`) — je m'y suis aligné dans le nouveau texte plutôt que d'introduire une troisième numérotation.
infra: fait confiance au CA local de Caddy pour l'envoi des artefacts SBOM
Some checks failed
Intégration / Qualité du code Python (pull_request) Successful in 13s
Intégration / Tests unitaires et couverture (pull_request) Successful in 11s
Intégration / Dépendances Python et inventaire applicatif (pull_request) Failing after 42s
Intégration / Dépendances du tableau de bord (pull_request) Failing after 11s
Intégration / Images épinglées par version (pull_request) Successful in 3s
Intégration / Aucun secret commité (pull_request) Successful in 3s
2a9ea0cc1a
L'envoi des trois artefacts SBOM échouait systématiquement en CI
(« unable to get local issuer certificate » contre le CA auto-signé de
Caddy), masqué par continue-on-error. Sans nom de domaine public
prévu d'ici la fin du projet, jamais de certificat ACME reconnu par un
magasin de confiance standard : on récupère donc la chaîne de
certificats à chaque exécution (le CA de Caddy tourne trop souvent
pour être figé dans le dépôt) et on la passe à
actions/upload-artifact via NODE_EXTRA_CA_CERTS.

Closes #77
gabriel self-assigned this 2026-09-02 09:49:10 +00:00
gabriel requested review from lenaic 2026-09-02 09:49:16 +00:00
infra: adresse la forge en dur dans confiance-caddy, pas github.server_url
All checks were successful
Intégration / Qualité du code Python (pull_request) Successful in 15s
Intégration / Tests unitaires et couverture (pull_request) Successful in 11s
Intégration / Dépendances du tableau de bord (pull_request) Successful in 8s
Intégration / Images épinglées par version (pull_request) Successful in 3s
Intégration / Aucun secret commité (pull_request) Successful in 3s
Intégration / Dépendances Python et inventaire applicatif (pull_request) Successful in 3m32s
e79bbb0a0a
Échec observé sur la PR #78 (11s et 42s, trop rapide pour un blocage
réseau) : ce dépôt n'a jamais utilisé ${{ github.server_url }} au-delà
de github.workflow/github.ref, et rien ne garantit que ce runner
Forgejo le peuple comme GitHub Actions. L'adresse de la forge est déjà
en dur partout ailleurs dans le dépôt (bin/fj, docs/runbooks/ci.md) :
même choix ici, plutôt qu'un contexte non éprouvé sur ce runner.
infra: épingle la racine Caddy plutôt que de la récupérer à chaque run
All checks were successful
Intégration / Qualité du code Python (pull_request) Successful in 11s
Intégration / Tests unitaires et couverture (pull_request) Successful in 11s
Intégration / Dépendances Python et inventaire applicatif (pull_request) Successful in 43s
Intégration / Dépendances du tableau de bord (pull_request) Successful in 7s
Intégration / Images épinglées par version (pull_request) Successful in 2s
Intégration / Aucun secret commité (pull_request) Successful in 2s
c82606224e
La version précédente (e79bbb0) rendait le job vert mais l'envoi des
artefacts échouait toujours (unable to get issuer certificate) :
une poignée de main TLS ne transmet jamais la racine d'une autorité,
seulement la feuille et l'intermédiaire — NODE_EXTRA_CA_CERTS ne
pouvait donc jamais fermer la chaîne de confiance avec cette approche.

Vérifié côté serveur (docker exec g2-forge-proxy) : contrairement à
l'intermédiaire (renoué chaque semaine) et à la feuille (12h), la
racine « Caddy Local Authority » est générée une fois et valable dix
ans. C'est elle qu'on épingle dans le dépôt (certificat public, pas
de clé privée) plutôt que de la traquer à l'exécution. Une étape
bloquante (pas de continue-on-error) vérifie qu'elle n'a pas expiré,
pour qu'une péremption future rougisse la chaîne au lieu de se
cacher derrière le garde-fou de l'envoi d'artefact.

Supprime .forgejo/scripts/confiance-caddy.mjs et son test, devenus
inutiles.

Voir #77
lenaic approved these changes 2026-09-02 13:42:48 +00:00
lenaic merged commit e3bff4e66e into develop 2026-09-02 13:42:54 +00:00
lenaic deleted branch gabriel/77-confiance-caddy-ci 2026-09-02 13:42:54 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
g2/enervision!78
No description provided.