La règle cardinale
Tout ce qui est commité dans Git est permanent jusqu'à ce que vous réécriviez activement l'historique. Tout ce qui est poussé sur un remote doit être considéré comme exposé.
Couche 1 : ne jamais commiter de secrets
# .env.example
DATABASE_URL=postgres://localhost/myapp
JWT_SECRET=replace-me
# .gitignore
.env
.env.local
.env.*.local
*.pem
*.key
secrets/
Couche 2 : détection pre-commit
brew install gitleaks
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks
gitleaks detect --redact --source=.
Couche 3 : rejet côté serveur
Un hook pre-receive sur le serveur peut rejeter les pushes contenant des secrets.
Couche 4 : scan en CI
- uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Couche 5 : secrets chiffrés dans Git
sops -e -i secrets.yaml
sops secrets.yaml
git add secrets.yaml
git commit -m "Update encrypted secrets"
Si un secret fuit
- Tourner immédiatement.
- Auditer les logs d'usage.
- Réécrire l'historique.
- Force-push.
- Notifier.
# patterns.txt
AKIAIOSFODNN7EXAMPLE==>REDACTED
sk_live_abc123==>REDACTED
Récupération sur le host
Même après force-push, GitHub conserve les commits "dangling" accessibles par SHA pendant un certain temps.