Secrets et accès
Un secret, c'est une valeur qui donne un accès : un mot de passe, un jeton, une clé. Règle absolue : aucun secret en clair dans le dépôt.
Tous les secrets
| Secret | Rangé dans | Utilisé par | Donne accès à |
|---|---|---|---|
| Clé SSH d'administration | la machine de l'opérateur | Ansible | SSH avec sudo sur les deux VM |
| Mot de passe du vault | le gestionnaire de mots de passe de l'opérateur | Ansible | déchiffrer prod.yml et tooling.yml |
Jeton GitHub classique (repo, write:packages, autorisé SSO) | tooling.yml, puis le .env de Jenkins | Jenkins | lire le dépôt, pousser sur GHCR |
| Clé privée de déploiement | tooling.yml, puis un secret Docker monté dans Jenkins | Jenkins | SSH en deploy sur tm-prod |
| Clé publique de déploiement | all.yml, puis authorized_keys de deploy | tm-prod | vérifier l'identité de Jenkins |
| Jeton GHCR en lecture seule | prod.yml, puis le docker login de deploy | tm-prod | télécharger les images, rien d'autre |
| Mot de passe PostgreSQL | prod.yml, puis le .env de l'application | back, db | la base de données |
secret_key_base | prod.yml, puis le .env de l'application | back | signer les sessions et les jetons |
| Clé de l'API d'emails (Brevo) | prod.yml, puis le .env de l'application | back | envoyer les emails |
| Mot de passe admin de Jenkins | tooling.yml, puis le .env de Jenkins | l'opérateur | l'interface web de Jenkins |
| Certificats TLS | acme.json sur tm-prod | Traefik | HTTPS, renouvelés tout seuls par Let's Encrypt |
Les principes
- Aucun secret en clair dans le dépôt : les secrets sont soit dans un fichier Ansible Vault, soit générés sur les serveurs.
- Un secret, un usage : Jenkins peut écrire des images, la production ne peut que les lire.
- Des secrets en fichier quand c'est possible : la clé de déploiement est un secret Docker monté dans
/run/secrets/deploy_key, pas une variable d'environnement. - Les
.envsont générés par Ansible sur les serveurs, en mode0600. Aucun.envn'est modifié à la main.
Le chemin d'un secret
- Les secrets sont chiffrés dans
group_vars/prod.ymletgroup_vars/tooling.yml. - Au lancement du playbook, Ansible demande le mot de passe du vault et les déchiffre en mémoire.
- Il les écrit sur les serveurs dans des fichiers lisibles par leur seul propriétaire (
0600). no_log: trueempêche qu'ils apparaissent dans la sortie d'Ansible.
Les secrets d'une machine ne vont que sur elle : tm-prod ne reçoit jamais ceux de Jenkins, tm-tooling jamais ceux de la base.
Ansible Vault au quotidien
Depuis timemanager-devops/ansible/ :
# lire un fichier chiffré
ansible-vault view group_vars/prod.yml
# le modifier (ouvre l'éditeur, rechiffre à la fermeture)
ansible-vault edit group_vars/prod.yml
# changer le mot de passe du vault
ansible-vault rekey group_vars/prod.yml group_vars/tooling.ymlToujours chiffré
Ne jamais commiter un fichier de vault déchiffré : vérifier qu'il commence par $ANSIBLE_VAULT;1.1;AES256. Le mot de passe du vault ne doit jamais être dans le dépôt : il se transmet de personne à personne.
Ajouter un secret
Exemple : une nouvelle clé ma_cle pour l'API.
L'ajouter au vault :
bashansible-vault edit group_vars/prod.ymlyamlma_cle: valeur-secreteL'écrire dans le
.env, dansroles/app/tasks/main.yml:yamlMA_CLE={{ ma_cle }}La passer au conteneur, dans
app/docker-compose.yml:yamlback: environment: MA_CLE: ${MA_CLE}Appliquer :
bashansible-playbook playbook.yml --tags app --ask-vault-pass
En cas de fuite
Si un secret a été exposé (poussé en clair, copié dans un message) :
- Le révoquer à la source : nouveau jeton GitHub, nouveau mot de passe, nouvelle paire de clés SSH.
- Mettre la nouvelle valeur dans le vault.
- Relancer le rôle concerné.
- Le retirer de Git ne suffit pas : l'historique le garde. Seule la révocation compte.