Automation
Azure Container Registry : migrer Docker Content Trust vers Notation sans ouvrir la chaîne de livraison
Un runbook de production pour inventorier Docker Content Trust, doubler les signatures avec Notation, valider les digests et basculer les gates CI/CD avec un rollback explicite.
Une pipeline peut refuser les images non signées depuis des années et perdre ce contrôle pendant une migration pourtant légitime. Docker Content Trust ne peut plus être activé sur de nouveaux registres Azure Container Registry, ou sur des registres qui ne l’utilisaient pas déjà, depuis le 31 mai 2026. Sa suppression complète est annoncée pour le 31 mars 2028. Remplacer DCT par Notation n’est donc pas une mise à jour de CLI : c’est une modification du contrat entre le build, le registre et le déploiement.
Le cas fil rouge est une plateforme qui publie plusieurs images dans ACR. Les promotions de production vérifient aujourd’hui des tags signés avec DCT. L’équipe veut passer à des signatures Notation attachées aux digests OCI, sans accepter une fenêtre où une image non vérifiée pourrait atteindre AKS ou un autre runtime. Le runbook doit finir par une décision claire : basculer, prolonger la double vérification ou restaurer le dernier gate connu.
Figer le contrat de migration
Suspendez d’abord les changements de politique, pas les builds. Décrivez ce que le contrôle actuel protège réellement : registres, repositories, tags de promotion, identités de signature, consommateurs et comportement en cas d’échec.
migration: dct-to-notation
registry: acrprodweu.azurecr.io
repositories:
- payments/api
- payments/worker
current_gate:
mechanism: docker-content-trust
protected_tags: [release, stable]
failure_mode: block
target_gate:
mechanism: notation
reference: immutable-digest
trust_policy_version: prod-images-v1
failure_mode: block
cutover_requires:
- same_digest_verified_by_both_paths
- approved_publisher_identity
- negative_test_rejected
- rollback_pipeline_available Un inventaire par tags ne suffit pas. Un tag peut bouger entre l’observation DCT et la signature Notation. La clé de rapprochement doit être le digest complet sha256, avec le run de build qui l’a produit et l’environnement qui le consomme.
Inventorier avant de signer
Commencez par le registre et les pipelines, puis descendez vers les images. Identifiez les registres où DCT est actif, les jobs qui utilisent DOCKER_CONTENT_TRUST, les rôles historiques de signature, les tags protégés et les déploiements qui vérifient seulement un tag.
ACR="acrprodweu"
REPO="payments/api"
TAG="release"
az acr config content-trust show --registry "$ACR" --output json
az acr manifest list-metadata --registry "$ACR" --name "$REPO" --orderby time_desc --top 20 --output table
docker trust inspect --pretty "$ACR.azurecr.io/$REPO:$TAG" Conservez une matrice par repository : tag observé, digest résolu, présence DCT, présence Notation, identité attendue, dernière vérification réussie et consumer. Ne considérez pas l’absence de docker trust inspect comme la preuve d’une image non signée tant que l’authentification, le registre et le tag exact ne sont pas confirmés.
Profitez de cette étape pour supprimer une ambiguïté fréquente : ACR stocke l’artefact, mais la politique de confiance est appliquée par les clients, les pipelines ou les contrôles d’admission. Activer une fonction sur le registre n’a jamais prouvé que tous les consommateurs bloquaient les images non approuvées.
Construire la confiance Notation séparément
Ne traduisez pas mécaniquement les anciens rôles DCT. Établissez un trust store, une politique bornée au registre et au repository, puis une identité de publication distincte de l’identité de déploiement. La politique doit nommer les identités autorisées et refuser les scopes hors périmètre.
{
"version": "1.0",
"trustPolicies": [
{
"name": "payments-production",
"registryScopes": [
"acrprodweu.azurecr.io/payments/api",
"acrprodweu.azurecr.io/payments/worker"
],
"signatureVerification": { "level": "strict" },
"trustStores": ["ca:payments-release"],
"trustedIdentities": ["x509.subject:<approved-publisher-subject>"]
}
]
} Importez la politique sur un runner de validation isolé. Versionnez son contenu, son bundle de certificats et les versions de Notation et du plugin. Une politique locale modifiée à la main n’est pas un gate reproductible.
notation policy import trustpolicy.json --force
notation policy show
notation cert ls Doubler les signatures sur le même digest
Choisissez un digest déjà publié, encore déployable et représentatif. Ne reconstruisez pas l’image pour la migration : un nouveau build changerait l’objet et empêcherait de comparer les deux contrôles. Ajoutez la signature Notation au digest existant avec la clé approuvée, puis inventoriez les referrers OCI.
IMAGE="acrprodweu.azurecr.io/payments/api@sha256:<candidate-digest>"
KEY_ID="https://kv-signing-prod.vault.azure.net/keys/container-signing/<version>"
notation sign --signature-format cose --id "$KEY_ID" --plugin azure-kv "$IMAGE"
notation ls "$IMAGE"
notation verify "$IMAGE" L’objectif de la double signature n’est pas de garder deux systèmes indéfiniment. Elle crée une période de comparaison où l’ancien gate reste autoritaire et où Notation produit une décision shadow. Pour chaque promotion, journalisez digest, scope de politique, identité reconnue, résultat DCT, résultat Notation, version des outils et run de pipeline.
Tester les refus avant la bascule
Un test positif prouve seulement que le chemin nominal fonctionne. Construisez au minimum quatre cas : digest correctement signé, digest sans signature Notation, signature valide issue d’une identité non approuvée et référence par tag qui a bougé après validation.
Case 1 - approved digest
DCT: pass
Notation: pass
Expected: candidate remains eligible
Case 2 - unsigned digest
DCT: not sufficient for target state
Notation: fail
Expected: promotion blocked
Case 3 - unapproved publisher
Signature cryptographically valid
Trust policy: fail
Expected: promotion blocked
Case 4 - tag moved after verification
Verified digest differs from deployment digest
Expected: promotion blocked Vérifiez aussi le mode de panne. Si Key Vault, le trust store, ACR ou le plugin est indisponible, le pipeline doit distinguer un artefact rejeté d’un vérificateur indisponible, tout en bloquant la promotion dans les deux cas. Le message opérateur et le chemin d’escalade ne doivent pas suggérer de désactiver le contrôle pour « débloquer » la release.
Basculer par repository
Ne remplacez pas le gate global en une fois. Basculez un repository à faible risque, continuez à signer les releases avec les deux mécanismes, puis rendez Notation autoritaire uniquement pour ce scope. Déployez par digest et comparez le digest vérifié avec l’image réellement observée dans le runtime.
Le gate peut être promu lorsque plusieurs runs représentatifs concordent, que les tests négatifs sont bloqués et qu’aucun consumer officiel ne dépend exclusivement de DCT. L’inventaire doit inclure les jobs de reprise, les déploiements manuels approuvés et les clusters secondaires : la pipeline principale n’est pas toujours le seul chemin vers la production.
N’effacez pas les clés, métadonnées ou étapes DCT au moment de la première bascule. Désactivez leur capacité à autoriser une promotion, mais gardez les éléments nécessaires pour expliquer les anciennes releases pendant la période d’audit définie.
Décider maintien, extension ou rollback
BASCULER VERS NOTATION
Tous les consommateurs déploient par digest.
Le publisher attendu passe la politique bornée.
Les cas non signé, mauvais publisher et tag déplacé sont bloqués.
Le rollback du pipeline a été testé.
PROLONGER LA DOUBLE VERIFICATION
Les décisions concordent mais un consumer DCT reste actif.
Notation reste shadow et aucune exception globale n'est créée.
Un owner et une date de sortie sont assignés au consumer restant.
ROLLBACKER LE GATE
La politique vise le mauvais scope, le trust store n'est pas reproductible
ou le vérificateur produit des décisions incohérentes.
Restaurer la version précédente du pipeline et de la politique.
Garder le digest candidat hors production et corriger hors incident.
ARRETER
Un digest différent de celui vérifié atteint le runtime.
Une image non signée passe une promotion.
L'ancien contrôle a été supprimé avant validation du nouveau. Le rollback porte sur la version du pipeline, la politique de confiance et la décision d’autorité. Il ne consiste pas à réactiver DCT sur un registre qui ne peut plus l’activer, ni à accepter temporairement des images non vérifiées. Tant que le nouveau gate n’est pas fiable, conservez la dernière image déjà vérifiée et déployable par digest.
Conclusion
La migration DCT vers Notation réussit quand elle préserve le contrat de livraison, pas quand une commande de signature retourne zéro. Inventoriez les consommateurs, rapprochez les contrôles sur un digest immuable, testez les refus, puis basculez repository par repository.
La décision finale doit rester exploitable : adopter Notation après preuves positives et négatives, maintenir une double vérification bornée pour un consumer identifié, ou restaurer le dernier gate connu sans ouvrir une exception de production.