Règles et points de contrôle d'exécution (Rules & Hooks) : associer des barrières et déclencheurs
📚 Navigation dans la série : Le chapitre précédent [23 · Extensions et modules (Plugins)] présentait le packaging d'outils complexes au sein d'extensions pour Codex. Ce chapitre traite de deux mécanismes d'encadrement fondamentaux de l'exécution : les règles (Rules) définissent les commandes autorisées à s'exécuter hors du bac à sable, et les points de contrôle (Hooks) déclenchent automatiquement des scripts à des étapes clés du cycle de vie de la session. L'une fait office de barrière de sécurité, l'autre de déclencheur automatique, éliminant la saisie manuelle de tâches de contrôle répétitives. Le chapitre suivant [25 · Arborescences de travail Git isolées (Worktrees)] présentera comment isoler et paralléliser le travail de plusieurs instances de Codex.
Permettez-moi de reproduire un échange réel survenu le mois dernier avec un collaborateur, lors de la recherche d'une panne d'intégration continue (CI) :
Moi : « Cette semaine, j'ai dû saisir manuellement la commande
ruff formatau moins dix fois après les modifications appliquées par Codex. » Collaborateur : « Pourtant, tu as inscrit la consigne « Formater après modification » dans le fichierAGENTS.md? » Moi : « Oui. Mais Codex l'omet une fois sur trois. Cette consigne reste une requête, pas une garantie. Un oubli et le contrôle de formatage de la CI rejette la modification. » Collaborateur : « Configure un hook. Dès que l'événement survient, le script s'exécute de manière automatique, que Codex s'en souvienne ou non. »
Cette suggestion était pertinente. J'ai configuré un hook PostToolUse et, depuis, chaque modification de fichier par Codex déclenche automatiquement le formatage. Je n'ai plus jamais saisi la commande manuellement, et aucun commit n'a été rejeté par la CI. Ce chapitre détaille le rôle et le paramétrage des règles et des hooks.
À la fin de ce chapitre, vous aurez en main :
- La différence entre règles et hooks, et pourquoi ils offrent une garantie de traitement là où
AGENTS.mdreste incitatif. - La rédaction des fichiers de règles (
.rulesavecprefix_rule) pour autoriser ou bloquer une commande, et l'usage decodex execpolicy checkpour valider vos filtres. - L'emplacement des fichiers de hooks et les événements clés associés (
PreToolUse,PostToolUse,Stop,SessionStart, etc.). - Le fonctionnement de la validation des hooks de Codex — pourquoi tout nouveau script est inactif par défaut jusqu'à sa validation via la commande
/hooks. - Le protocole d'échange de données des hooks (stdin en JSON, codes de sortie et stdout en JSON), ainsi que les différences d'intégration avec Claude Code.
- Deux scripts types prêts à l'emploi : le formatage automatique de fichiers et le blocage de commandes sensibles, ainsi qu'un guide de diagnostic en cas de dysfonctionnement.
⚠️ Note concernant les fonctionnalités : Les règles (Rules) de Codex sont signalées comme expérimentales et sujettes à modification. Les structures de clés et les comportements associés peuvent évoluer avec les versions de l'application. Fiez-vous aux configurations actives de votre installation.
01 Distinguer les rôles : Les règles définissent les accès, les hooks gèrent les réactions
En résumé : les règles (Rules) contrôlent l'autorisation d'exécuter une commande hors du bac à sable (barrière d'accès), tandis que les hooks (points de contrôle) déclenchent automatiquement un script lors d'un événement de session (déclencheur).
Analogie : La barrière d'accès d'une résidence et les éclairages automatiques de sécurité. Le lecteur de badge de la barrière vérifie une liste d'autorisations (« résidents autorisés, livreurs sous condition, intrus rejetés ») : c'est le rôle des règles. À l'inverse, le projecteur qui s'allume au passage d'un visiteur réagit à un événement physique (« détection de mouvement ») indépendamment de l'identité du visiteur : c'est le rôle des hooks. L'un valide une autorisation, l'autre réagit à une action.
Quelle est la différence avec le fichier AGENTS.md (présenté au chapitre 11) ? Elle tient en une notion :
Les consignes de
AGENTS.mdsont des requêtes ; les règles et hooks sont des garanties.
Explications :
- Dans
AGENTS.md: Vous demandez à Codex d'appliquer une action (« Exécuter ruff format après modification » ou « Ne pas modifier les fichiers de configuration de production »). Codex tente de respecter la consigne, mais chaque étape repose sur son évaluation. Il peut l'oublier ou l'omettre selon le contexte. - Avec un hook ou une règle : L'action s'exécute ou est bloquée de façon systématique par l'application, indépendamment de la décision du modèle.
C'est cette différence qui fiabilise le formatage : configuré dans AGENTS.md, le formatage est appliqué de manière probabiliste ; configuré dans un hook, il s'exécute à chaque écriture.
Cas d'usage classiques des garanties :
- « J'exécute fréquemment la commande
gh pr view. Je souhaite que Codex l'exécute sans me demander de validation à chaque fois » : configuration d'une règle d'autorisation directe. - « Je souhaite interdire l'usage des commandes
rm -rfougit push --force» : configuration d'une règle de blocage systématique. - « Je souhaite formater et analyser le code après chaque modification appliquée par l'IA » : configuration d'un hook automatique.
💡 En résumé : Les règles filtrent l'accès aux commandes (barrières), tandis que les hooks déclenchent des scripts sur des événements de session (déclencheurs). Ils transforment les requêtes incitatives en traitements obligatoires.
02 Configurer des règles (Rules) : Encadrer les exécutions de commandes
⚠️ Fonctionnalité expérimentale. Le format de définition des règles décrit ci-dessous peut évoluer. Fiez-vous à la documentation active de votre version.
Le rôle des règles est de raffiner le périmètre de sécurité. Comme vu au chapitre 15, les politiques de bac à sable sont globales (autorisé ou interdit pour tout le projet). Une règle (Rule) permet d'apporter de la granularité : « Autoriser l'exécution de la commande de lecture gh pr view hors du bac à sable, mais bloquer l'usage de grep au profit de rg ».
Analogie : L'accès d'un technicien dans un bâtiment. La politique globale définit son droit d'accès général (le badge d'entrée). La règle est la note complémentaire remise au poste de contrôle : « Autoriser l'accès aux bureaux techniques, mais interdire l'accès à la salle serveurs principale ». Cela évite d'avoir à redéfinir l'ensemble de son badge pour un seul local.
Applications types :
- Déclarer les outils de test et de reporting de l'équipe (
gh,make test) en liste blanche pour supprimer les demandes d'approbation récurrentes. - Exclure des utilitaires obsolètes ou interdits dans l'entreprise (
grep,find) pour forcer l'usage des standards de l'équipe (rg,fd). - Bloquer les écritures ou modifications critiques (
rm -rf /, accès aux dossiers.ssh) au niveau de la machine.
Structure et emplacement des fichiers de règles
Les règles s'écrivent dans des fichiers dotés de l'extension .rules, stockés dans un dossier rules/ associé à votre couche de configuration. Le fichier principal de l'utilisateur se situe généralement sous ~/.codex/rules/default.rules. La syntaxe utilise le langage Starlark (un dialecte de Python conçu pour être exécuté de manière sécurisée sans accès direct au système de fichiers).
Exemple de règle pour valider l'usage de la commande gh pr view :
# Avant d'exécuter la commande gh pr view, demande une invite de confirmation.
prefix_rule(
# Déclaration du préfixe de la commande (paramètre par paramètre dans le tableau).
pattern = ["gh", "pr", "view"],
# Décision de sécurité : allow (autoriser) / prompt (demander confirmation) / forbidden (bloquer).
decision = "prompt",
# Description optionnelle de la règle pour l'affichage utilisateur.
justification = "Affichage des PR autorisé sous condition de validation.",
# Tests unitaires intégrés : vérification des cas d'association.
match = [
"gh pr view 7888",
"gh pr view --repo openai/codex",
],
not_match = [
# Non associé : le filtre exige que l'ordre des arguments corresponde au pattern.
"gh pr --repo openai/codex view 7888",
],
)Détail des paramètres de la fonction prefix_rule :
| Paramètre | Rôle | Description |
|---|---|---|
pattern (requis) | Tableau décrivant le préfixe de commande cible | Les arguments peuvent être des chaînes uniques ou des alternatives ["view", "list"] |
decision | Action de sécurité appliquée lors de la correspondance | allow / prompt / forbidden (la décision la plus restrictive est prioritaire) |
justification | Explication du rôle de la règle | S'affiche dans les invites d'approbation |
match / not_match | Exemples de tests de validation | Validés automatiquement par Codex lors du chargement |
La priorité des décisions de sécurité s'évalue selon l'ordre : forbidden (priorité maximale) > prompt > allow (priorité minimale) :
| Décision | Comportement |
|---|---|
allow | Exécution directe de la commande hors du bac à sable, sans invite de confirmation. |
prompt | Affichage d'une invite d'approbation à l'utilisateur avant chaque exécution. |
forbidden | Blocage systématique de la commande ; l'IA ne peut pas l'exécuter. |
Une modification du fichier .rules nécessite un redémarrage de Codex pour être prise en compte. Notez que lorsque vous sélectionnez l'option « Toujours autoriser cette commande » lors d'une invite dans la console, Codex ajoute automatiquement l'entrée correspondante dans le fichier ~/.codex/rules/default.rules.
Sécurité : Traitement des commandes complexes
Une sécurité importante de Codex consiste à analyser les structures de commandes complexes (comme git add . && rm -rf /). L'application utilise un parseur syntaxique (tree-sitter) pour découper la ligne de commande en instructions autonomes et évaluer chaque bloc individuellement :
["bash", "-lc", "git add . && rm -rf /"]La commande est analysée selon ses deux composants :
["git", "add", "."]
["rm", "-rf", "/"]Même si la commande git add fait l'objet d'une règle d'autorisation (allow), la commande rm associée sera évaluée de manière autonome et bloquée si ses droits sont insuffisants. Cette décomposition empêche de contourner les règles en masquant des commandes dangereuses au sein d'enchaînements complexes.
Attention toutefois : ce découpage ne s'applique qu'aux enchaînements de commandes simples. Si l'instruction comporte des redirections de flux (>), des substitutions de variables ($(...)), des déclarations de variables en ligne ou des jokers (*), Codex ne la découpera pas et évaluera l'intégralité de la chaîne comme un appel de script bash -lc. Le système applique alors la décision la plus stricte.
Valider vos règles avec execpolicy check
Avant de déployer un fichier de règles, vous pouvez tester son comportement avec l'outil de validation :
codex execpolicy check --pretty \
--rules ~/.codex/rules/default.rules \
-- gh pr view 7888 --json title,body,commentsCette commande retourne un rapport au format JSON détaillant la décision finale appliquée par le filtre et les règles correspondantes. Prenez l'habitude de tester vos modifications avant de relancer votre session.
💡 En résumé : Les fichiers
.rulesdéfinissent les actions de sécurité (allow/prompt/forbidden) par préfixes de commandes. Codex décompose les enchaînements de commandes simples pour bloquer les tentatives de contournement. Testez vos règles aveccodex execpolicy checkavant de les activer.
03 Les événements du cycle de vie des sessions (Hooks)
Les hooks s'associent aux événements du cycle de vie de la session de travail de Codex.
Rappelons que le fonctionnement de Codex repose sur une boucle d'action : « Analyse → Action → Évaluation ». Les événements se situent à des étapes précises de cette boucle.

