ServicesÀ proposNotesContact Me contacter →
EN FR
Note

Hooks de sécurité dbt en production

Utiliser les hooks PreToolUse de Claude Code pour bloquer les commandes dbt dangereuses avant leur exécution — full-refresh en production, builds sans sélecteur et autres opérations à risque élevé

Planté
claude codedbtautomationdata quality

Les hooks Claude Code peuvent bloquer les commandes CLI dbt dangereuses avant leur exécution. La note sur les hooks existants couvre le blocage des modifications de fichiers vers des chemins protégés — cette note couvre le blocage des commandes CLI dbt dangereuses ciblant la production, comme l’exécution sur la mauvaise cible, le déclenchement de --full-refresh sur une table longue à reconstruire, ou l’exécution de dbt build sans sélecteur.

Le mécanisme clé est un hook PreToolUse qui inspecte la commande que Claude s’apprête à exécuter. Si elle correspond à un pattern dangereux, le hook sort avec le code 2, ce qui bloque l’exécution et fait remonter un message d’erreur à Claude. La sortie 0 laisse la commande passer. Tout autre code de sortie enregistre un avertissement mais ne bloque pas — une distinction qui prend les gens de court. Voir Hooks Claude Code pour le comportement complet des codes de sortie.

Le script de sécurité

Créez .claude/hooks/dbt-safety.sh :

#!/usr/bin/env bash
set -euo pipefail
input=$(cat)
command=$(echo "$input" | jq -r '.tool_input.command // empty')
# Est-ce une commande dbt ciblant la production ?
if echo "$command" | grep -q "dbt" && echo "$command" | grep -q "\-\-target.*prod"; then
# Bloquer full-refresh en production
if echo "$command" | grep -q "\-\-full-refresh"; then
echo "Bloqué : --full-refresh en production. Exécutez cela manuellement si vous en êtes sûr." >&2
exit 2
fi
# Bloquer run/build sans sélecteur explicite
if echo "$command" | grep -qE "dbt (run|build)" && ! echo "$command" | grep -qE "\-\-(select|models)"; then
echo "Bloqué : dbt run en production nécessite un --select explicite" >&2
exit 2
fi
fi
exit 0

Le hook lit l’entrée de l’outil depuis stdin en JSON, extrait la chaîne de commande et vérifie deux patterns :

  1. --full-refresh en production — Toujours bloqué. Un full refresh reconstruit la table depuis zéro, supprimant toutes les données existantes d’abord. Sur une grande table de production, cela signifie des heures de reconstruction et des données potentiellement manquantes pendant la reconstruction. Si vous avez réellement besoin d’un full refresh en prod, exécutez-le manuellement en dehors de Claude Code.

  2. dbt run ou dbt build non scopé en production — Bloqué sauf si --select ou --models est spécifié. Sans sélecteur, dbt exécute tout dans le projet. Sur une cible de production, c’est un défaut dangereux.

Enregistrement du hook

La configuration va dans .claude/settings.json :

{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/dbt-safety.sh"
}
]
}
]
}
}

Le matcher Bash déclenche le hook sur chaque commande bash que Claude tente d’exécuter. Le hook lui-même effectue le filtrage — il n’inspecte que les commandes contenant dbt et --target.*prod. Tout le reste passe à la sortie 0.

Notez que les matchers sont sensibles à la casse. bash ne correspondra pas à Bash. Vérifiez les noms exacts des outils dans la sortie de Claude si vos hooks ne se déclenchent pas.

Extension du pattern

Le script de base couvre les deux erreurs de production les plus courantes, mais vous pouvez l’étendre pour les risques spécifiques à votre projet :

Bloquer dbt seed en production. Les seeds remplacent entièrement le contenu des tables. En production, cela peut écraser des tables de référence dont d’autres modèles dépendent :

Terminal window
if echo "$command" | grep -qE "dbt seed" && echo "$command" | grep -q "\-\-target.*prod"; then
echo "Bloqué : dbt seed en production. Les seeds remplacent des tables entières." >&2
exit 2
fi

Bloquer dbt run-operation en production. Les opérations personnalisées (comme les instructions drop dans les macros) peuvent être destructives :

Terminal window
if echo "$command" | grep -qE "dbt run-operation" && echo "$command" | grep -q "\-\-target.*prod"; then
echo "Bloqué : dbt run-operation en production. Revoyez l'opération manuellement." >&2
exit 2
fi

Exiger --defer sur les builds de production. Si votre workflow attend que les builds de production utilisent --defer avec un manifest de production (pour que les modèles inchangés ne soient pas reconstruits), vous pouvez l’imposer :

Terminal window
if echo "$command" | grep -qE "dbt (run|build)" && echo "$command" | grep -q "\-\-target.*prod"; then
if ! echo "$command" | grep -q "\-\-defer"; then
echo "Bloqué : les builds de production nécessitent --defer --state ./prod-manifest" >&2
exit 2
fi
fi

Pourquoi pas juste CLAUDE.md ?

Vous pourriez ajouter « ne jamais exécuter —full-refresh en production » à votre CLAUDE.md. Claude suivrait cette instruction la plupart du temps. Mais CLAUDE.md est probabiliste — une conversation complexe, une longue session ou un prompt particulièrement persuasif peut faire déprioriser les instructions.

Les hooks sont déterministes. Le script shell bloque soit la commande (sortie 2) soit la laisse passer (sortie 0). Il n’y a pas de place pour l’interprétation du LLM. Pour les opérations où le coût d’une erreur se mesure en heures d’indisponibilité ou en données de production corrompues, l’application déterministe vaut l’effort de configuration.

L’approche pratique : mettez la règle dans les deux endroits. CLAUDE.md empêche Claude d’essayer la commande dangereuse en premier lieu. Le hook l’intercepte si Claude essaie quand même. Défense en profondeur.

Versionnez vos hooks de sécurité

Placez .claude/hooks/ et .claude/settings.json dans git. Quand vous intégrez un nouveau membre d’équipe, il obtient automatiquement tous vos garde-fous de production. Quand quelqu’un dans l’équipe rencontre un nouveau pattern dangereux, il ajoute une vérification au script de sécurité partagé et tout le monde en bénéficie au prochain pull.

Ce pattern est une application de l’approche de revue en couches : détecter les opérations dangereuses au plus tôt dans le workflow.