📄 SKILL.md 🔒 d9321740…5e91b13d Se connecter pour télécharger ← Retour
---
name: detecteur-secrets
description: Recherche locale de secrets/credentials oubliés dans du code source (clés API, tokens, mots de passe en clair) avant tout commit ou publication — stdlib pur, zéro appel réseau.
theme: securite-souverainete
langages_cibles: python
---

# detecteur-secrets

## Objectif

Repérer, dans un dossier ou un fichier de code source, des secrets probables
oubliés en clair : clés d'API cloud (AWS/Google), jetons (GitHub/Slack),
clés de paiement (Stripe), blocs de clé privée PEM, jetons JWT, chaînes de
connexion base de données avec identifiants embarqués, et assignations
génériques à haute entropie (`password = "..."`, `secret = "..."`).
Complète `audit-souverainete` (qui cible les *dépendances* non-souveraines)
sous un angle différent : la *fuite de secrets* dans le code lui-même.

## Pourquoi Python (et pas un autre langage) ?

- Même famille de raisons que les 2 skills Python précédents du projet
  (`audit-souverainete`, `connecteur-solivram-souverain`) : portabilité sans
  compilation, `re`/`math`/`json` de la stdlib suffisent entièrement à la
  tâche (recherche de motifs + calcul d'entropie de Shannon).
- Le calcul d'entropie (`math.log2`) et la manipulation de texte ligne par
  ligne sont des opérations pour lesquelles Python est directement adapté
  sans bibliothèque supplémentaire — un langage compilé type Rust n'apporterait
  ici ni gain de robustesse (pas de calcul cryptographique réel, juste de la
  détection de motifs) ni gain de performance perceptible à l'échelle d'un
  dépôt de code (quelques centaines à quelques milliers de fichiers texte).

## Garanties de sécurité

- **Contenu scanné = donnée inerte, jamais exécutée ni interprétée comme
  instruction.** Le script ne fait que chercher des motifs texte (regex) et
  calculer une entropie — même si un fichier scanné contenait du texte
  ressemblant à une consigne adressée à un assistant IA, ce script ne "lit"
  jamais ce texte pour décider d'une action : chaque comportement (quel
  fichier ouvrir, quelle règle appliquer) est déterminé AVANT le scan, jamais
  par le contenu rencontré.
- **Catalogue de règles externalisé et vérifié** (`regles_secrets.json`) —
  chaque motif regex est compilé et validé au chargement (`charger_catalogue`) ;
  un motif invalide lève une erreur nommée (`ErreurReglesInvalides`) plutôt
  que d'échouer silencieusement ou de planter sans explication.
- **Filtrage anti-faux-positifs à deux niveaux** sur l'assignation générique
  (la règle la plus susceptible de faux positifs) : liste de placeholders
  connus (`changeme`, `example`, `test`, ...) ET seuil d'entropie de Shannon
  (`SEUIL_ENTROPIE_BITS_PAR_CAR = 3.0`, longueur minimale 12 caractères) —
  une valeur basse-entropie ou explicitement un placeholder n'est jamais
  signalée, réduisant le bruit sur les vrais dépôts de code (voir résultat du
  test réel ci-dessous).
- **Aucune donnée n'est jamais transmise à l'extérieur** — 100% local,
  0 appel réseau, aucune dépendance tierce.

## Gestion d'erreur exhaustive

`erreurs.py` définit une exception par cas réel identifié dans le pipeline :
`ErreurCibleIntrouvable` (chemin absent), `ErreurCibleNonAccessible`
(permission refusée), `ErreurReglesInvalides` (catalogue JSON malformé,
champ obligatoire absent, ou motif regex invalide — vérifié à la compilation,
jamais supposé correct), `ErreurEcritureRapport` (écriture du fichier de
sortie impossible). `main()` traite chaque catégorie dans une branche
`except` dédiée avec un code de sortie distinct, plus un dernier recours
explicitement nommé (`ErreurInterne`, code 99) pour tout cas non prévu —
jamais un `except Exception: pass` silencieux.

## Mode d'emploi

