Infrastructure

Azure Key Vault : récupérer un secret supprimé avant de le recréer

Un runbook de production pour qualifier la suppression d’un secret Key Vault, récupérer l’objet en soft-delete, valider ses consommateurs et décider maintien ou rollback sans exposer sa valeur.

18 août 2026 azurekey-vaultsecretssoft-deletepurge-protectionrecoverysecurityobservabilitykqlrunbookrollbackproduction

Une application démarre avec des SecretNotFound. Le secret attendu n’apparaît plus dans Key Vault alors que le déploiement fonctionnait quelques minutes plus tôt. Le recréer sous le même nom à partir d’une variable CI semble rapide, mais peut propager une valeur incertaine, casser les références versionnées et masquer la suppression initiale.

Le cas d’usage est un secret lu par trois consommateurs : une application utilise un URI sans version, un job épingle une version et une policy APIM résout le même objet. Le runbook doit prouver la suppression, récupérer l’objet soft-deleted avec une identité dédiée, puis vérifier chaque contrat. La purge et la recréation restent hors du chemin d’urgence.

Figer l’incident avant toute écriture

Consignez le nom logique, les versions référencées et les consommateurs. Ne copiez jamais la valeur du secret.

yaml key-vault-deletion-incident.yml
incident:
detected_at_utc: 2026-08-18T14:12:00Z
vault: kv-platform-prod
secret: payment-api-token
symptom: SecretNotFound
last_known_good_utc: 2026-08-18T13:55:00Z

consumers:
- name: checkout-api
  reference: unversioned
- name: settlement-job
  reference: version-pinned
- name: apim-policy
  reference: named-value

guardrails:
expose_secret_value: false
purge_allowed: false
recreate_allowed: false
recovery_requires_change_record: true

Un consommateur épinglé et un consommateur sans version ne valident pas le même contrat. Le premier attend un identifiant immuable ; le second reprendra la version active la plus récente.

Prouver l’état soft-deleted

Utilisez une identité de diagnostic sans droit de purge. Vérifiez le coffre, l’objet actif, puis l’objet supprimé.

bash 01-key-vault-deleted-secret-evidence.sh
set -euo pipefail

SUBSCRIPTION="<subscription-id>"
VAULT="kv-platform-prod"
SECRET="payment-api-token"

az account set --subscription "$SUBSCRIPTION"
az keyvault show --name "$VAULT" --query "{id:id,softDelete:properties.enableSoftDelete,purgeProtection:properties.enablePurgeProtection,retentionDays:properties.softDeleteRetentionInDays,rbac:properties.enableRbacAuthorization}" --output json

az keyvault secret show --vault-name "$VAULT" --name "$SECRET" --query "{id:id,enabled:attributes.enabled,updated:attributes.updated}" --output json || true

az keyvault secret show-deleted --vault-name "$VAULT" --name "$SECRET" --query "{name:name,recoveryId:recoveryId,deletedDate:deletedDate,scheduledPurgeDate:scheduledPurgeDate}" --output json

Si l’objet est actif, cherchez plutôt un problème de nom, version, identité ou accès. S’il est supprimé, la récupération reste possible pendant la rétention. S’il n’existe dans aucun état, arrêtez : recréer une valeur sans source autoritative relève d’une rotation de sécurité, pas d’une restauration.

La purge protection ne récupère rien. Elle empêche une suppression définitive avant la fin de la rétention et évite qu’une identité privilégiée transforme l’incident en perte irréversible.

Retrouver l’événement de suppression

Corrélez les journaux Key Vault avec le changement, pipeline ou runbook suspect.

kusto 02-key-vault-delete-recover-timeline.kql
let Vault = "kv-platform-prod";
let Secret = "payment-api-token";
let WindowStart = datetime(2026-08-18T13:30:00Z);
let WindowEnd = datetime(2026-08-18T15:30:00Z);
AzureDiagnostics
| where TimeGenerated between (WindowStart .. WindowEnd)
| where ResourceProvider == "MICROSOFT.KEYVAULT"
| where Resource has Vault
| where OperationName has_any ("SecretDelete", "SecretRecover", "SecretGet")
| where requestUri_s has Secret
| project TimeGenerated, OperationName, ResultType, ResultSignature,
        identity_claim_appid_g, identity_claim_oid_g,
        CallerIPAddress, requestUri_s, correlationId_g
