Aller au contenu principal

Rotation

Disponible

Fonctionnalité déployée et prise en charge. Les champs et commandes décrits ici sont stables au sein de la version v1alpha1.

La rotation remplace la valeur d'un secret par une nouvelle valeur aléatoire, stockée comme nouvelle version. Vous pouvez la déclencher vous-même (sng secret rotate) ou la confier à la plateforme, qui renouvelle la valeur tous les N jours sans intervention (--rotation N). Vos applications reçoivent la nouvelle valeur automatiquement.

Prérequis​

  • Un secret existant avec une valeur : voir Créer et lire un secret.
  • sng secret rotate lit puis réécrit le secret : il faut ssm:read et ssm:write (policies readwrite ou admin).
  • L'application qui consomme le secret doit savoir relire sa configuration au redémarrage — c'est le cas de toute App déployée avec StackNGO, qui est redémarrée pour vous (voir plus bas).

1. Renouveler maintenant​

sng secret rotate db-password
secret "db-password" rotated: new 16-character value (sng secret get db-password)

La nouvelle valeur est générée par la CLI avec les mêmes options que sng secret set : --length, --contains, --exclude-chars, --no-lowercase, --no-uppercase, --no-numbers, --no-symbols, --require-each-type.

sng secret rotate api-key --length 40 --contains letters,numbers

Pour un secret à plusieurs clés (posé avec --data), désignez la clé à renouveler ; les autres sont conservées :

sng secret rotate shop-api --key SMTP_PASSWORD
secret "shop-api" rotated: new 16-character value for key "SMTP_PASSWORD"

Sans --key sur un secret multi-clés, la commande refuse : the secret holds several keys (DATABASE_URL, SMTP_HOST, SMTP_PASSWORD): choose one with --key.

2. Armer une rotation automatique​

sng secret set db-password --rotation 30 --length 24 --contains letters,numbers
secret "db-password" saved with a generated 24-character value (sng secret get db-password)

À partir de maintenant, la plateforme génère une nouvelle valeur de 24 caractères (lettres et chiffres) tous les 30 jours. Les options de génération passées avec --rotation décrivent la valeur future : à l'échéance, aucun client n'est là pour les choisir, la plateforme doit les connaître. C'est pourquoi elles restent acceptées même quand vous fournissez la valeur initiale :

# valeur initiale fournie, renouvelée par la plateforme tous les 90 jours
sng secret set db-password --from-file ./initial --rotation 90 --length 32

--rotation s'applique aussi à sng secret rotate, pour renouveler tout de suite et armer la suite :

sng secret rotate db-password --rotation 30

Pour un secret multi-clés, --rotation-key dit quelle clé la plateforme devra renouveler (obligatoire si le secret a plusieurs clés, sinon la rotation planifiée échoue) :

sng secret set shop-api --data DATABASE_URL=… --data SMTP_PASSWORD=… \
--rotation 60 --rotation-key SMTP_PASSWORD

Vérifiez la planification :

sng secret describe db-password
{
"name": "db-password",
"keys": ["value"],
"version_id": "2",
"rotation_enabled": true,
"rotation_days": 30,
"next_rotation_date": "2026-11-06T10:02:17Z",
"version_stages": { "current": "2" },
"bindings": { "...": "..." }
}

3. Modifier ou désarmer​

