Implémenter un hook
Mis à jour le 29 juillet 2026
Implémenter un hook
Passons de la théorie au code. Nous allons construire un hook concret pour empêcher Claude de lire des fichiers sensibles comme .env. C’est un exemple pratique de la façon dont les hooks peuvent protéger vos variables d’environnement et autres données confidentielles, et il met en œuvre l’intégralité du mécanisme décrit à la leçon précédente : un matcher, un script qui lit stdin, un code de sortie qui tranche.
Configurer le hook
Ouvrez votre fichier .claude/settings.local.json et ajoutez la configuration :
{
"hooks": {
"PreToolUse": [
{
"matcher": "Read|Grep",
"hooks": [
{
"type": "command",
"command": "node ./hooks/read_hook.js"
}
]
}
]
}
}
Le pipe agit comme un opérateur OU — le hook se déclenchera sur l’outil Read ou Grep. C’est la traduction directe du raisonnement mené précédemment : une clé d’API ne fuit pas seulement quand on ouvre le fichier qui la contient, elle fuit tout autant quand une recherche de motif en affiche la ligne. Le choix de settings.local.json n’est pas anodin non plus, puisque le chemin ./hooks/read_hook.js et la configuration restent ainsi sur votre machine, sans être imposés au reste de l’équipe.
Implémenter le script
Créez le fichier hooks/read_hook.js :
async function main() {
const chunks = [];
for await (const chunk of process.stdin) {
chunks.push(chunk);
}
const toolArgs = JSON.parse(
Buffer.concat(chunks).toString()
);
// Extraire le chemin que Claude essaie de lire
const readPath =
toolArgs.tool_input?.file_path ||
toolArgs.tool_input?.path ||
"";
// Bloquer si Claude essaie de lire un fichier .env
if (readPath.includes(".env")) {
console.error(
"Accès interdit : fichier .env protège par un hook"
);
process.exit(2);
}
}
main();
Trois moments structurent ce script. Il commence par accumuler l’intégralité de stdin avant de l’analyser, parce que les données arrivent par fragments et qu’un JSON.parse appliqué à un fragment échouerait. Il extrait ensuite le chemin visé en essayant successivement file_path puis path : les deux outils surveillés ne nomment pas leur argument de la même façon, et la chaîne vide en dernier recours évite de planter sur un appel dont la forme vous surprendrait. Il vérifie enfin si le chemin contient .env et bloque l’opération si c’est le cas. En sortant avec le code 2, Claude reçoit le message d’erreur et comprend que l’opération a été bloquée.
Remarquez que le script ne fait rien d’explicite lorsque le chemin est autorisé : la fonction se termine normalement, le processus sort avec le code 0, et l’appel d’outil suit son cours. Le silence vaut autorisation.
Tester le hook
Après avoir sauvegardé la configuration et le script, redémarrez Claude Code pour que les changements prennent effet. C’est l’oubli le plus fréquent à ce stade : un hook parfaitement écrit qui ne se déclenche jamais est presque toujours un hook dont la session n’a pas été relancée. Testez ensuite en demandant à Claude de lire votre fichier .env :
Lis le contenu du fichier .env
Claude va tenter l’opération Read, votre hook va l’intercepter et renvoyer un message d’erreur. La même protection s’applique aux opérations Grep : demandez-lui de chercher une chaîne dans le projet et vous verrez le même refus se produire, ce qui valide le second terme du matcher.
L’intérêt de ce pattern tient à ce qu’il déplace la protection en amont. Le blocage intervient avant que les données sensibles ne soient lues, et non après coup, donc rien de confidentiel n’a transité vers le modèle. Le message envoyé sur stderr rend l’échec intelligible pour Claude, qui poursuit sa tâche autrement plutôt que de s’acharner. Et parce que le matcher accepte plusieurs outils, la même règle ferme toutes les portes d’entrée d’un coup.
Ce pattern peut être étendu pour protéger n’importe quel fichier ou répertoire sensible dans votre projet : il vous suffit de remplacer le test sur .env par la condition qui correspond à vos secrets, un répertoire credentials/ ou un fichier de clés privées par exemple. La logique, elle, ne bouge pas.