
Mon CI ouvre ses propres PR de sécurité
Une faille de sécu, ce n’est jamais un projet. C’est dix.
J’ai des dizaines d’applis en production. Et toutes, à un moment, partagent les mêmes briques : la même lib de requêtes HTTP, le même bundler, le même framework. Le ciment est commun.
Alors quand une CVE tombe sur une de ces libs, je sais déjà ce qui m’attend. Ce n’est pas un repo à corriger. C’est la moitié de mon parc.
Et le scénario est toujours le même. Cloner, lancer le scan, repérer la version vulnérable, bumper, resynchroniser le lockfile, vérifier que ça repasse au vert, ouvrir la PR, surveiller le CI, merger. Multiplié par cinq, par huit, par dix.
Une demi-journée. Pour zéro valeur ajoutée. Juste pour rester à la même place.
C’est ça le vrai coût de la sécu quand tu shippes à l’échelle d’une seule personne : pas la difficulté, la répétition.
Alors j’ai arrêté de le faire à la main
Ce matin, un de mes projets avait une dépendance vulnérable. Je ne l’ai pas appris par une alerte. Je l’ai appris par une Pull Request.
Déjà prête. Branche créée, version corrigée, lockfile resynchronisé, scan repassé au vert, message de commit propre. Je n’avais plus qu’à relire et cliquer sur « merge ».
Personne ne l’a écrite. C’est le CI qui s’est réparé tout seul.
Le principe est simple. Sur mes repos, le workflow de sécu tourne déjà : gitleaks pour les secrets, Trivy pour les dépendances vulnérables, semgrep pour l’analyse statique. Il part sur chaque push, sur chaque PR, et par un cron quotidien à 5 h du matin, pendant que la forge est libre et que je dors.
La nouveauté, c’est ce qui se passe quand un de ces scans échoue. Au lieu de me pinger et d’attendre, le runner lance une session Claude Code en headless, avec une mission claire : identifie la faille, corrige, ouvre une PR.
L’outil qui détecte le problème le répare aussi. Et ce qui était une demi-journée de patch en série devient une pile de PR qui m’attendent au réveil.
Le prompt fait la moitié du boulot
C’est le truc qu’on ne voit pas dans les démos. Une session headless n’a personne à qui poser une question. Tout ce qu’un dev aurait deviné en dix secondes en ouvrant le repo, il faut le lui écrire à l’avance.
Alors mon prompt ne dit pas juste « corrige la faille ». Il décrit la stack du repo, et surtout ses pièges : ici c’est pnpm et pas npm ; les overrides vont dans pnpm-workspace.yaml, pas dans la clé pnpm du package.json qui est ignorée depuis pnpm 10 ; le Dockerfile s’appuie sur allowBuilds, on n’y touche pas ; et on reste dans le major courant de chaque paquet, pour ne pas troquer une CVE contre une breaking change.
Sans ce contexte, l’IA « corrige » et casse le build. Avec, elle repasse Trivy jusqu’au vert, resynchronise le lockfile, pousse la branche et ouvre la PR en listant les CVE traitées.
Le prompt dit aussi quand ne rien faire : si Trivy ne trouve finalement rien, parce que l’échec venait d’un autre job, elle explique ce qu’elle a vu et s’arrête. Une IA à qui on ne laisse pas le droit de ne rien faire finit par inventer un problème à résoudre.
Mais une IA qui ouvre des PR toute seule, ça se cadre
Sinon c’est exactement comme ça qu’on se plante.
- Anti-récursion. Le job ne se déclenche jamais sur une PR : il tourne sur
failure(), et seulement horspull_request. Sinon la PR de hotfix relance la sécu, qui échoue, qui ouvre une nouvelle PR, à l’infini. Une ligne de condition, mais sans elle c’est la boucle. - Idempotence. Avant de lancer l’IA, le workflow interroge l’API de la forge pour vérifier qu’aucune branche
hotfix/security-*n’a déjà sa PR ouverte. Sinon le cron quotidien me pose la même PR tous les matins. - Périmètre serré. Consigne explicite : touche UNIQUEMENT ce qui est nécessaire au fix, et un budget de tours limité. Pas de « tant que j’y suis, je refactore ».
- Et surtout : c’est moi qui merge. L’IA propose. Elle ne décide jamais. Le dernier mot reste humain, et la mise en prod aussi.
Ce que ça change vraiment
Le code d’un fix, je l’écris en deux minutes. Le gain n’a jamais été là.
Le gain, c’est de récupérer cette demi-journée. De ne plus payer la taxe de la répétition sur dix projets. De transformer « il faut que je patche tout mon parc » en « je relis dix PR et je merge ».
L’IA n’a pas remplacé ma vigilance. Elle a supprimé le travail sans valeur entre une faille et sa correction. Pour me laisser le seul truc qui compte vraiment : décider, et produire.
Un outil, ça se maîtrise. Et bien cadré, ça bosse pendant que tu dors.
Ce que ça demande pour tenir
Rien de tout ça n’est un coup de génie. C’est de la plomberie : un workflow, trois scans, un prompt qui connaît le repo, quatre garde-fous. Le mérite n’est pas dans l’IA, il est dans le cadre qu’on lui pose autour.
Et c’est précisément le travail qu’une démo ne montre jamais : pas faire marcher l’outil, le rendre sûr à laisser tourner sans surveillance.
Et toi, combien de temps tu perds à patcher la même faille sur plusieurs projets ? Si le sujet te parle, un échange de trente minutes suffit en général pour repérer ce qui mérite d’être confié à un CI qui se répare tout seul.