Ce schéma illustre la boucle d'exécution : la session débute avec SessionStart, puis chaque message utilisateur déclenche UserPromptSubmit. L'assistant évalue ensuite l'usage d'outils : avant chaque appel, l'événement PreToolUse s'active. Une fois l'outil exécuté, PostToolUse traite les résultats. À la fin de la boucle d'analyse, l'événement Stop s'active avant de restituer la réponse.
Les quatre événements principaux de Codex sont :
| Événement | Moment d'exécution | Cas d'usage type |
|---|---|---|
PreToolUse | Avant le lancement d'un outil par Codex | Vérification de la commande, filtrage de sécurité (permet de bloquer l'action) |
PostToolUse | Après le retour de résultat d'un outil | Lancement d'outils de formatage, analyse statique de code |
Stop | À la fin d'une boucle de réflexion de Codex | Analyse des erreurs de compilation, relance d'une boucle de correction si nécessaire |
SessionStart | Lors de l'initialisation ou de la restauration de la session | Injection d'informations de contexte (logs Git récents, état du projet) |
Un autre événement utile est PermissionRequest, déclenché juste avant l'affichage d'une invite d'approbation, permettant de scripter des validations d'accès dynamiques.
La distinction entre Pre (avant) et Post (après) détermine les capacités d'action : seul un hook configuré sur un événement Pre peut interrompre ou modifier l'action de l'outil avant son exécution. Un hook Post intervient après le traitement et ne peut pas annuler les modifications appliquées par l'outil sur votre système.

