detect-secrets empêche les nouveaux secrets d’entrer dans votre code, sans vous obliger à nettoyer tout l’historique Git d’un coup. Grâce à un système de baseline versionnable, l’outil identifie les secrets existants et les met de côté pour se concentrer sur les ajouts. C’est l’approche pragmatique adoptée par Yelp pour sécuriser des centaines de dépôts en entreprise.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre la philosophie baseline de detect-secrets
- Scanner un projet et créer une baseline
- Auditer les résultats pour distinguer vrais et faux positifs
- Filtrer les faux positifs avec les exclusions et l’allowlist inline
- Intégrer detect-secrets comme pre-commit hook et en CI/CD
Le problème : des secrets qui s’accumulent dans l’historique
Section intitulée « Le problème : des secrets qui s’accumulent dans l’historique »Imaginez un dépôt Git avec 5 ans d’historique et 10 000 commits. Quelque part dans ces commits, des clés API et des mots de passe ont été commités par erreur. Les supprimer du code actuel ne suffit pas : ils restent dans l’historique Git. Et réécrire l’historique complet est souvent irréaliste.
C’est exactement ce problème que detect-secrets résout avec une approche différente des autres scanners :
| Approche | Comment ça marche | Limitation |
|---|---|---|
| Scanner tout l’historique (Gitleaks, TruffleHog) | Parcourt chaque commit | Lent sur les gros dépôts, beaucoup de bruit |
| Baseline (detect-secrets) | Photographie les secrets existants, bloque les nouveaux | Ne scanne pas l’historique |
L’idée est simple : on accepte que des secrets existent déjà (c’est la baseline), et on empêche la situation d’empirer. Ensuite, on migre les secrets existants progressivement.
Comment detect-secrets fonctionne
Section intitulée « Comment detect-secrets fonctionne »detect-secrets repose sur deux composants qui travaillent ensemble : les plugins et les filtres.
Les plugins trouvent les secrets dans le code. Il en existe trois types :
| Type | Fonctionnement | Exemple |
|---|---|---|
| Regex | Cherche des patterns structurés (clés AWS, tokens GitHub) | AKIA... détecté par AWSKeyDetector |
| Entropie | Mesure le “désordre” d’une chaîne (haute entropie = probable secret) | wJalrXUtnFEMI/K7MDENG détecté par Base64HighEntropyString |
| Mot-clé | Cherche des noms de variables associés aux secrets | password = "hunter2" détecté par KeywordDetector |
Les filtres éliminent les faux positifs. Par défaut, detect-secrets ignore :
- Les UUIDs (pattern reconnaissable)
- Les chaînes séquentielles (
abcdefg) - Les templates (
${SECRET},{{key}},<placeholder>) - Les fichiers de lock
- Les références indirectes (
password = get_secret())
Trois outils, trois usages
Section intitulée « Trois outils, trois usages »detect-secrets fournit trois commandes distinctes :
| Commande | Quand l’utiliser |
|---|---|
detect-secrets scan | Créer ou mettre à jour la baseline |
detect-secrets-hook | Bloquer les commits contenant de nouveaux secrets |
detect-secrets audit | Analyser et labelliser les résultats de la baseline |
Installation
Section intitulée « Installation »pip install detect-secretsPour les fonctionnalités optionnelles :
# Support word-list (exclure des mots connus)pip install detect-secrets[word_list]
# Support détecteur de gibberish (ML)pip install detect-secrets[gibberish]brew install detect-secretsSi votre système bloque l’installation globale (PEP 668) :
python3 -m venv .venvsource .venv/bin/activatepip install detect-secretsVérification :
detect-secrets --version# 1.5.0Scanner un projet et créer la baseline
Section intitulée « Scanner un projet et créer la baseline »-
Créer la baseline initiale : detect-secrets scanne tous les fichiers trackés par Git et génère un fichier JSON contenant les secrets détectés.
Fenêtre de terminal detect-secrets scan > .secrets.baselineLe fichier
.secrets.baselinecontient trois sections :plugins_used: la liste des 27 plugins actifsfilters_used: les 11 filtres appliquésresults: les secrets détectés, regroupés par fichier
-
Vérifier ce qui a été détecté : utilisez la commande
audit --reportpour afficher un résumé lisible.Fenêtre de terminal detect-secrets audit .secrets.baseline --reportChaque secret est affiché avec son fichier, sa ligne, son type et sa catégorie (
UNVERIFIED,VERIFIED_TRUEouVERIFIED_FALSE). -
Versionner la baseline : ajoutez le fichier au dépôt Git. Il servira de référence pour bloquer les futurs secrets.
Fenêtre de terminal git add .secrets.baselinegit commit -m "chore: add detect-secrets baseline"
Mettre à jour la baseline
Section intitulée « Mettre à jour la baseline »Au fil du temps, votre code évolue. Des secrets sont supprimés, d’autres ajoutés. Pour synchroniser la baseline :
detect-secrets scan --baseline .secrets.baselineCette commande :
- Met à jour la baseline vers le format de la dernière version
- Ajoute les nouveaux secrets détectés
- Supprime les secrets qui ne sont plus dans le code
- Préserve les labels déjà attribués lors de l’audit
Scanner une chaîne individuelle
Section intitulée « Scanner une chaîne individuelle »Pour tester rapidement si une valeur est détectée comme secret :
detect-secrets scan --string "AKIAIOSFODNN7EXAMPLE"AWSKeyDetector : True (unverified)ArtifactoryDetector : FalseAzureStorageKeyDetector : FalseBase64HighEntropyString : False (3.684)BasicAuthDetector : False...Chaque plugin indique True ou False. Pour les détecteurs d’entropie, le score est affiché entre parenthèses (seuil par défaut : 4.5 pour base64, 3.0 pour hex).
Les 27 plugins intégrés
Section intitulée « Les 27 plugins intégrés »detect-secrets v1.5.0 embarque 27 plugins activés par défaut :
| Plugin | Ce qu’il détecte |
|---|---|
AWSKeyDetector | Clés d’accès AWS (AKIA...) |
AzureStorageKeyDetector | Clés de stockage Azure |
BasicAuthDetector | Identifiants en URLs (user:pass@host) |
GitHubTokenDetector | Tokens GitHub (ghp_, gho_, ghs_) |
GitLabTokenDetector | Tokens GitLab (glpat-) |
JwtTokenDetector | JSON Web Tokens (eyJ...) |
KeywordDetector | Variables nommées password, secret, token, etc. |
OpenAIDetector | Clés API OpenAI (sk-) |
PrivateKeyDetector | Clés privées RSA, DSA, ECDSA, OpenSSH |
SlackDetector | Tokens et webhooks Slack |
StripeDetector | Clés API Stripe (sk_live_, rk_live_) |
Base64HighEntropyString | Chaînes base64 à haute entropie (seuil : 4.5) |
HexHighEntropyString | Chaînes hexadécimales à haute entropie (seuil : 3.0) |
Et aussi : ArtifactoryDetector, CloudantDetector, DiscordBotTokenDetector, IbmCloudIamDetector, IbmCosHmacDetector, IPPublicDetector, MailchimpDetector, NpmDetector, PypiTokenDetector, SendGridDetector, SoftlayerDetector, SquareOAuthDetector, TelegramBotTokenDetector, TwilioKeyDetector.
Désactiver des plugins
Section intitulée « Désactiver des plugins »Pour réduire le bruit, désactivez les plugins inutiles :
# Désactiver le détecteur de mots-clés et les IP publiquesdetect-secrets scan \ --disable-plugin KeywordDetector \ --disable-plugin IPPublicDetectorScanner avec un seul plugin
Section intitulée « Scanner avec un seul plugin »Pour n’utiliser qu’un seul plugin, désactivez tous les autres :
detect-secrets scan --list-all-plugins | \ grep -v 'AWSKeyDetector' | \ sed "s#^#--disable-plugin #g" | \ xargs detect-secrets scanRégler les seuils d’entropie
Section intitulée « Régler les seuils d’entropie »Les détecteurs d’entropie acceptent un seuil entre 0.0 et 8.0. Un seuil plus bas détecte plus de secrets (mais plus de faux positifs) :
# Seuil base64 abaissé de 4.5 à 3.5detect-secrets scan --base64-limit 3.5
# Seuil hex relevé de 3.0 à 4.0detect-secrets scan --hex-limit 4.0Gérer les faux positifs
Section intitulée « Gérer les faux positifs »Les faux positifs sont inévitables. detect-secrets propose plusieurs mécanismes pour les gérer.
Allowlist inline (pragma)
Section intitulée « Allowlist inline (pragma) »Ajoutez un commentaire pragma: allowlist secret sur la ligne à exclure :
# Ce n'est pas un vrai secret, c'est un exempleEXAMPLE_KEY = "AKIAIOSFODNN7EXAMPLE" # pragma: allowlist secretPour exclure la ligne suivante :
// pragma: allowlist nextline secretconst EXAMPLE_KEY = "AKIAIOSFODNN7EXAMPLE";Exclure des fichiers
Section intitulée « Exclure des fichiers »Ignorez des fichiers par regex :
detect-secrets scan --exclude-files '\.signature$' --exclude-files 'test_data/.*'Exclure des lignes
Section intitulée « Exclure des lignes »Ignorez des lignes qui correspondent à un pattern :
detect-secrets scan --exclude-lines 'EXAMPLE' --exclude-lines 'fake_secret'Exclure des valeurs de secrets
Section intitulée « Exclure des valeurs de secrets »Ignorez des secrets par leur valeur :
detect-secrets scan --exclude-secrets '(fakesecret|\$\{.*\})'Exclure avec une word-list
Section intitulée « Exclure avec une word-list »Pour exclure un grand nombre de faux positifs connus, utilisez un fichier de mots :
pip install detect-secrets[word_list]example-passwordtest-api-keySuperSecret123detect-secrets scan --word-list wordlist.txtAuditer la baseline
Section intitulée « Auditer la baseline »L’audit permet de labelliser chaque secret comme vrai positif ou faux positif. C’est utile pour :
- Établir la liste des secrets à migrer
- Mesurer la précision des plugins
- Améliorer la configuration
Audit interactif
Section intitulée « Audit interactif »detect-secrets audit .secrets.baselinePour chaque secret, detect-secrets affiche le contexte (5 lignes avant/après) et demande :
Secret: 1 of 12Filename: config.envSecret Type: Secret Keyword----------1: DATABASE_HOST=localhost2: DATABASE_PORT=54323: DATABASE_USER=admin4: DATABASE_PASSWORD=SuperSecret123!5: AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE----------Should this string be committed to the repository? (y)es, (n)o, (s)kip, (q)uit:- y (yes) : c’est un faux positif, on peut le garder
- n (no) : c’est un vrai secret, à migrer
- s (skip) : on ne sait pas, on passe
- q (quit) : arrêter et sauvegarder
Générer un rapport
Section intitulée « Générer un rapport »# Rapport completdetect-secrets audit --report .secrets.baseline
# Seulement les vrais secretsdetect-secrets audit --report --only-real .secrets.baseline
# Seulement les faux positifsdetect-secrets audit --report --only-false .secrets.baselineStatistiques de précision
Section intitulée « Statistiques de précision »Après un audit interactif, mesurez la précision de vos plugins :
detect-secrets audit --stats .secrets.baselineBase64HighEntropyString: - Precision: 75% (3 / 4 labelled secrets) - Recall: 60% (3 / 5 known true secrets)Comparer deux configurations
Section intitulée « Comparer deux configurations »Pour optimiser vos réglages, comparez deux baselines :
detect-secrets scan --base64-limit 4 > limit4.jsondetect-secrets scan --base64-limit 5 > limit5.jsondetect-secrets audit --diff limit4.json limit5.jsonIntégration pre-commit
Section intitulée « Intégration pre-commit »La méthode recommandée par la documentation officielle est d’utiliser le framework pre-commit :
-
Créer la baseline :
Fenêtre de terminal detect-secrets scan > .secrets.baseline -
Configurer le hook dans
.pre-commit-config.yaml:.pre-commit-config.yaml repos:- repo: https://github.com/Yelp/detect-secretsrev: v1.5.0hooks:- id: detect-secretsargs: ['--baseline', '.secrets.baseline']exclude: package.lock.json -
Installer les hooks :
Fenêtre de terminal pre-commit install -
Tester : essayez de commiter un fichier contenant un secret non listé dans la baseline. Le commit sera bloqué.
Intégration CI/CD
Section intitulée « Intégration CI/CD »GitHub Actions
Section intitulée « GitHub Actions »name: Detect Secretson: [push, pull_request]
jobs: detect-secrets: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install detect-secrets run: pip install detect-secrets - name: Scan for secrets run: | detect-secrets scan --baseline .secrets.baseline git ls-files -z | xargs -0 detect-secrets-hook --baseline .secrets.baselineGitLab CI
Section intitulée « GitLab CI »detect-secrets: image: python:3.12-slim stage: test before_script: - pip install detect-secrets script: - detect-secrets scan --baseline .secrets.baseline - git ls-files -z | xargs -0 detect-secrets-hook --baseline .secrets.baselineUtilisation comme bibliothèque Python
Section intitulée « Utilisation comme bibliothèque Python »detect-secrets peut aussi être utilisé directement dans vos scripts Python :
from detect_secrets import SecretsCollectionfrom detect_secrets.settings import default_settings
secrets = SecretsCollection()with default_settings(): secrets.scan_file('config.env')
import jsonprint(json.dumps(secrets.json(), indent=2))Pour une configuration personnalisée :
from detect_secrets import SecretsCollectionfrom detect_secrets.settings import transient_settings
secrets = SecretsCollection()with transient_settings({ 'plugins_used': [ {'name': 'AWSKeyDetector'}, {'name': 'Base64HighEntropyString', 'limit': 5.0}, ],}) as settings: secrets.scan_file('config.env')detect-secrets vs Gitleaks vs TruffleHog
Section intitulée « detect-secrets vs Gitleaks vs TruffleHog »| Critère | detect-secrets | Gitleaks | TruffleHog |
|---|---|---|---|
| Langage | Python | Go | Go |
| Approche | Baseline + diff | Scan complet | Scan complet |
| Historique Git | Non (seulement les fichiers actuels) | Oui | Oui |
| Vérification des secrets | Oui (certains plugins) | Non | Oui (800+ détecteurs) |
| Plugins custom | Oui (fichiers Python) | Oui (règles TOML) | Non |
| Filtres custom | Oui (fichiers Python) | Oui (allowlists TOML) | Non |
| Audit interactif | Oui | Non | Non |
| Pre-commit | Oui (natif) | Oui | Oui |
| Performance | Rapide (pas d’historique) | Très rapide (Go) | Rapide (Go) |
| Cas d’usage idéal | Prévention progressive en entreprise | Scan complet d’historique | Scan multi-sources (Git, Docker, S3) |
Limites et pièges
Section intitulée « Limites et pièges »| Limitation | Conséquence | Contournement |
|---|---|---|
| Pas de scan d’historique | Les secrets déjà commités ne sont pas détectés | Utiliser Gitleaks ou TruffleHog en complément |
| Secrets multi-lignes | Non détectés par défaut | Écrire un plugin custom |
| Mots de passe faibles | login = "hunter2" passe si le KeywordDetector ne match pas le nom de variable | Combiner avec un mot-clé personnalisé |
| Maintenance de la baseline | Doit être mise à jour régulièrement | Automatiser avec detect-secrets scan --baseline |
| Pas de scan Docker/S3 | Limité aux fichiers locaux et Git | Utiliser TruffleHog pour ces cibles |
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause | Solution |
|---|---|---|
Did not detect git repository | Version de Git < 1.8.5 | Mettre à jour Git |
Not a valid baseline file! (Windows) | Encodage du fichier incorrect | S’assurer que .secrets.baseline est en UTF-8 |
Baseline vide ("results": {}) | Les fichiers ne sont pas trackés par Git | Ajouter les fichiers avec git add ou utiliser --all-files |
Your baseline file is unstaged | .secrets.baseline pas dans la zone de staging | Exécuter git add .secrets.baseline |
| Trop de faux positifs | Seuils d’entropie trop bas ou plugins trop larges | Ajuster --base64-limit, --exclude-lines, ou --disable-plugin |
À retenir
Section intitulée « À retenir »- detect-secrets adopte une approche baseline : il accepte les secrets existants et empêche les nouveaux d’entrer.
- Le scan par défaut ne couvre que les fichiers trackés par Git (pas l’historique des commits).
- 27 plugins couvrent les principaux fournisseurs cloud, tokens, clés privées et mots de passe.
- Les filtres (exclusions, allowlist inline, word-list) permettent de gérer les faux positifs.
detect-secrets-hookest le gardien au quotidien : il bloque les commits contenant de nouveaux secrets.- L’audit interactif permet de labelliser les résultats et de mesurer la précision des plugins.
- Pour un scan d’historique complet, combinez avec Gitleaks ou TruffleHog.