Passer au contenu principal Passer à la navigation Passer au pied de page
Offre limitée : Design Partner Program. Plan BUSINESS gratuit à vie.

Gérer les secrets

Placez vos identifiants de déploiement dans un endroit inaccessible aux forks. En écriture seule par conception.

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

Un fichier .env dans l'image du dépôt est cloné par chaque fork

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

Modèle en écriture seule : get retourne un digest, jamais la valeur

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

Après le fork, la liste des secrets est vide

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 secret place vos identifiants en dehors de l’image du dépôt.
  • Les deux modes atteignent vraiment le conteneur : interpolation env et /run/secrets.
  • get retourne 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.