Files
RF_ACTIONS/README.md
T
george-claudeandClaude Opus 5.5 e6a5fd6252 🔒️ build-push refuse de publier une image qui porte une CVE HIGH ou CRITICAL corrigeable (raggaroth-factory/RF_CICD#7)
Entre la construction et la publication, Trivy examine l'image, exportée
en répertoire OCI : pas de démon, et rien n'est publié avant le verdict.

Seuil décidé par Benjamin le 2026-10-07 : HIGH et CRITICAL corrigeables
bloquent ; le reste est rapporté sans bloquer. Le seuil n'est pas une
entrée : un dépôt ne l'abaisse pas pour lui seul. Exceptions dans
.trivyignore.yaml, chacune avec « statement » et « expired_at » —
vérifiés par l'action, faute de quoi elle refuse le fichier.

Banc du 2026-10-07, Ubuntu 24.04 non privilégié, buildah 1.33.7, trivy
0.75.0 vérifié par empreinte, registre jetable :
  1. frontend actuel          → bloqué (libexpat, pcre2 HIGH corrigeables)
  2. + apk upgrade            → publié
  3. + exceptions futures     → publié
  4. + exceptions expirées    → bloqué
  5. exception sans date      → refusé à la validation

Constaté en route : « trivy --input » refuse une archive OCI ; il veut
l'archive Docker ou le répertoire OCI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VyxLNGHojdXeRMQgWFgzRV
2026-10-07 22:15:54 +02:00

73 lines
3.2 KiB
Markdown

# 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, et la publie dans
le registre de Gitea sous les tags de sa filière. **Ne déploie rien.**
```yaml
- uses: https://gitea.raggaroth-factory.fr/public/RF_ACTIONS/build-push@main
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 }}
```
| Déclencheur | Tags publiés |
|---|---|
| poussée sur `develop` | `:dev` et `:<sha court, 12 caractères>` |
| tag `vX.Y.Z` (ou `vX.Y.Z-rc.1`) | `:vX.Y.Z`, orthographié comme le tag git, et rien d'autre |
| toute autre référence | **échec**, sans rien construire |
Sorties : `tags` (les tags publiés) 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.
```yaml
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.