| order by TimeGenerated asc

Les colonnes varient selon la collecte. Conservez la chaîne de preuve : heure UTC, opération, résultat, identité, adresse source, URI et corrélation. Un trou de logs devient une action corrective ; il n’autorise pas à inventer la cause.

Préparer une récupération bornée

L’identité d’urgence reçoit le droit recover nécessaire au niveau concerné, sans droit de purge. Le modèle d’autorisation du coffre détermine s’il faut vérifier Azure RBAC ou une access policy.

Avant l’exécution, confirmez :

  • le coffre, le nom, la fenêtre et la date de purge planifiée ;
  • les consommateurs et leurs versions attendues ;
  • l’absence de rotation ou recréation concurrente ;
  • une exécution relue par une seconde personne ;
  • des critères d’arrêt écrits.

Ne combinez pas récupération, nouvelle valeur, ouverture réseau et redéploiement. Une action, une hypothèse, une validation.

Récupérer sans lire la valeur

bash 03-recover-key-vault-secret.sh
set -euo pipefail

VAULT="kv-platform-prod"
SECRET="payment-api-token"

az keyvault secret recover --vault-name "$VAULT" --name "$SECRET" --output none

for attempt in 1 2 3 4 5 6; do
if az keyvault secret show --vault-name "$VAULT" --name "$SECRET" --query "{id:id,enabled:attributes.enabled,created:attributes.created,updated:attributes.updated}" --output json; then
  exit 0
fi
sleep 5
done

echo "recovery_not_visible_after_bounded_wait" >&2
exit 1

L’attente est bornée. N’enchaînez jamais sur une création automatique : la récupération peut être asynchrone, un droit peut manquer ou le mauvais coffre peut être ciblé.

Valider les consommateurs

Voir le secret actif ne prouve pas que la production est réparée. Testez avec les identités et chemins réels, sans journaliser la valeur.

text key-vault-recovery-validation.txt
Coffre
Objet actif et enabled=true
Versions attendues visibles dans les metadonnees
Aucun nouvel evenement Delete ou Purge

Consommateurs
URI non versionne lisible avec l'identite runtime
Version epinglee toujours presente et accessible
Reference APIM resolue sans changement de policy
SecretNotFound revenu au niveau normal
Aucun nouveau 401, 403 ou retry storm

Arret
Version attendue absente ou desactivee
Identite de suppression encore active
Valeur potentiellement compromise
Effet metier produit avec une credential incertaine

Préférez un endpoint de santé qui confirme l’accès sans révéler le secret. À défaut, le test ne journalise que le statut, la version demandée et un identifiant de corrélation.

Décider maintien, rotation ou rollback

Maintenez la récupération si les références versionnées et non versionnées fonctionnent, que les erreurs disparaissent et que la source de suppression est contenue. Corrigez ensuite l’identité ou l’automatisation fautive.

Lancez une rotation séparée si la valeur a pu être exposée, si son intégrité n’est plus défendable ou si le fournisseur l’a révoquée. Cette rotation exige son propre plan de double valeur, bascule et révocation.

Rollbackez si la mauvaise version devient active ou si un consommateur produit un effet inattendu : isolez d’abord le consommateur et restaurez sa référence précédente. Ne purgez jamais pour rollbacker. Si l’objet doit être retiré, gardez-le dans le cycle soft-delete afin qu’il reste récupérable pendant la rétention.

Conclusion

Un secret supprimé est un incident de cycle de vie, pas une invitation à recréer une valeur au plus vite. Il faut distinguer objet actif, objet soft-deleted, version consommée, identité de suppression et impact réel.

La sortie saine est une décision prouvée : récupérer l’objet existant, valider chaque référence, maintenir la restauration ou lancer une rotation indépendante. La purge reste exclue de l’urgence, et le rollback protège les consommateurs sans effacer la preuve.