Chapitre 7.3 — Garde-fous & sécurité
⏱️ TL;DR — Les hooks
PreToolUsebloquants sont ton filet dur : ils empêchent, mécaniquement, ce qui ne doit jamais arriver — éditer un fichier protégé (migrations,.env, fichiers générés), commiter/pusher surmain, lancer une commande destructrice, laisser fuir un secret. Combinés auxdeny-lists de permissions (5.3), ils rendent l’autonomie de l’agent sûre : même en confiance, l’agent ne peut pas franchir les lignes rouges. Un bon garde-fou explique en bloquant, pour que l’agent s’adapte.
🎯 Objectifs
- Poser des hooks bloquants pour les fichiers protégés.
- Empêcher les actions git dangereuses (commit/push sur main, force push).
- Bloquer les commandes destructrices et les fuites de secrets.
- Articuler hooks bloquants et
deny-lists de permissions.
Pourquoi des garde-fous durs
Les permissions (5.3) filtrent déjà beaucoup, mais un hook PreToolUse va plus loin : il est programmable (il peut inspecter quel fichier, quelle commande précise) et explique son refus à l’agent. C’est le rempart pour les cas où « une erreur est irréversible » : une migration écrasée, un .env commité, un push --force sur main. Ces choses-là ne doivent pas dépendre de la vigilance — ni la tienne, ni celle du modèle.
Protéger des fichiers
Certains fichiers ne doivent jamais être édités à la main par l’agent : les migrations déjà appliquées, les fichiers générés (types auto, build), les lockfiles, les secrets (.env). Un hook PreToolUse qui inspecte le chemin ciblé et refuse si c’est protégé :
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [{
"type": "command",
"command": "node .claude/hooks/protect-paths.mjs"
}]
}
]
}
}Le script protect-paths.mjs lit les infos de l’événement (le fichier visé), et sort en échec (avec un message) si le chemin matche une liste protégée (prisma/migrations/**, .env*, *.generated.*, pnpm-lock.yaml…). Le message revient à l’agent : « les migrations ne s’éditent pas à la main, génère-en une nouvelle ». Il apprend la règle au lieu de la subir.
💡 Réflexe d’architecte — Un garde-fou qui explique vaut dix fois un garde-fou muet. Fais toujours renvoyer par le hook un message qui dit pourquoi c’est bloqué et quoi faire à la place. L’agent s’aligne sur ta contrainte au lieu de se cogner au mur en boucle.
Empêcher les bêtises git
Deux classiques irréversibles : commiter/pusher sur main et le push --force. Un hook PreToolUse sur les commandes shell peut les intercepter :
Combiné à ta deny-list de permissions (5.3), tu as deux couches : la permission refuse les patterns évidents, le hook inspecte finement (la branche courante, le flag --force). Résultat : l’agent en autonomie ne peut pas casser ton historique.
Bloquer le destructeur et les fuites
- Commandes destructrices :
rm -rf, suppression de branches,DROP TABLE… →deny-list + hook qui inspecte la commande. - Fuites de secrets : un hook
PreToolUse(ou un scan sur les éditions) qui repère un motif de clé/API dans ce qui va être écrit ou commité, et bloque. Précieux pour éviter qu’un secret parte dans le repo.
⚠️ Piège — Croire que les garde-fous remplacent le filet de la Partie 5 (git propre, branche, tests). Non : ils le complètent. Les hooks empêchent les lignes rouges ; git + tests rattrapent les erreurs ordinaires. Autonomie sûre = garde-fous durs et filet de récupération. L’un sans l’autre laisse un trou.
L’articulation permissions ↔ hooks
deny-list de permissions | Hook PreToolUse | |
|---|---|---|
| Nature | filtre par pattern de commande | script qui inspecte le contexte |
| Force | simple, déclaratif | programmable (branche, contenu, chemin) |
| Message | refus générique | explication sur mesure |
| Idéal pour | interdits évidents (rm -rf) | règles fines (branche courante, secret, fichier protégé) |
On utilise les deux : la deny-list pour le grossier, le hook pour le fin et l’explicatif.
🧭 Sur TaskFlow — Garde-fous de TaskFlow (7.4) : hook qui protège
prisma/migrations/**et.env*, hook qui refuse commit/push surmain. Avec ça + les hooks de qualité (7.2) + le filet git/tests (P5), on peut élargir l’autonomie de l’agent sur les tâches mécaniques sans risque réel : il est formaté, testé, et ne peut franchir aucune ligne rouge.
✏️ Exercices
Exercice 1 — Liste tes lignes rouges. Écris les 5 choses que l’agent ne doit jamais faire sur ton projet (fichiers à ne pas toucher, commandes interdites, branche protégée). Pour chacune : deny-list, hook, ou les deux ?
✅ Solution
Typiquement : éditer les migrations/.env/générés → hook (inspection de chemin). push --force / commit sur main → hook (inspecte la branche/flag) + deny pour le pattern évident. rm -rf → deny + hook. La règle : deny pour le grossier, hook pour le fin et l’explicatif.
Exercice 2 — Le garde-fou qui explique. Mets en place UN hook bloquant (ex. protéger .env). Vérifie que, quand l’agent tente d’y toucher, il reçoit un message clair et s’adapte (au lieu de réessayer en boucle).
✅ Solution
Un bon hook renvoie « .env est protégé ; utilise des variables d’environnement / le fichier .env.example ». L’agent reformule son approche. Si ton hook bloque sans message, l’agent ne comprend pas et peut réessayer — d’où l’importance du message explicatif.
🧠 Quiz de révision
1. Pourquoi des hooks bloquants en plus des permissions ?
Parce qu’ils sont programmables (inspectent le chemin, la branche, le contenu) et expliquent leur refus. Pour les erreurs irréversibles (migration écrasée, .env commité, force push), on ne veut pas dépendre de la vigilance.
2. Quel événement pour un garde-fou, et pourquoi ?
PreToolUse : il se déclenche avant l’action et peut la refuser. C’est le seul moment où l’on peut empêcher une bêtise avant qu’elle se produise.
3. Pourquoi un garde-fou doit-il « expliquer » ?
Pour que l’agent comprenne pourquoi c’est bloqué et quoi faire à la place, et s’adapte — au lieu de se cogner au mur en boucle. Un refus muet est inefficace.
4. Les garde-fous remplacent-ils git + tests ?
Non, ils les complètent : les hooks empêchent les lignes rouges, git + tests rattrapent les erreurs ordinaires. Autonomie sûre = garde-fous durs et filet de récupération.
5. deny-list ou hook : lequel pour « pas de commit sur main » ?
deny-list ou hook : lequel pour « pas de commit sur main » ?Idéalement les deux : la deny-list pour le pattern évident, et un hook qui inspecte finement (la branche courante) et explique. Le hook gère le contextuel que la liste ne voit pas.
Chapitre suivant : Atelier — les hooks de TaskFlow — on assemble la chaîne complète.