Gérer les secrets
Voici le problème avec les forks : ce sont des copies octet par octet de l’image chiffrée, identifiants y compris. Une clé Stripe de production, un mot de passe de base de données, un token API dans le dépôt ? Le fork les hérite. Votre sandbox finit par facturer de vrais clients.
Le bon endroit est rdc repo secret. Deux modes de livraison, en écriture seule par conception, et le fork démarre avec rien. Dans ce tutoriel, nous configurons les deux types, déployons une application qui les consomme, prouvons que les valeurs arrivent vraiment dans le conteneur, puis regardons un fork échouer à démarrer parce que les secrets ont refusé de le suivre.
Regarder le tutoriel
Le piège : .env dans le dépôt
La plupart des équipes mettent .env dans le dépôt. C’est le geste évident.
Puis elles forkent.
Le fork est une copie octet par octet de l’image du parent. Ce qui se trouve dans .env se retrouve dans le .env du fork. Les conteneurs du fork démarrent. Ils lisent la même clé Stripe. Ils appellent la même API Stripe avec les identifiants de production. Du côté de Stripe, cet appel, c’est vous.
C’est une mauvaise journée. Demandez-moi comment je le sais.
Étape 1 : Définir un secret en mode env
rdc repo secret set --name my-app --key DB_HOST --value postgres.internal --mode env D'abord, définissez un secret en mode env. La valeur arrive comme variable d'environnement dans le container. Les premières écritures ne demandent aucune formalité. C'est l'écrasement d'un secret existant qui exige une preuve.
--mode env fait atterrir la valeur comme variable d’environnement dans le conteneur. Les premières écritures ne nécessitent aucune cérémonie ; c’est l’écrasement d’un secret existant qui exige la preuve de la valeur actuelle.
Étape 2 : Définir un secret en mode file
rdc repo secret set --name my-app --key STRIPE_KEY --value sk_test_xxx --mode file Définissez maintenant un secret en mode fichier. Le mode fichier n'expose jamais la valeur via l'environnement du container. Il écrit la valeur dans un fichier sous /run/secrets en utilisant le mécanisme standard de secrets de Docker. Préférez le mode fichier pour tout ce qui est sensible.
Le mode file ne place jamais la valeur dans l’environnement du conteneur. Il l’écrit à /run/secrets/stripe_key à la place, en utilisant le mécanisme standard de Docker. Préférez ceci pour tout ce qui est sensible.
Étape 3 : Lister ce que vous avez
rdc repo secret list --name my-app Listons ce que nous avons. Les noms et les modes uniquement. La liste n'affiche jamais les valeurs, peu importe qui pose la question.
Vous voyez les noms et les modes. Aucune valeur. La liste n’affiche jamais les valeurs, peu importe qui demande.
L’intégrer dans compose
Ouvrez docker-compose.yml. Référencez les deux modes :
services:
api:
image: myapp:latest
environment:
DATABASE_HOST: ${REDIACC_SECRET_DB_HOST}
secrets:
- stripe_key
secrets:
stripe_key:
file: /var/run/rediacc/secrets/${REDIACC_NETWORK_ID}/STRIPE_KEY
${REDIACC_SECRET_DB_HOST} est le mode env : le wrapper compose de renet le développe depuis votre store de secrets au moment du déploiement.
Le bloc secrets: est le mode file, utilisant le mécanisme standard de Docker. Le chemin hôte utilise ${REDIACC_NETWORK_ID} pour que le même compose fonctionne pour les parents et les forks. Chaque fork a son propre identifiant réseau.
Vous ne pouvez jamais le relire
Voici la partie qui surprend tout le monde la première fois, moi y compris.
Étape 4 : Get retourne un digest
rdc repo secret get --name my-app --key STRIPE_KEY La commande secret get renvoie un condensé, pas la valeur, et il n'existe aucun flag pour récupérer le texte en clair. Cela suit le modèle GitHub Actions : les secrets sont en écriture seule par conception.
Vous obtenez un digest. Pas la valeur. Il n’y a pas de flag qui le fait retourner la valeur. Il n’existe aucune commande qui vous donnera le texte en clair.
C’est le modèle GitHub Actions : en écriture seule. Vous pouvez prouver que vous connaissez un secret en passant --current <valeur> et en observant la précondition réussir. Vous ne pouvez pas demander à Rediacc de vous dire ce que c’est.
Étape 5 : Faire une rotation quand vous oubliez
Perdu la valeur ? Ne regardez pas. Faites une rotation.
rdc repo secret set --name my-app --key STRIPE_KEY --value sk_test_new --mode file --rotate-secret Si vous perdez trace de la valeur d'un secret, faites-en la rotation plutôt que d'essayer de la récupérer. Le flag rotate-secret ignore la vérification des prérequis et le journal d'audit enregistre le changement comme une rotation délibérée.
--rotate-secret ignore la précondition. Le journal d’audit marque l’opération comme une rotation : explicite, délibérée.
Si vous vous souvenez de l’ancienne valeur, prouvez-le plutôt avec --current <old-value>. C’est la voie la plus sûre. Ça m’a sauvé plus d’une fois quand j’étais dans le mauvais terminal ou sur la mauvaise machine.
Déployer et prouver la livraison
Les secrets qui n’atteignent jamais l’application ne sont qu’une base de données sophistiquée. Déployez et vérifiez les deux chemins de livraison.
Étape 6 : Déployer avec les deux secrets
rdc repo up --name my-app --machine <machine-name> Déployez le repo. Le fichier compose utilise les deux secrets : la valeur env par interpolation, la valeur fichier via un montage de secrets Docker.
Étape 7 : Le secret env arrive
rdc term connect --machine <machine-name> --repository my-app --command 'docker exec app printenv DB_HOST' Affichez la variable dans le container : postgres.internal. Le secret en mode env a atteint l'application au moment du déploiement.
Le conteneur affiche postgres.internal. L’application a vraiment reçu la valeur, développée dans son environnement au moment du déploiement.
Étape 8 : Le secret file arrive
rdc term connect --machine <machine-name> --repository my-app --command 'docker exec app cat /run/secrets/stripe_key' Lisez /run/secrets/stripe_key dans le container : la valeur après rotation y est montée. L'application obtient le texte en clair ; seul le CLI refuse de l'afficher.
Et voilà la valeur après rotation, lue depuis /run/secrets/stripe_key à l’intérieur du conteneur. L’écriture seule s’applique aux humains et au CLI ; votre application obtient le vrai texte en clair là où Docker le promet.
La révélation du fork
Vous souvenez-vous du piège ? Forkez le dépôt et regardez.
Étape 9 : Forker le dépôt
rdc repo fork --parent my-app --tag test --machine <machine-name> Forkez le repo. Le fork est une copie octet par octet de l'image chiffrée du parent.
Étape 10 : Le fork liste vide
rdc repo secret list --name my-app:test Lister les secrets du fork renvoie un ensemble vide : pas de clé Stripe, pas de mot de passe de base de données, pas de token API. Le fork ne peut pas se faire passer pour le parent, ce qui rend le clonage de la production sûr.
Vide.
Le fork n’a pas de clé Stripe. Pas de mot de passe de base de données. Pas de token API. Les conteneurs du fork ne peuvent pas interpoler ${REDIACC_SECRET_STRIPE_KEY}. Le fichier à /var/run/rediacc/secrets/<fork-id>/STRIPE_KEY n’existe pas.
Le fork ne peut pas se faire passer pour vous.
Étape 11 : Le fork ne peut même pas démarrer
rdc repo up --name my-app:test --machine <machine-name> Démarrer le fork avec le compose du parent échoue : le fichier secret n'existe pas sous l'ID réseau du fork, donc Docker refuse le montage bind. Les identifiants de production ne suivent jamais un fork.
Le déploiement échoue exprès : bind source path does not exist: /var/run/rediacc/secrets/<fork-id>/STRIPE_KEY. Le fichier secret vit sous l’identifiant réseau du parent, pas celui du fork, donc Docker refuse le montage. L’échec est la démonstration : les identifiants de production ne suivent jamais un fork, même par accident.
Si vous voulez des secrets dans le fork pour les tests, définissez-les explicitement sur le fork avec des valeurs sandbox, par exemple rdc repo secret set --name my-app:test --key STRIPE_KEY --value sk_sandbox_yyy --mode file. Le fork parle alors au sandbox Stripe et démarre proprement. Les identifiants de production n’ont jamais quitté la production.
Résumé
rdc repo secretplace vos identifiants en dehors de l’image du dépôt.- Les deux modes atteignent vraiment le conteneur : interpolation env et
/run/secrets. getretourne un digest, jamais la valeur. Faites une rotation si vous oubliez ; ne regardez pas.- Le fork liste vide et ne peut même pas démarrer le compose du parent.
Des secrets que le fork ne peut pas suivre.
Suivant : Sauvegarde et restauration.