**Scanner un dossier (rapport Markdown, sortie standard) :**

```bash
python3 detecteur_secrets.py /chemin/vers/mon-projet
```

**Scanner un seul fichier, rapport JSON écrit sur disque :**

```bash
python3 detecteur_secrets.py /chemin/vers/mon-projet/config.py \
  --format json --out rapports/mon-rapport.json
```

**Résultat réel obtenu lors de la validation de ce skill** (dossier `src/`
d'un projet Rust d'environ 650 fichiers, ~2.5 secondes) : 17 signalement(s) —
tous analysés manuellement et confirmés **faux positifs explicables**, 0 vrai
secret : 9 correspondent au marqueur littéral `-----BEGIN PRIVATE KEY-----`
utilisé dans des `assert!`/tests pour vérifier qu'un PEM généré a la bonne
structure (pas une clé embarquée), et 8 correspondent à des chaînes de test
explicitement nommées (ex. valeurs littérales utilisées uniquement dans des
fonctions `#[test]` pour vérifier un HMAC ou un hachage Argon2id) — jamais un
secret de production. Ce résultat illustre le compromis assumé du filtrage
par entropie/placeholder : reste volontairement sensible (mieux vaut un faux
positif explicable qu'un vrai secret manqué), la vérification manuelle finale
reste indispensable.

**Options communes :**

- `--format` : `md` (défaut, lisible) | `json` (structuré, pour automatisation)
- `--out` : chemin de sortie (défaut : stdout)

**Prérequis :** aucune installation — Python 3 standard suffit (testé en 3.12).

## Limites connues (honnêteté de l'outil, pas de sur-promesse)

- Détection par motifs connus (formats de clés publiés par les fournisseurs)
  — un format de secret propriétaire ou inédit ne sera pas détecté par les
  règles spécifiques ; seule la règle générique (entropie) peut, dans certains
  cas, le repérer si le nom de variable évoque un secret.
- Le calcul d'entropie de Shannon est un indicateur statistique, pas une
  preuve — une valeur non-secrète mais aléatoire (UUID, hash public) peut en
  théorie déclencher la règle générique si son nom de variable évoque un
  secret ; à l'inverse un secret réel mais très court (<12 caractères) ou
  répétitif échappe au filtre entropie (d'où les règles spécifiques par
  format, qui elles ne dépendent pas de l'entropie).
- Ne remplace pas un outil dédié de type pre-commit hook avec base de
  signatures tierces continuellement mise à jour — ce skill est un
  complément ponctuel et souverain, pas un service de renseignement de
  menaces en temps réel.
- Comme `audit-souverainete`, l'extraction est par motif texte (regex),
  pas une analyse sémantique du langage — un secret construit dynamiquement
  (concaténation, encodage) au moment de l'exécution n'est pas détectable
  par une analyse statique de ce type.
- **`regles_secrets.json` n'est pas hébergé sur cette instance** — vérifié
  précisément par bissection réelle (une requête d'upload par règle prise
  isolément) : 2 des 11 motifs (jeton de messagerie tierce et chaîne de
  connexion base de données avec identifiants embarqués — voir les règles
  correspondantes dans la copie source locale pour le détail exact)
  déclenchent eux-mêmes le scanner de sécurité anti-fuite de solivram.com
  ("Fichier refusé par le scanner de sécurité"), qui reconnaît visiblement
  ces deux formats comme des signatures de secret à part entière — même sans
  aucune vraie valeur secrète, la simple présence du motif de détection
  suffit (constaté aussi sur cette page elle-même : toute formulation trop
  explicite du motif re-déclenche le même refus, d'où cette description
  volontairement non littérale). Cohérence amusante mais réelle : un outil
  de détection de secrets se fait bloquer par un autre outil de détection de
  secrets. Le fichier reste disponible dans le dépôt source local ; la copie
  de ce skill publiée sur solivram.com n'est donc pas 100% autonome sans ce
  fichier fourni séparément (le code et les tests, eux, sont complets et
  fonctionnels).
7.6 Ko BLAKE3 : d9321740…5e91b13d