george-claudeandClaude Opus 5.5 50e0e9e258 🔒️ build-push construit et scanne sur toute référence, PR comprise ; il ne publie que sur develop et les tags (raggaroth-factory/RF_CICD#7)
Demande de Benjamin, 2026-10-08 : « il faut que le scan se fasse au build
pour empêcher le build ». Jusqu'ici, le scan ne tournait que dans la
publication, après la fusion : une PR n'était jamais scannée, et une
dépendance vulnérable passait la revue.

- Toute référence : construction + scan bloquant. Seules develop et
  vX.Y.Z publient ; une PR, une autre branche ou main s'arrêtent après le
  scan, sous un tag local « controle-<sha> » jamais poussé.
- Identifiants du registre facultatifs : lus et exigés seulement si la
  référence publie. Une PR ne se connecte pas au registre.
- REGISTRY_AUTH_FILE n'est exporté que pour publier : pointé sur un
  fichier absent, il faisait échouer buildah jusque dans l'export local
  vers le scan (constaté au banc, « credential file is not accessible »).
- Sortie « publie » ; « tags » vide quand rien n'est publié.

Banc, 2026-10-08, les deux étapes extraites du YAML et enchaînées :
  A. PR, sans identifiants, saine      → code 0, registre vide
  B. PR, sans identifiants, vulnérable → code 1, image refusée
  C. develop, identifiants             → :dev et :<sha> publiés
  D. develop, sans identifiants        → code 1, erreur explicite
  E. main                              → code 0, rien publié

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VyxLNGHojdXeRMQgWFgzRV
2026-10-08 13:20:09 +02:00

RF_ACTIONS

Actions Gitea partagées par les projets de Raggaroth Factory.

Ce dépôt est public parce qu'il doit l'être : act_runner télécharge les actions appelées par uses: sans s'authentifier, et un dépôt privé lui répond « repository not found ». Il ne contient donc que le code des actions — rien qui décrive l'infrastructure qui les exécute. Cette description, les décisions et la procédure d'installation du runner vivent dans RF_CICD, qui reste privé.

Règle qui en découle : rien de propre à une machine, un compte ou un chemin de l'infrastructure n'entre ici. Et aucun secret, jamais — ils arrivent par les entrées des actions, depuis les secrets du dépôt appelant.

build-push

Construit une image avec buildah, sans démon ni socket, la passe au scan de vulnérabilités bloquant, puis — sur develop ou un tag vX.Y.Z seulement — la publie dans le registre de Gitea. Ne déploie rien.

L'image est construite et scannée sur toute référence, PR comprise : une image vulnérable fait échouer le pipeline avant la fusion, pas après. Le job qui l'appelle tourne donc sur chaque événement, juste après les tests :

  image:
    needs: tests
    runs-on: docker
    steps:
      - uses: actions/checkout@<empreinte de commit> # vX.Y.Z
      - uses: https://gitea.raggaroth-factory.fr/public/RF_ACTIONS/build-push@v1.0.0
        with:
          image: gitea.raggaroth-factory.fr/raggaroth-factory/<nom-de-l-image>
          dockerfile: Dockerfile
          context: .
          registry_user: ${{ secrets.REGISTRY_USER }}
          registry_password: ${{ secrets.REGISTRY_PASSWORD }}
Référence Construction + scan Publication
poussée sur develop oui :dev et :<sha court, 12 caractères>
tag vX.Y.Z (ou vX.Y.Z-rc.1) oui :vX.Y.Z, orthographié comme le tag git, et rien d'autre
PR, autre branche, main oui rien

Les identifiants du registre ne sont lus que si la référence publie : une PR ne se connecte pas au registre. Ils sont exigés dans ce cas, et leur absence est une erreur explicite.

Sorties : publie (true / false), tags (les tags publiés, vide sinon) et digest (l'empreinte sha256:… de l'image publiée).

Scan de vulnérabilités bloquant. Entre la construction et la publication, Trivy examine l'image. Une CVE HIGH ou CRITICAL pour laquelle un correctif existe fait échouer le job : rien n'est publié. Les autres — dont les CVE sans correctif, contre lesquelles personne ne peut rien — sont rapportées dans le journal sans bloquer. Le seuil n'est pas une entrée de l'action : un dépôt ne peut pas l'abaisser pour lui seul.

Une CVE acceptée sciemment va dans .trivyignore.yaml, à la racine du dépôt appelant. Chaque entrée porte une justification et une date d'expiration ; sans l'une ou l'autre, l'action refuse le fichier. À l'échéance, Trivy cesse d'appliquer l'exception et la CVE bloque de nouveau.

vulnerabilities:
  - id: CVE-2026-93990
    statement: libexpat de l'image nginx ; correctif attendu dans la prochaine base
    expired_at: 2026-11-15

Le plus souvent, la correction est une ligne dans le Dockerfile — mettre à jour les paquets de la base (apk upgrade --no-cache, apt-get upgrade) — plutôt qu'une exception.

Exigences : l'image du conteneur de job doit porter buildah et trivy. L'action construit avec --storage-driver vfs --isolation chroot, ce qui fonctionne dans un conteneur non privilégié, sans capacité ajoutée ni /dev/fuse. Les FROM des Dockerfiles construits doivent être des noms complets (docker.io/library/nginx:alpine, pas nginx:alpine) : buildah n'a pas de registre de recherche par défaut, et sa table d'alias est incomplète.

Toujours uses: en URL complète : la forme courte public/RF_ACTIONS/… serait résolue contre le serveur d'actions par défaut de l'instance, qui n'est pas forcément celle-ci.

S
Description
No description provided
Readme
49 KiB