Ce schéma illustre la liaison des scripts aux événements : chaque événement du cycle (SessionStart, PreToolUse, PostToolUse, Stop) agit comme une prise sur laquelle se branche un script spécifique. Dès que Codex atteint cette étape, le script associé est exécuté de manière déterministe.
Note de comportement propre à Codex : le retour d'une décision decision: "block" sur l'événement Stop ne signifie pas le rejet de l'échange. Il indique à Codex de poursuivre sa réflexion pour une boucle supplémentaire, en utilisant le texte retourné dans le champ reason comme une nouvelle instruction utilisateur. Sur PostToolUse, une décision block n'annule pas la commande exécutée mais réinjecte le message d'erreur écrit sur stderr dans la boucle de réflexion du modèle pour correction.
💡 En résumé : Les hooks se branchent sur des événements clés du cycle de vie. Les événements
Preinterviennent avant l'action (permettant le blocage) et les événementsPostouStopinterviennent après (permettant des actions de formatage ou de relance de boucle).
04 Structure de configuration et filtres de hooks
Les hooks se déclarent au format JSON ou TOML au sein des fichiers de configuration.
Emplacements des configurations de hooks
Les configurations s'écrivent dans des fichiers hooks.json ou sous le bloc [hooks] des fichiers config.toml :
| Fichier | Portée d'accès | Partage Git |
|---|---|---|
Global : ~/.codex/hooks.json | Tous les projets locaux de l'utilisateur | Non |
Global : ~/.codex/config.toml | Tous les projets locaux de l'utilisateur | Non |
Projet local : <projet>/.codex/hooks.json | Limité à ce projet spécifique | Oui (recommandé pour l'équipe) |
Projet local : <projet>/.codex/config.toml | Limité à ce projet spécifique | Oui |
Règles de traitement :
- Les hooks issus de configurations locales et globales se cumulent (les fichiers locaux n'écrasent pas les hooks globaux).
- Évitez de déclarer des hooks simultanément dans
hooks.jsonetconfig.tomlau sein d'une même couche pour éviter les avertissements de fusion lors de l'initialisation. - Les configurations locales ne sont chargées que si le répertoire est marqué comme fiable.
Syntaxe de configuration des hooks
Exemple de déclaration au sein du fichier de projet .codex/hooks.json pour surveiller l'usage du terminal Bash :
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/post_tool_use.py\"",
"timeout": 30,
"statusMessage": "Analyse du retour de la commande Bash"
}
]
}
]
}
}Détail de la structure :
- La clé d'événement (ex:
"PostToolUse") définit le moment d'activation. - La clé de filtre
"matcher"restreint l'exécution de l'événement à un outil cible (ici, l'outilBash). - Le tableau
"hooks"liste les actions à exécuter. Le paramètre"type": "command"indique l'exécution d'un script système, et"command"contient la commande associée.
Détails d'intégration importants :
- Délai d'attente (
timeout) : Le paramètre s'exprime en secondes (la valeur par défaut est de 600 secondes si elle n'est pas renseignée). - Type de script : Seul le format
"type": "command"(exécution d'un script système) est supporté actuellement par l'application. - Exécution parallèle : Si plusieurs hooks correspondent à un même événement, ils s'exécutent de façon parallèle. Un hook de blocage n'empêchera pas l'initialisation d'un autre hook sur le même événement.
- Répertoire de travail : L'exécution s'effectue dans le répertoire courant de la session. Pour référencer un script interne au projet, utilisez la commande git
$(git rev-parse --show-toplevel)pour construire un chemin d'accès absolu stable, peu importe le sous-dossier depuis lequel Codex a été démarré. - Compatibilité Windows : Vous pouvez déclarer la clé
command_windows(oucommandWindowsen TOML) pour spécifier la commande alternative à exécuter sur les postes Windows.
Note pour les utilisateurs de Claude Code : Le paramètre
timeouts'exprime en secondes (et non en millisecondes), et il n'existe pas de variable d'environnement$CLAUDE_PROJECT_DIR. Utilisez les commandes Git pour localiser la racine du projet.
La déclaration équivalente au format TOML au sein de config.toml respecte la structure suivante :
[[hooks.PostToolUse]]
matcher = "^Bash$"
[[hooks.PostToolUse.hooks]]
type = "command"
command = '/usr/bin/python3 "$(git rev-parse --show-toplevel)/.codex/hooks/post_tool_use.py"'
timeout = 30
statusMessage = "Analyse du retour de la commande Bash"L'usage des filtres matcher
Le paramètre matcher évite d'exécuter vos scripts à chaque action. Il s'appuie sur une expression régulière (regex) pour cibler l'outil déclencheur :
| Syntaxe matcher | Correspondance | Exemple d'activation |
|---|---|---|
"Bash" | Contient la chaîne "Bash" | Outil d'exécution de terminal |
"^apply_patch$" | Correspondance exacte | Outil d'écriture de fichiers de Codex |
"Edit|Write" | Alternance regex (symbolisant Edit ou Write) | Raccourcis pour intercepter les modifications de code |
"mcp__filesystem__.*" | Préfixe regex de connecteur MCP | Outils d'accès aux fichiers du serveur MCP concerné |
"" ou omission | Correspondance globale | Le script s'exécute à chaque événement de cette catégorie |
Détails à retenir :
- Le nom de l'outil d'écriture de fichiers de Codex est
apply_patch. Les identifiantsEditouWritesont gérés comme des alias pour faciliter les filtres, mais les données reçues par le script contiendront l'outilapply_patchdans le champtool_name. - Les événements
UserPromptSubmitetStopn'étant pas associés à des outils, le filtrematcherest ignoré sur ces catégories. - L'événement
PreToolUseintercepte les appels terminaux simples, l'écriture de fichiersapply_patchet les serveurs MCP. Il ne peut pas bloquer des exécutions complexes utilisant des shells déportés ou des outils réseau natifs. Ne l'utilisez pas comme une barrière de sécurité absolue.
💡 En résumé : La configuration associe l'événement, le filtre
matcher(regex) et le script de commande. Les chemins d'accès doivent être absolus (utilisez Git pour construire les liens).
05 Le protocole de sécurité : La validation obligatoire des hooks
Codex applique une sécurité stricte sur les scripts d'exécution : tout hook ajouté ou modifié est bloqué par défaut jusqu'à sa validation manuelle par l'utilisateur.
Les scripts d'exécutions automatiques disposant des mêmes privilèges système que l'utilisateur, l'activation d'un hook issu d'un projet cloné sur internet pourrait exécuter du code malveillant sur votre machine.
Analogie : L'autorisation de droits sur un système d'exploitation. L'installation d'une application ne lui donne pas un accès immédiat à votre micro ou à vos fichiers. Le système d'exploitation affiche une invite d'autorisation lors de la première tentative d'accès. La validation des hooks de Codex répond à cette exigence.
Les règles de validation sont les suivantes :
- Codex calcule et enregistre l'empreinte de sécurité (le hash) de chaque hook configuré. Toute modification de chemin d'accès ou de commande invalide l'empreinte et bloque le script.
- La console d'administration
/hooksaffiche l'état des scripts détectés, permet de consulter leur commande et de valider leur activation. - Si un hook bloqué (non validé) est détecté au démarrage d'une session, Codex affiche un message d'avertissement.
Lors de la première configuration d'un script, ouvrez la console d'administration pour valider son exécution :
/hooksL'interface liste les scripts. Sélectionnez le hook configuré (indiqué en état « review ») et validez son exécution pour l'activer. Les scripts système ou définis par des politiques d'administration (managed hooks) sont validés d'office et ne peuvent pas être désactivés par cette interface.
Pour les environnements automatisés (CI/CD), l'option --dangerously-bypass-hook-trust permet de contourner cette étape de validation. Réservez cet argument aux conteneurs de test isolés.
Sécurité : Auditez la commande du script dans la console
/hooksavant d'accorder votre validation. N'activez pas de scripts d'exécution automatique issus de sources non vérifiées.
💡 En résumé : Tout hook ajouté ou modifié est suspendu par sécurité. Ouvrez la console
/hooksau lancement pour auditer le script et valider son activation.
06 Protocole d'échange de données : stdin, codes de sortie et stdout
Les scripts de hooks communiquent avec Codex selon un protocole d'échange s'appuyant sur les flux d'entrées-sorties standard.
Le protocole d'échange s'organise autour de trois flux : la réception des données de l'événement sur stdin (format JSON), le traitement par votre script, et le retour d'instructions via le code de sortie (exit code) et stdout (format JSON).
Réception des données (stdin)
Lors de l'activation d'un événement, Codex transmet une structure JSON contenant les clés système suivantes sur l'entrée standard du script :
| Clé JSON | Description |
|---|---|
session_id | Identifiant unique de la session de travail active |
cwd | Répertoire de travail courant de la session |
hook_event_name | Nom de l'événement déclencheur (ex: PreToolUse) |
transcript_path | Chemin d'accès au journal d'échanges de la session |
model | Identifiant du modèle d'IA actif pour la tâche |
permission_mode | Politique de droits d'accès de la session |
Pour les événements associés à des outils, les clés complémentaires tool_name (l'identifiant de l'outil, ex: "Bash") et tool_input (contenant la commande ou les paramètres d'entrée) sont fournies. Exemple de flux reçu par un script PreToolUse avant l'exécution d'une commande Bash :
{
"session_id": "abc123",
"cwd": "/Users/sarah/monprojet",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": {
"command": "rm -rf /tmp/x"
}
}Votre script peut lire cette structure pour analyser la commande en cours d'exécution.
Retour d'instructions par code de sortie (exit code)
Le code de retour de votre script transmet la décision de traitement à Codex :
| Code de sortie | Signification | Comportement appliqué |
|---|---|---|
0 | Traitement valide | L'action se poursuit normalement. |
2 | Signal d'interruption / de rebouclage | Comportement dépendant de l'événement (blocage ou réinjection). |
| Autre | Erreur d'exécution | Traité comme un échec du script de hook. |
Le comportement du code de retour 2 s'adapte selon la nature de l'événement :
- Sur les événements
PreToolUseouUserPromptSubmit: L'exécution de l'outil (ou le traitement du message) est bloquée. Le texte écrit par votre script sur le flux d'erreur standard (stderr) s'affiche à l'écran comme explication. - Sur les événements
PostToolUseouStop: L'outil ayant déjà été exécuté, le signal ne peut pas l'annuler. Il réinjecte le message d'erreur écrit sur stderr dans la boucle de réflexion de l'IA pour forcer une correction de code.
Retour d'instructions complexes par stdout (JSON)
Pour transmettre des consignes élaborées, votre script peut retourner une structure JSON sur son flux de sortie standard (stdout) tout en retournant le code 0 :
Pour interrompre une action sur PreToolUse en retournant le champ permissionDecision: "deny" :
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "La commande cible touche des répertoires sensibles et a été bloquée par le script de sécurité."
}
}Pour injecter du contexte au démarrage avec SessionStart via le champ additionalContext :
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "Consigne d'équipe : Vérifie la couverture de tests avant de valider tes modifications."
}
}Règles de formatage importantes :
- Les retours de texte brut sur la sortie standard (stdout) sont ignorés sur l'événement
PreToolUse; vous devez formater le retour en JSON pour transmettre une décision. - Les événements
SessionStartetUserPromptSubmitacceptent le retour de texte brut sur la sortie standard, qui est directement injecté dans le contexte du modèle. - Les événements
StopetSubagentStopexigent une structure de retour au format JSON ; le retour de texte brut provoquera une erreur de traitement.
💡 En résumé : Les hooks reçoivent les données d'événement au format JSON sur stdin. Le retour d'information s'effectue via le code de retour (
0pour continuer,2pour interrompre/relancer) et par l'écriture de structures JSON sur stdout.
07 Exemples de scripts de hooks prêts à l'emploi
Cette section présente deux exemples concrets de configuration de hooks.
Exemple 1 : Formatage automatique après modification de code (PostToolUse)
Ce hook automatise le formatage après chaque écriture appliquée par Codex, évitant les rejets lors des contrôles de CI.
Étape 1 : Créez le script d'exécution .codex/hooks/format.py (lecture du flux JSON, extraction des fichiers modifiés et exécution de l'outil de formatage) :
#!/usr/bin/env python3
import json, subprocess, sys
# Charge les données de l'événement depuis stdin
data = json.load(sys.stdin)
# Exécute l'outil de formatage sur le répertoire du projet
subprocess.run(["ruff", "format", "."])Étape 2 : Déclarez le hook dans le fichier .codex/hooks.json de votre projet, en ciblant l'outil d'écriture de fichiers de Codex (Edit|Write correspondant à apply_patch) :
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/format.py\"",
"timeout": 30,
"statusMessage": "Formatage automatique des fichiers modifiés"
}
]
}
]
}
}Étape 3 : Ouvrez une session Codex et validez l'empreinte du script dans /hooks pour l'activer.
Exemple 2 : Blocage des commandes terminal de suppression critique (PreToolUse)
Ce script intercepte l'appel de commandes Bash dangereuses et bloque leur exécution.
Étape 1 : Créez le script de contrôle .codex/hooks/block-dangerous.py :
#!/usr/bin/env python3
import json, sys
# Récupère la commande depuis le flux stdin
data = json.load(sys.stdin)
command = data.get("tool_input", {}).get("command", "")
# Recherche de motifs sensibles
if "rm -rf" in command:
# Affiche l'explication sur stderr pour le modèle
print("Action interdite : L'usage de la commande de suppression rm -rf est bloqué par la politique locale.", file=sys.stderr)
# Retourne le code 2 pour forcer l'interruption
sys.exit(2)
sys.exit(0)Étape 2 : Enregistrez le hook de contrôle dans .codex/hooks.json sur l'événement PreToolUse de l'outil Bash :
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/block-dangerous.py\"",
"statusMessage": "Audit de sécurité de la commande Bash"
}
]
}
]
}
}Étape 3 : Validez l'activation du script dans /hooks lors du premier lancement.
Comparatif d'utilisation :
| Caractéristique | Exemple 1 : Formatage automatique | Exemple 2 : Audit de sécurité |
|---|---|---|
| Événement cible | PostToolUse (après exécution) | PreToolUse (avant exécution) |
| Filtre matcher | Edit|Write (alias de apply_patch) | Bash |
| Méthode d'action | Exécute un outil de style sans bloquer | Renvoie le code 2 pour interrompre la commande |
| Alternative de règles | Non applicable (action post-traitement) | Possible (les filtres simples se gèrent dans .rules) |
💡 En résumé : Le script de formatage utilise
PostToolUsepour traiter les fichiers modifiés. Le script de sécurité utilisePreToolUseet retourne le code2pour interrompre les commandes sensibles.
08 En pratique : Configurer et valider un hook de traçabilité
Voici un exercice pour configurer un hook de journalisation d'activité, valider son empreinte de sécurité et vérifier son bon fonctionnement.
Note technique : L'exercice s'appuie sur Python. La commande Git
git initdoit être exécutée dans votre répertoire de test pour que le script puisse localiser la racine du projet via les commandes Git.
Étape 1 : Initialiser le répertoire de test
Créez le répertoire et initialisez le dépôt Git local :
mkdir hooks-demo
cd hooks-demo
git init
mkdir -p .codex/hooksÉtape 2 : Écrire le script de journalisation
Créez le fichier .codex/hooks/log-commands.py (qui extrait la commande Bash et l'écrit dans un fichier journal de votre dossier utilisateur) :
#!/usr/bin/env python3
import json, sys, os
# Charge les données de stdin
data = json.load(sys.stdin)
command = data.get("tool_input", {}).get("command", "")
log_path = os.path.expanduser("~/codex-commands-log.txt")
# Enregistre la commande dans le fichier
with open(log_path, "a") as f:
f.write(command + "\n")Étape 3 : Déclarer la configuration du hook
Créez le fichier de configuration .codex/hooks.json à la racine du dossier de test :
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/log-commands.py\"",
"statusMessage": "Journalisation de la commande"
}
]
}
]
}
}Étape 4 : Lancer Codex et valider l'activation
Démarrez Codex dans le dossier de test :
codexOuvrez la console de gestion des hooks pour valider le script :
/hooksComportement attendu : Le script de journalisation apparaît sous le statut « review ». Validez son activation. L'empreinte du script est enregistrée.
Étape 5 : Exécuter une commande et vérifier le journal
Saisissez une consigne simple pour forcer l'usage du terminal Bash :
Affiche la liste des fichiers du répertoire courant.Codex exécute la commande de lecture. Fermez la session Codex. Affichez ensuite le contenu du fichier de logs généré dans votre répertoire utilisateur :
cat ~/codex-commands-log.txtComportement attendu : La commande exécutée par Codex (ex: ls) est enregistrée dans le fichier journal, validant le bon fonctionnement du hook.
Ce test valide la chaîne d'exécution automatique des hooks.
💡 En résumé : L'exercice montre la déclaration du hook dans
.codex/hooks.json, son activation dans/hookset la validation de son fonctionnement par la lecture du fichier journal généré.
09 Guide de diagnostic des dysfonctionnements
Si un hook ou une règle ne réagit pas comme prévu, suivez les étapes de contrôle suivantes :
| Problème constaté | Cause probable | Solution |
|---|---|---|
| Le hook ne se déclenche pas | Le script n'a pas été validé dans la console /hooks | Ouvrez /hooks en session et validez l'empreinte du script (toute modification du script nécessite une nouvelle validation). |
Le filtre matcher ou l'événement cible est erroné | Vérifiez que le nom de l'outil correspond à l'expression régulière du matcher. | |
Le hook n'apparaît pas dans /hooks | Le fichier JSON présente des erreurs de syntaxe | Validez la structure JSON (les commentaires et les virgules de fin de ligne sont interdits en JSON standard). |
| L'emplacement du fichier est incorrect | Vérifiez que le fichier est nommé hooks.json dans le dossier .codex/. | |
| Erreur de type « command not found » | Le script utilise un chemin d'accès relatif | Utilisez $(git rev-parse --show-toplevel) dans la commande pour construire un chemin d'accès absolu. |
| La commande n'est pas bloquée | L'événement ciblé est PostToolUse | Seul l'événement PreToolUse intervient avant l'action et permet son blocage. |
| Le script ne renvoie pas le code d'interruption | Assurez-vous que le script retourne le code 2 ou la structure JSON permissionDecision: "deny". |
Pour tester un script de hook indépendamment de Codex, vous pouvez simuler son appel en console en lui transmettant une structure JSON sur son entrée standard :
echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /tmp/x"}}' | python3 .codex/hooks/block-dangerous.py
echo $? # Affiche le code de retour (doit être 2 pour un blocage)Cette validation rapide permet de fiabiliser le code de vos scripts avant leur intégration dans Codex.
Pour désactiver temporairement l'ensemble des hooks, modifiez le paramètre suivant dans votre fichier principal ~/.codex/config.toml :
[features]
hooks = false💡 En résumé : Le diagnostic impose de vérifier la validation dans
/hooks, l'usage de chemins d'accès absolus, et d'isoler les tests des scripts en simulant l'injection de flux JSON sur l'entrée standard.
10 Résumé
Ce chapitre a présenté la mise en œuvre de règles et de points de contrôle (Hooks) pour automatiser et sécuriser l'exécution de Codex.
Voici les points clés à retenir :
| Mécanisme | Rôle | Configuration |
|---|---|---|
| Règles (Rules) | Définit les autorisations d'exécution de commandes hors du bac à sable. | Fichiers .rules (bloc prefix_rule avec allow/prompt/forbidden). |
| Hooks | Déclenche des scripts automatiques sur des événements du cycle de vie. | Fichiers hooks.json ou bloc [hooks] dans config.toml. |
| Événements | Jalons du cycle de traitement. | PreToolUse (avant exécution) / PostToolUse (après) / Stop (fin de boucle) / SessionStart (démarrage). |
| Validation | Sécurité contre l'exécution de scripts malveillants. | Tout hook ajouté ou modifié doit être validé manuellement dans la console /hooks. |
| Protocole | Flux d'échange de données. | Entrées JSON sur stdin ; retour par code de sortie (0 pour continuer, 2 pour interrompre) ou JSON sur stdout. |
Vous êtes désormais en mesure de faire la différence entre une règle d'accès et un hook d'événement, de configurer des filtres de commandes dans des fichiers .rules et d'en vérifier le comportement, de choisir l'événement du cycle de vie adapté à vos scripts de contrôle, de déclarer des hooks locaux ou globaux, de valider la sécurité des scripts dans la console /hooks, et d'exploiter le protocole d'échange de données pour concevoir des scripts d'analyse de code.
Le chapitre suivant 25 · Arborescences de travail Git isolées (Worktrees) présente l'isolation des tâches : comment configurer des répertoires de travail distincts (Git Worktrees) pour permettre à Codex de mener des tâches de développement en parallèle sans interférer avec vos modifications en cours ? Nous verrons comment sécuriser l'exécution de tâches multiples.