Dans la liste des fichiers qu’un agent de GitHub Agentic Workflows ne peut pas modifier sans revue humaine, on trouve package.json, go.mod, Gemfile.lock et pyproject.toml. On n’y trouve ni composer.json ni composer.lock. Le 28 octobre, GitHub a rendu ce produit disponible pour tous les plans, Free compris : des agents de code qui tournent dans GitHub Actions pour trier des tickets, analyser une CI en échec ou écrire des tests. L’architecture est sérieuse, et je pense qu’elle mérite d’être essayée sur une base de code qui a quelques années. Mais ses réglages par défaut sont pensés pour npm, Go et Python, et la détection de menaces avertit sans bloquer. Sur un dépôt PHP, trois réglages doivent précéder le premier lancement.
Ce que GitHub a rendu disponible le 28 octobre
Le principe est d’écrire un workflow en Markdown : un frontmatter qui déclare les déclencheurs, les permissions et ce que l’agent a le droit de produire, puis des instructions en langage naturel. La commande gh aw compile transforme ce fichier en un .lock.yml classique, que l’on commite à côté de la source et qu’Actions exécute. Le moteur par défaut est Copilot CLI, qui demande une licence Copilot ; Claude, Codex et Gemini sont possibles avec leur propre clé, rangée dans un secret du dépôt.
Le changelog du 28 octobre ajoute deux points utiles pour une équipe : les workflows réutilisent les groupes de runners et les règles d’Actions déjà en place, runners auto-hébergés compris, et gh aw forecast estime la dépense en crédits IA, détection de menaces comprise. Le dépôt githubnext/agentics fournit des workflows prêts à l’emploi ; le plus parlant pour un legacy est « CI Doctor », qui se déclenche quand le workflow CI échoue sur main, lit les journaux, classe la cause (code, dépendance, configuration, runner, test instable) et ouvre un ticket ou commente un ticket existant.
Pour une application PHP dont la CI casse une semaine sur deux pour des raisons que personne n’a le temps d’élucider, c’est exactement le genre de tâche que je confie volontiers à un agent : lire des journaux, recouper des commits, proposer un diagnostic qu’un humain valide.
Une architecture qui sépare la lecture de l’écriture
Ce qui m’a convaincu de regarder de près, c’est la page d’architecture. L’agent tourne avec un GITHUB_TOKEN en lecture seule, dans un conteneur Docker (ou une micro-VM sur les runners éligibles). Il ne modifie rien lui-même : il produit des demandes structurées, les « safe outputs », que des jobs séparés exécutent après lui avec des permissions limitées à chaque action, issues: write pour un commentaire, contents: write et pull-requests: write pour une PR. La documentation résume : même un agent entièrement compromis ne peut pas modifier directement l’état du dépôt.
Autour, trois couches complètent le dispositif. Un pare-feu, l’Agent Workflow Firewall, fait passer le trafic HTTP de l’agent par un proxy Squid qui n’autorise que les domaines déclarés. Chaque sortie a un plafond (max), par défaut une seule PR par exécution. Enfin, un job de détection relit le patch et les sorties de l’agent avec un modèle dédié avant que quoi que ce soit ne soit appliqué.
Le pare-feu connaît l’écosystème PHP : l’identifiant php ouvre packagist.org et getcomposer.org. Sans bloc network, seul defaults s’applique (certificats, miroirs de paquets Ubuntu, schémas JSON). Les archives de nombreux paquets Composer sont servies par GitHub : au premier passage, lisez les refus du pare-feu dans les journaux plutôt que d’ouvrir large d’emblée.
composer.json n’est pas un fichier protégé
La protection contre les attaques de chaîne d’approvisionnement repose sur une liste de fichiers. Quand une PR ou un push de l’agent touche l’un d’eux, le comportement par défaut (request-review) crée quand même la PR mais pose une revue REQUEST_CHANGES qui exige une approbation humaine. La liste couvre les fichiers d’instructions des agents (AGENTS.md, CLAUDE.md), tout .github/, les dossiers cachés à la racine, CODEOWNERS, et les manifestes de dépendances, définis runtime par runtime dans le code du compilateur.
J’ai vérifié directement dans ce code, sur la branche principale de github/gh-aw :
$ URL=https://raw.githubusercontent.com/github/gh-aw/main/pkg/workflow/runtime_definitions.go
$ curl -s "$URL" | grep -c -i -E 'composer|cargo'
0
$ curl -s "$URL" | grep -o 'ManifestFiles: *\[\]string{[^}]*}' | sed 's/ManifestFiles: *\[\]string//'
{"package.json", "bun.lockb", "bunfig.toml"}
{"deno.json", "deno.jsonc", "deno.lock"}
{"global.json", "NuGet.Config", "Directory.Packages.props"}
{"mix.exs", "mix.lock"}
{"go.mod", "go.sum"}
{"stack.yaml", "stack.yaml.lock"}
{"pom.xml", "build.gradle", "build.gradle.kts", "settings.gradle", "settings.gradle.kts", "gradle.properties"}
{"package.json", "package-lock.json", "yarn.lock", "pnpm-lock.yaml", "npm-shrinkwrap.json"}
{"requirements.txt", "Pipfile", "Pipfile.lock", "pyproject.toml", "setup.py", "setup.cfg"}
{"Gemfile", "Gemfile.lock"}
{"pyproject.toml", "uv.lock"}
Ces commandes ont été exécutées le 2 novembre 2026 (commit f37d3b9 de github/gh-aw). Onze runtimes déclarent leurs manifestes, PHP n’en fait pas partie, Rust non plus. Une PR de l’agent qui modifie composer.json est donc traitée comme une PR qui modifie un contrôleur.
Sur un projet PHP qui a dix ans, ce fichier n’est pas anodin. Il contient des blocs scripts (post-install-cmd, post-update-cmd) qui exécutent des commandes shell à chaque composer install de la CI, avec les secrets du job de déploiement à portée. Il contient souvent des repositories de type vcs ou package déclarés à la main pour un fork ou un paquet interne. Une ligne ajoutée à l’un de ces blocs, par erreur ou par injection de consigne via un ticket ou un journal, s’exécutera au prochain build. C’est précisément le scénario que la liste protège pour package.json.
La détection de menaces avertit, elle ne bloque pas
Deuxième réglage à connaître : le job de détection tourne par défaut en mode avertissement (continue-on-error: true). S’il trouve une menace, ou s’il échoue lui-même (panne du fournisseur, modèle retiré, réponse illisible), les sorties « révisables » comme une PR ou un commentaire sont quand même créées, avec un bloc d’avertissement, un libellé et une revue REQUEST_CHANGES sur la PR. La documentation est honnête sur deux points que je retiens : un échec du détecteur signifie que l’évaluation est incomplète, pas que la sortie est saine ; et un libellé n’est pas une barrière d’approbation, seule la protection de branche du dépôt l’est.
Troisième point, plus discret : la page d’architecture rappelle qu’un GITHUB_TOKEN en lecture seule ne retire pas les autres identifiants. Les étapes personnalisées (steps, post-steps, jobs ajoutés) sont du code de confiance qui ne tourne pas dans le bac à sable de l’agent. Si vous recopiez dans le workflow agentique l’étape « préparer l’environnement » de votre CI historique, avec son COMPOSER_AUTH ou sa clé de dépôt privé, elle s’exécute hors du pare-feu, et la clé ne dépend plus que de ce que l’agent arrive à lire du système de fichiers.
Une configuration de départ pour un dépôt PHP
Voici le frontmatter que je poserais pour un premier workflow de diagnostic de CI, en partant de CI Doctor. Il reste en lecture partout, ouvre seulement l’écosystème PHP, bloque l’application des sorties si la détection lève une alerte, et restreint une éventuelle PR de correctif au code et aux tests :
---
description: Analyse les échecs de la CI sur main et propose un diagnostic
on:
workflow_run:
workflows: ["CI"]
types: [completed]
branches: [main]
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
permissions:
actions: read
contents: read
issues: read
pull-requests: read
network:
allowed:
- defaults
- php
safe-outputs:
threat-detection:
continue-on-error: false
add-comment:
create-pull-request:
allowed-files:
- src/**
- tests/**
protected-files: blocked
timeout-minutes: 10
max-ai-credits: 300
---
allowed-files est une liste blanche exclusive : tout fichier hors de src/ et tests/ fait échouer la sortie, composer.json, composer.lock, Makefile et phpunit.xml.dist compris. C’est le contournement le plus simple de l’absence de PHP dans la liste protégée, et il vaut mieux qu’une liste noire que l’on oubliera de compléter. protected-files: blocked transforme la revue imposée en refus net pour le reste. Pour un workflow dont le métier est justement de mettre à jour les dépendances, la bonne réponse n’est pas d’ouvrir allowed-files, mais d’en écrire un second, distinct, avec une revue obligatoire par la protection de branche.
Les limites
Cet article s’appuie sur l’annonce, la documentation et le code source de gh-aw au 2 novembre ; je n’ai pas fait tourner de workflow agentique sur un dépôt réel. La liste des manifestes est du code qui bouge vite : PHP et Rust peuvent y entrer à la prochaine version, et la documentation n’est pas tout à fait alignée sur le code (une page cite Rust parmi les runtimes protégés, le fichier source ne le contient pas). Relisez-la avant de vous en remettre aux réglages par défaut.
Le meilleur contre-argument est simple : si votre protection de branche exige déjà une revue humaine sur toute PR, la différence entre un fichier protégé et un fichier ordinaire se réduit à un signal visuel. C’est vrai, à condition que la revue lise vraiment le diff de composer.json d’une PR intitulée « Fix flaky test ». Sur les équipes réduites qui maintiennent un legacy, c’est rarement le cas, et c’est pour cela que je préfère un refus mécanique.
Reste le coût. Le budget par défaut est de 1 000 crédits IA par exécution pour l’agent et de 400 pour la détection, et un workflow déclenché à chaque échec de CI peut tourner souvent sur un projet instable. gh aw forecast existe pour cela : lancez-le avant d’activer le déclencheur.
Concrètement, par où commencer
- Relevez dans votre
composer.jsonles blocsscriptsetrepositories, et ce que la CI exécute à l’install: c’est la surface qu’un agent pourrait atteindre. - Partez de CI Doctor en lecture seule, avec des commentaires pour seule sortie, pendant deux ou trois semaines : vous saurez si ses diagnostics valent les crédits.
- Avant d’autoriser une PR, posez
allowed-filessur les dossiers de code et de tests, etcontinue-on-error: falsesur la détection. - Vérifiez que la protection de
mainexige une revue humaine, y compris pour les PR ouvertes par un bot. - N’importez aucune étape historique qui manipule un secret dans le workflow agentique ; si l’agent a besoin de dépendances privées, préparez-les dans un job séparé qui ne lui transmet que les fichiers.
Un agent qui lit vos journaux de CI à votre place est un vrai gain ; le jour où il écrit dans composer.json, la question n’est plus technique mais de gouvernance.
Sources
- GitHub Agentic Workflows generally available, GitHub Changelog, 28 octobre 2026
- Security Architecture, documentation GitHub Agentic Workflows, consultée le 2 novembre 2026
- Safe Outputs (Pull Requests), Protected Files et allowed-files, documentation GitHub Agentic Workflows, consultée le 2 novembre 2026
- Threat Detection, documentation GitHub Agentic Workflows, consultée le 2 novembre 2026
- Network Permissions, documentation GitHub Agentic Workflows, consultée le 2 novembre 2026
- runtime_definitions.go, dépôt github/gh-aw, commit f37d3b9, consulté le 2 novembre 2026
- CI Doctor, dépôt githubnext/agentics, consulté le 2 novembre 2026
Sur ce sujet, l’offre de l’atelier : Agents de code