Vous voulezCommande
Changer l'intervallesng secret set NAME --rotation 15 (l'échéance repart d'aujourd'hui)
Changer la forme de la future valeursng secret set NAME --rotation 30 --length 40 (même intervalle : l'échéance en cours est conservée)
Désarmersng secret set NAME --rotation 0, ou l'API POST /v1/secrets/NAME/rotate/cancel (sans toucher la valeur)
Ne rien changer à la rotationn'indiquez pas --rotation : un set ordinaire conserve la planification en place

Un sng secret set NAME --rotation 0 seul, sans valeur, génère aussi une nouvelle valeur (c'est un set). Pour désarmer sans toucher la valeur, repassez la valeur courante : sng secret get NAME --key value --out-file ./cur && sng secret set NAME --from-file ./cur --rotation 0.

Annuler la rotation planifiée sans toucher la valeur​

La route POST /v1/secrets/{name}/rotate/cancel désarme la rotation planifiée : la valeur et les versions ne changent pas, la prochaine échéance disparaît. Elle exige l'action ssm:rotate sur ce secret. Il n'existe pas de commande sng dédiée.

curl -s -X POST -H "Authorization: Bearer $SESSION" \
https://api.dev.stackngo.fr/v1/secrets/db-password/rotate/cancel
{
"name": "db-password",
"keys": ["value"],
"version_id": "4"
}

La réponse ne contient plus rotation_enabled ni next_rotation_date : la rotation est désarmée. L'appel réussit aussi sur un secret dont la rotation est déjà désarmée ; il répond 404 si le secret n'existe pas ou a été supprimé. sng secret describe db-password ne montre plus non plus d'échéance.

Secret déclaré par manifeste

Si le secret est déclaré par un manifeste SSMSecret qui porte rotateDays, le manifeste fait foi : la rotation est réarmée d'elle-même, au plus tard 6 heures après l'annulation. Pour l'arrêter durablement, retirez rotateDays du manifeste (ou mettez 0) et réappliquez.

Rotation à la demande, rotation planifiée​

  • La rotation à la demande (sng secret rotate) est faite par votre CLI : elle lit la valeur courante, en génère une nouvelle et l'enregistre. Elle exige donc ssm:read et ssm:write.
  • La rotation planifiée est faite par la plateforme, sans aucun client connecté. À l'échéance (vérifiée chaque minute), une nouvelle valeur est générée selon les options enregistrées, enregistrée comme nouvelle version, et l'échéance suivante est fixée à maintenant + N jours. La plateforme ne peut que faire générer une valeur : elle ne la lit pas et ne peut pas en choisir une.
  • Une policy gérée réservée à la rotation est présente dans chaque tenant (visible avec sng tenant policy list). Ne la retirez pas. Si vos propres policies refusent ssm:rotate sur ce secret, la rotation échoue ; après 5 échecs consécutifs, elle est désarmée (rotation_enabled disparaît de describe) pour ne pas réessayer indéfiniment. Réarmez-la après avoir corrigé la policy.
  • La rotation remplace la valeur quelle que soit son origine, y compris une valeur posée à la main avec --from-file.

Comment une App voit la nouvelle valeur​

Une App référence un secret par son nom (env: { DB_PASSWORD: { secret: db-password, key: value } }). Après chaque écriture, manuelle ou planifiée :

  1. dans les 5 minutes, la plateforme constate la nouvelle version ;
  2. les services deployment qui lisent ce secret sont redémarrés en douceur : les nouveaux conteneurs démarrent avec la nouvelle valeur avant que les anciens s'arrêtent ;
  3. les job et cronjob ne sont pas redémarrés : leur prochaine exécution lit la nouvelle valeur.

Conséquence : une rotation entraîne un redémarrage de vos services dans les 5 minutes. Dimensionnez replicas et strategy pour qu'il soit sans interruption, et évitez de faire tourner un secret dont la nouvelle valeur doit aussi être posée ailleurs (base de données externe, fournisseur SMTP) sans avoir prévu l'étape correspondante : la rotation ne met à jour que le secret, pas le service qui le vérifie.

Vérification​

sng secret versions db-password # une version de plus après chaque rotation
sng secret describe db-password # next_rotation_date avance de N jours
sng kind get App shop # l'App est repassée par un déploiement

Si ça ne marche pas​

Ce que vous voyezCauseCorrection
the secret holds several keys (…): choose one with --keySecret multi-clés sans --keyAjouter --key (ou --rotation-key pour la rotation planifiée)
rotation_enabled absent de describe alors que vous l'aviez armée5 rotations planifiées ont échoué d'affilée, souvent à cause d'une policy qui refuse ssm:rotate ; ou quelqu'un a annulé la rotationCorriger la policy, puis réarmer avec --rotation N
La rotation revient après une annulationLe secret est déclaré par un SSMSecret avec rotateDaysRetirer rotateDays du manifeste
Le service qui vérifie le mot de passe le refuse après une rotationLa rotation n'a changé que le secret, pas le service externeDésarmer la rotation pour ce secret, ou mettre à jour le service externe à chaque rotation
forbidden (…) sur sng secret rotateIl manque ssm:read ou ssm:writeDemander readwrite à un administrateur

Pour aller plus loin​

  • Bornes : --rotation accepte de 1 à 3650 jours ; --length de 1 à 4096.
  • Échéance : réarmer le même intervalle ne repousse pas l'échéance (sinon des set fréquents la reporteraient sans fin). Un intervalle différent repart d'aujourd'hui.
  • Secret déclaré par manifeste : spec.rotateDays d'un SSMSecret arme la même rotation planifiée, avec spec.length et spec.contains comme forme de la future valeur. status.nextRotationAt en reflète l'échéance.
  • API : la politique voyage dans le champ rotation_policy du corps de PUT /v1/secrets/{name} : {"enabled": true, "interval_days": 30, "key": "SMTP_PASSWORD", "generation": {"length": 24, "contains": ["lower","upper","number"], "exclude_chars": "", "require_each_type": true}}. Les classes côté API sont lower, upper, number, symbol. {"enabled": false} désarme ; champ absent = inchangé.
  • POST /v1/secrets/{name}/rotate (action ssm:rotate) existe dans l'API mais ne fait pas ce que fait sng secret rotate : il renouvelle le chiffrement de la valeur courante sans la changer. Il crée une version mais ne renouvelle pas le mot de passe.

Voir aussi​