Le problème
Une clé d'API poussée dans un dépôt, même supprimée au commit suivant, reste dans l'historique. Des robots scrutent GitHub en permanence : une clé publique est souvent exploitée en quelques minutes.
Règle numéro un : jamais dans le code
// ❌ Secret en dur
const client = new Stripe("sk_live_abc123");
// ✅ Lu depuis l'environnement
const client = new Stripe(process.env.STRIPE_SECRET_KEY);Le fichier .env
En local, un fichier .env regroupe les variables. Il doit être ignoré par Git :
# .gitignore
.env
.env.*
!.env.exampleOn versionne en revanche un .env.example sans valeurs réelles, pour documenter ce qui est attendu :
DATABASE_URL=
STRIPE_SECRET_KEY=Côté Next.js
Seules les variables préfixées par NEXT_PUBLIC_ sont envoyées au navigateur. Tout le reste reste côté serveur.
Ne préfixez jamais un secret par
NEXT_PUBLIC_: il serait embarqué dans le JavaScript public.
En CI/CD
- Stockez les secrets dans le gestionnaire de la plateforme (GitHub Actions Secrets).
- Donnez à chaque secret le moindre privilège : une clé en lecture seule si l'écriture est inutile.
- Ne les affichez jamais dans les logs.
Détecter les fuites
Des outils analysent le code et l'historique :
# Analyse de l'historique complet
gitleaks detect --source .
# Analyse avant chaque commit
gitleaks protect --stagedBranchez-les dans un hook de pré-commit et dans la CI.
Que faire en cas de fuite ?
- Révoquer immédiatement la clé (la réécriture de l'historique ne suffit pas).
- En générer une nouvelle.
- Vérifier les journaux d'usage de l'ancienne.
- Seulement ensuite, nettoyer l'historique si nécessaire.
La rotation
Changez régulièrement les secrets, et surtout lors du départ d'un membre de l'équipe. Une rotation facile à faire est une rotation qui sera faite : automatisez-la quand c'est possible.
À retenir
- Un secret commité est un secret compromis.
.envignoré,.env.exampleversionné.- Moindre privilège et rotation.
- Un scanner dans la CI vaut mieux qu'une bonne résolution.