Hook de blocage No-Verify
Configuration du hook PreToolUse qui intercepte et bloque l'utilisation des flags de contournement avant l'exécution, garantissant que les agents IA ne peuvent pas ignorer les hooks de pre-commit, la signature GPG ou autres mécanismes de sécurité git.
Overview
Les agents de codage IA (Claude Code, Codex, etc.) peuvent exécuter des commandes shell avec des flags comme --no-verify qui contournent les hooks de pre-commit. Cela anéantit l'objectif du linting, du formatage, des tests et des vérifications de sécurité configurés dans les hooks de pre-commit. Le hook block-no-verify ajoute une garde PreToolUse qui rejette tout appel d'outil contenant des flags de contournement avant l'exécution.
Problem
Quand les agents IA commitent du code, ils peuvent utiliser des flags de contournement pour éviter les échecs de hooks :
# Ces commandes ignorent complètement les hooks de pre-commit
git commit --no-verify -m "quick fix"
git push --no-verify
git commit --no-gpg-sign -m "unsigned commit"
git merge --no-verify feature-branch
Cela permet :
- Au code non formaté d'entrer dans le repository
- Aux erreurs de linting de contourner les vérifications
- À la analyse de sécurité d'être ignorée
- Aux commits non signés de contourner les politiques de signature
- Aux suites de tests d'être contournées
Solution
Ajoutez un hook PreToolUse à .claude/settings.json qui inspecte chaque appel d'outil Bash et bloque les commandes contenant des flags de contournement.
Configuration
Ajoutez ce qui suit au fichier .claude/settings.json de votre projet :
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; then echo 'BLOCKED: --no-verify and --no-gpg-sign flags are not allowed. Run the commit without bypass flags so that pre-commit hooks execute properly.' >&2; exit 2; fi"
}
}
]
}
}
How It Works
- Matcher : Le hook cible uniquement les appels d'outil
Bash, donc il n'interfère pas avec les autres outils (Read, Edit, Grep, etc.). - Inspection : La variable d'environnement
$TOOL_INPUTcontient la commande complète que l'agent est sur le point d'exécuter. Le hook utiliseprintfpour passer l'entrée de manière sûre (en évitant les pièges deechoavec des caractères spéciaux) et vérifie les flags--no-verifyou--no-gpg-signuniquement s'ils sont précédés d'une commandegit. - Blocage : Si un flag de contournement est trouvé dans une commande git, le hook sort avec le code 2 et affiche un message d'erreur. Le code de sortie 2 signale à Claude Code de rejeter complètement l'appel d'outil.
- Passage : Si aucun flag de contournement n'est trouvé, le hook sort avec le code 0 et la commande s'exécute normalement.
Exit Codes
| Code | Signification |
|---|---|
| 0 | Autoriser l'appel d'outil à procéder |
| 1 | Erreur (l'appel d'outil procède quand même, avertissement affiché) |
| 2 | Bloquer complètement l'appel d'outil |
Blocked Flags
| Flag | Objectif | Pourquoi bloqué |
|---|---|---|
--no-verify |
Ignore les hooks de pre-commit et commit-msg | Contourne le linting, le formatage, les tests, les vérifications de sécurité |
--no-gpg-sign |
Ignore la signature GPG des commits | Contourne la politique de signature des commits |
Installation
Per-Project Setup
Créez ou mettez à jour .claude/settings.json à la racine de votre projet :
mkdir -p .claude
cat > .claude/settings.json << 'EOF'
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; then echo 'BLOCKED: --no-verify and --no-gpg-sign flags are not allowed. Run the commit without bypass flags so that pre-commit hooks execute properly.' >&2; exit 2; fi"
}
}
]
}
}
EOF
Global Setup
Pour appliquer à tous les projets, ajoutez à ~/.claude/settings.json :
mkdir -p ~/.claude
cat > ~/.claude/settings.json << 'EOF'
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; then echo 'BLOCKED: --no-verify and --no-gpg-sign flags are not allowed. Run the commit without bypass flags so that pre-commit hooks execute properly.' >&2; exit 2; fi"
}
}
]
}
}
EOF
Verification
Testez que le hook bloque les flags de contournement :
# Ceci devrait être bloqué par le hook :
git commit --no-verify -m "test"
# Ceci devrait réussir normalement :
git commit -m "test"
Extending the Hook
Adding More Blocked Flags
Pour bloquer des flags supplémentaires (par ex. --force), étendez le pattern grep :
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign|force-with-lease|force)'; then echo 'BLOCKED: Bypass flags are not allowed.' >&2; exit 2; fi"
}
}
]
}
}
Combining with Other Hooks
Le hook block-no-verify fonctionne aux côtés d'autres hooks PreToolUse :
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; then echo 'BLOCKED: Bypass flags not allowed.' >&2; exit 2; fi"
}
},
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE 'rm\\s+-rf\\s+/'; then echo 'BLOCKED: Dangerous rm command.' >&2; exit 2; fi"
}
}
]
}
}
Best Practices
- Commitez le fichier de configuration -- Ajoutez
.claude/settings.jsonau contrôle de version pour que tous les membres de l'équipe bénéficient du hook. - Documentez dans l'onboarding -- Mentionnez le hook dans le guide de contribution de votre projet pour que les développeurs comprennent pourquoi les flags de contournement sont bloqués.
- Associez avec les hooks de pre-commit -- Le hook block-no-verify garantit que les hooks de pre-commit s'exécutent ; assurez-vous d'avoir des hooks de pre-commit significatifs configurés.
- Testez après la configuration -- Vérifiez que le hook fonctionne en le déclenchant intentionnellement dans un test de commit.