Contexte / besoin
Une plateforme de services, ce sont des dizaines de credentials : mots de
passe de bases de données, tokens d’API, clés d’accès à l’API du registrar
pour le TLS. Le risque n’a rien d’exotique : un secret committé par erreur,
une variable d’environnement qui fuite dans un log ou un docker inspect,
un token stocké en clair côté serveur.
Contraintes
- Tout est versionné. C’est la force du setup (configuration déclarative, reproductible), et ça impose une frontière nette entre Git et les secrets.
- Un seul mainteneur. La solution doit être simple à appliquer à chaque fois, sans jamais exiger d’héroïsme.
Décision & pourquoi
Plutôt qu’un outillage lourd, une hygiène systématique, appliquée partout.
- Rien dans Git. Les fichiers d’environnement et répertoires de secrets
sont ignorés dès la création du dépôt. Les templates committés
(
.env.example) documentent les variables attendues, sans valeur. - Injection par fichiers plutôt que par variables d’environnement quand
l’image le permet (ex.
POSTGRES_PASSWORD_FILE). Le secret n’apparaît ni dansdocker inspect, ni dans l’environnement hérité par les processus. - Jamais de token en clair côté serveur. Les tokens d’API, comme ceux du Hub, sont stockés hachés en SHA-256. Une fuite de la base ne divulgue alors aucun credential réutilisable.
- Coffre Vaultwarden auto-hébergé, accessible uniquement du tailnet, comme source de vérité pour les secrets humains : génération, stockage, partage.
Tradeoff assumé
Pas de gestionnaire de secrets centralisé côté serveur (type Vault ou sops/age). À l’échelle d’un mainteneur unique, la discipline de fichiers et le coffre couvrent le besoin sans ajouter une pièce critique de plus. Si la plateforme grossit (plusieurs opérateurs, rotation automatique), ce choix sera revu.
Résultat
- Sécurisé : un dépôt public ou une base compromise ne divulguent pas de secret exploitable. La surface de fuite (logs, inspect, environnement) est réduite à la source.
- Maintenable : des règles simples et identiques partout. N’importe quel service de la plateforme suit le même contrat.
Posture : auditer, trouver, corriger
L’hygiène n’est pas un état, c’est une pratique. Repasser régulièrement sur l’existant, chercher les secrets qui traînent (historique Git, configurations, logs), corriger, et révoquer ce qui a été exposé, même brièvement. Un secret qui a fui reste compromis tant qu’il n’est pas remplacé.
Exemple vécu, juillet 2026. Un audit de sécurité volontaire des dépôts de la
plateforme révèle une clé privée WireGuard committée en clair dans un
docker-compose, depuis le premier commit du dépôt, soit plusieurs semaines
d’exposition potentielle. Doctrine appliquée : un secret exposé est un secret
compromis. La clé est retirée du fichier puis rendue définitivement caduque
(le VPN qu’elle servait a été décommissionné). Et comme l’historique Git
garde tout, la règle de publication en a été durcie : un dépôt rendu public
repart d’un historique neuf.
L’audit reste manuel aujourd’hui ; son outillage (scan automatique de l’historique, hooks de pre-commit) est un chantier de la roadmap.