Signer des images conteneur avec Notation et Azure Key Vault à l'aide d'un certificat auto-signé

La signature d'images conteneur est un processus qui garantit leur authenticité et leur intégrité. Pour ce faire, ajoutez une signature numérique à l'image conteneur, qui peut être validée pendant le déploiement. La signature permet de vérifier que l'image provient d'un éditeur approuvé et qu'elle n'a pas été modifiée. Notation est un outil de sécurité de la chaîne logistique open source, développé par la communauté Notary Project et soutenu par Microsoft, qui prend en charge la signature et la vérification d’images conteneur et d’autres artefacts. Azure Key Vault (AKV) est utilisé pour stocker des certificats avec des clés de signature qui peuvent être utilisées par Notation avec le plug-in AKV de Notation (azure-kv) pour signer et vérifier les images conteneur et d'autres artefacts. L'Azure Container Registry (ACR) vous permet d'attacher des signatures à des images conteneur et à d'autres artefacts, ainsi que d'afficher ces signatures.

Dans ce tutoriel :

  • Installer l'interface CLI de Notation et le plug-in AKV
  • Créer un certificat auto-signé dans AKV
  • Générez et envoyez (push) une image conteneur avec ACR Tasks.
  • Signer une image conteneur avec l'interface CLI de Notation et le plug-in AKV
  • Valider une image conteneur par rapport à la signature avec l'interface CLI de Notation
  • Horodatage

Prérequis

Installer l'interface CLI de Notation et le plug-in AKV

  1. Installez Notation v1.2.0 sur un environnement Linux amd64. Suivez le Guide d’installation de Notation pour télécharger le package pour d’autres environnements.

    # Download, extract and install
    curl -Lo notation.tar.gz https://github.com/notaryproject/notation/releases/download/v1.2.0/notation_1.2.0_linux_amd64.tar.gz
    tar xvzf notation.tar.gz
    
    # Copy the Notation binary to the desired bin directory in your $PATH, for example
    cp ./notation /usr/local/bin
    
  2. Installez le plug-in de notation Azure Key Vault azure-kv v1.2.0 sur un environnement Linux amd64.

    Remarque

    L’URL et la somme de contrôle SHA256 du plug-in Notation Azure Key Vault se trouvent dans la page de version du plug-in.

    notation plugin install --url https://github.com/Azure/notation-azure-kv/releases/download/v1.2.0/notation-azure-kv_1.2.0_linux_amd64.tar.gz --sha256sum 06bb5198af31ce11b08c4557ae4c2cbfb09878dfa6b637b7407ebc2d57b87b34
    
  3. Listez les plug-ins disponibles et vérifiez que le plug-in azure-kv avec la version 1.2.0 est inclus dans la liste.

    notation plugin ls
    

Configuration des variables d’environnement

Notes

Pour faciliter l’exécution des commandes dans le tutoriel, fournissez des valeurs pour les ressources Azure afin de faire correspondre les ressources ACR et AKV existantes.

  1. Configurez les noms de ressources AKV.

    AKV_SUB_ID=myAkvSubscriptionId
    AKV_RG=myAkvResourceGroup
    # Name of the existing AKV used to store the signing keys
    AKV_NAME=myakv
    # Name of the certificate created in AKV
    CERT_NAME=wabbit-networks-io
    CERT_SUBJECT="CN=wabbit-networks.io,O=Notation,L=Seattle,ST=WA,C=US"
    CERT_PATH=./${CERT_NAME}.pem
    
  2. Configurez les noms de ressources ACR et d’image.

    ACR_SUB_ID=myAcrSubscriptionId
    ACR_RG=myAcrResourceGroup
    # Name of the existing registry example: myregistry.azurecr.io
    ACR_NAME=myregistry
    # Existing full domain of the ACR
    REGISTRY=$ACR_NAME.azurecr.io
    # Container name inside ACR where image will be stored
    REPO=net-monitor
    TAG=v1
    IMAGE=$REGISTRY/${REPO}:$TAG
    # Source code directory containing Dockerfile to build
    IMAGE_SOURCE=https://github.com/wabbit-networks/net-monitor.git#main
    

Se connecter avec Azure CLI

az login

Pour en savoir plus sur Azure CLI et sur la façon de se connecter avec elle, reportez-vous à Se connecter avec Azure CLI.

Autorisations d’accès sécurisées à ACR et AKV

Lorsque vous utilisez ACR et AKV, il est indispensable d’octroyer les autorisations appropriées pour veiller à un accès contrôlé et sécurisé. Vous pouvez autoriser l’accès pour diverses entités, telles que les principaux d’utilisateur, les principaux de service ou les identités managées, en fonction de vos scénarios spécifiques. Dans ce tutoriel, l’accès est autorisé pour un utilisateur Azure connecté.

Autoriser l’accès à ACR

Les rôles AcrPull et AcrPush sont requis pour signer des images conteneur dans ACR.

  1. Définir l’abonnement qui contient la ressource ACR

    az account set --subscription $ACR_SUB_ID
    
  2. Attribuer les rôles

    USER_ID=$(az ad signed-in-user show --query id -o tsv)
    az role assignment create --role "AcrPull" --role "AcrPush" --assignee $USER_ID --scope "/subscriptions/$ACR_SUB_ID/resourceGroups/$ACR_RG/providers/Microsoft.ContainerRegistry/registries/$ACR_NAME"
    

Autoriser l’accès à AKV

Dans cette section, nous allons explorer deux options pour autoriser l’accès à AKV.

Les rôles suivants sont requis pour signer en utilisant des certificats auto-signés :

  • Key Vault Certificates Officer pour la création et la lecture de certificats
  • Key Vault Certificates User pour la lecture de certificats existants
  • Key Vault Crypto User pour la signature d’opérations

Pour découvrir plus d’informations sur l’accès à Key Vault avec RBAC Azure, consultez Utiliser un contrôle d’accès en fonction du rôle (RBAC) Azure pour gérer l’accès.

  1. Définir l'abonnement qui contient la ressource AKV

    az account set --subscription $AKV_SUB_ID
    
  2. Attribuer les rôles

    USER_ID=$(az ad signed-in-user show --query id -o tsv)
    az role assignment create --role "Key Vault Certificates Officer" --role "Key Vault Crypto User" --assignee $USER_ID --scope "/subscriptions/$AKV_SUB_ID/resourceGroups/$AKV_RG/providers/Microsoft.KeyVault/vaults/$AKV_NAME"
    

Attribuer une stratégie d’accès dans AKV (hérité)

Les autorisations suivantes sont requises pour une identité :

  • Autorisations Create pour la création d’un certificat
  • Autorisations Get pour la lecture de certificats existants
  • Autorisations Sign pour la signature d’opérations

Pour en savoir plus sur l'attribution d'une stratégie à un principal, reportez-vous à Attribuer une stratégie d'accès.

  1. Définissez l’abonnement qui contient la ressource AKV :

    az account set --subscription $AKV_SUB_ID
    
  2. Définissez la stratégie d’accès dans AKV :

    USER_ID=$(az ad signed-in-user show --query id -o tsv)
    az keyvault set-policy -n $AKV_NAME --certificate-permissions create get --key-permissions sign --object-id $USER_ID
    

Important

Cet exemple montre les autorisations minimales nécessaires pour créer un certificat et signer une image conteneur. Selon vos besoins, vous devrez peut-être accorder des autorisations supplémentaires.

Créer un certificat auto-signé dans AKV (Azure CLI)

Les étapes suivantes montrent comment créer un certificat auto-signé à des fins de test.

  1. Créez un fichier de stratégie de certificat

    Une fois le fichier de stratégie de certificat exécuté comme ci-dessous, il crée un certificat de signature valide compatible avec les exigences du certificat de Projet Notary dans AKV. La valeur pour ekus est destinée à la signature de code, mais n'est pas requise pour signer des artefacts avec Notation. L’objet est utilisé ultérieurement comme identité de confiance que l’utilisateur approuve lors de la vérification.

    cat <<EOF > ./my_policy.json
    {
        "issuerParameters": {
        "certificateTransparency": null,
        "name": "Self"
        },
        "keyProperties": {
          "exportable": false,
          "keySize": 2048,
          "keyType": "RSA",
          "reuseKey": true
        },
        "secretProperties": {
          "contentType": "application/x-pem-file"
        },
        "x509CertificateProperties": {
        "ekus": [
            "1.3.6.1.5.5.7.3.3"
        ],
        "keyUsage": [
            "digitalSignature"
        ],
        "subject": "$CERT_SUBJECT",
        "validityInMonths": 12
        }
    }
    EOF
    
  2. Créez le certificat

    az keyvault certificate create -n $CERT_NAME --vault-name $AKV_NAME -p @my_policy.json
    

Signer une image conteneur avec l'interface CLI de Notation et le plug-in AKV

  1. Authentifiez-vous auprès de votre ACR à l'aide de votre identité Azure individuelle.

    az acr login --name $ACR_NAME
    

Important

Si vous avez installé Docker sur votre système et utilisé az acr login ou docker login pour vous authentifier auprès de votre ACR, c'est que vos informations d'identification sont déjà stockées et disponibles dans Notation. Dans ce cas, vous n'avez pas besoin de réexécuter notation login pour vous authentifier auprès de votre ACR. Pour en savoir plus sur les options d'authentification pour Notation, reportez-vous à Authentifier avec des registres conformes à OCI.

  1. Générez et envoyez (push) une nouvelle image avec ACR Tasks. Utilisez toujours la valeur de synthèse pour identifier l'image à signer, car les étiquettes sont mutables et peuvent être remplacées.

    DIGEST=$(az acr build -r $ACR_NAME -t $REGISTRY/${REPO}:$TAG $IMAGE_SOURCE --no-logs --query "outputImages[0].digest" -o tsv)
    IMAGE=$REGISTRY/${REPO}@$DIGEST
    

    Dans ce tutoriel, si l'image a déjà été créée et est stockée dans le registre, l'étiquette sert d'identificateur pour cette image pour plus de commodité.

    IMAGE=$REGISTRY/${REPO}:$TAG
    
  2. Obtenez l'ID de clé de la clé de signature. Un certificat dans AKV peut avoir plusieurs versions. La commande suivante obtient l'ID de clé de la dernière version.

    KEY_ID=$(az keyvault certificate show -n $CERT_NAME --vault-name $AKV_NAME --query 'kid' -o tsv)
    
  3. Signez l'image conteneur avec le format de signature COSE à l'aide de la clé de signature. Pour signer avec un certificat auto-signé, vous devez définir la valeur self_signed=true de configuration du plug-in.

    notation sign --signature-format cose --id $KEY_ID --plugin azure-kv --plugin-config self_signed=true $IMAGE
    

    Pour s'authentifier avec AKV, par défaut, les types d'informations d'identification suivants, s'ils sont activés, seront essayés dans l'ordre :

    Si vous souhaitez spécifier un type d’informations d’identification, utilisez une configuration de plug-in supplémentaire appelée credential_type. Par exemple, vous pouvez définir explicitement credential_type sur azurecli pour utiliser les informations d’identification Azure CLI, comme illustré ci-dessous :

    notation sign --signature-format cose --id $KEY_ID --plugin azure-kv --plugin-config self_signed=true --plugin-config credential_type=azurecli $IMAGE
    

    Consultez le tableau ci-dessous pour connaître les valeurs de credential_type pour différents types d’informations d’identification.

    Type d'informations d'identification Valeur de credential_type
    Informations d’identification de l’environnement environment
    Informations d’identification de l’identité de la charge workloadid
    Informations d’identification d’identité managée managedid
    Informations d’identification d’Azure CLI azurecli
  4. Affichez le graphique des images signées et des signatures associées.

    notation ls $IMAGE
    

Vérifier une image conteneur avec l'interface CLI de Notation

Pour vérifier l'image conteneur, ajoutez le certificat racine qui signe le certificat nœud terminal au magasin de confiance et créez des stratégies de confiance pour vérification. Pour le certificat auto-signé utilisé dans ce tutoriel, le certificat racine est le certificat auto-signé lui-même.

  1. Téléchargez le certificat public.

    az keyvault certificate download --name $CERT_NAME --vault-name $AKV_NAME --file $CERT_PATH
    
  2. Ajoutez le certificat public téléchargé au magasin de confiance nommé pour la vérification de la signature.

    STORE_TYPE="ca"
    STORE_NAME="wabbit-networks.io"
    notation cert add --type $STORE_TYPE --store $STORE_NAME $CERT_PATH
    
  3. Répertoriez le certificat à confirmer.

    notation cert ls
    
  4. Configurez la stratégie de confiance avant la vérification.

    Les stratégies d'approbation permettent aux utilisateurs de spécifier des stratégies de vérification affinées. L'exemple suivant configure une stratégie de confiance nommée wabbit-networks-images, qui s'applique à tous les artefacts dans $REGISTRY/$REPO et utilise le magasin de confiance $STORE_NAME nommé de type $STORE_TYPE. Il suppose également que l'utilisateur approuve une identité spécifique avec l'objet X.509 $CERT_SUBJECT. Pour plus d'informations, reportez-vous à Magasin de confiance et spécification de stratégie de confiance.

    cat <<EOF > ./trustpolicy.json
    {
        "version": "1.0",
        "trustPolicies": [
            {
                "name": "wabbit-networks-images",
                "registryScopes": [ "$REGISTRY/$REPO" ],
                "signatureVerification": {
                    "level" : "strict" 
                },
                "trustStores": [ "$STORE_TYPE:$STORE_NAME" ],
                "trustedIdentities": [
                    "x509.subject: $CERT_SUBJECT"
                ]
            }
        ]
    }
    EOF
    
  5. Utilisez notation policy pour importer la configuration de la stratégie de confiance à partir d’un fichier JSON que nous avons créé précédemment.

    notation policy import ./trustpolicy.json
    notation policy show
    
  6. Utilisez notation verify pour vérifier que l'image conteneur n'a pas été modifiée depuis sa création.

    notation verify $IMAGE
    

    En cas de vérification réussie de l’image à l’aide de la stratégie de confiance, la synthèse sha256 de l’image vérifiée est retournée dans un message de sortie réussi.

Horodatage

Depuis la version v1.2.0, Notation prend en charge l’horodatage conforme RFC 3161. Cette amélioration étend la confiance des signatures créées au cours de la période de validité du certificat en faisant confiance à une autorité d’horodatage (TSA, Timestamping Authority), ce qui permet à la vérification de la signature de réussir même après l’expiration des certificats. En tant que signataire d’image, vous devez veiller à signer les images conteneur avec des horodateurs générés par une TSA de confiance. En tant que vérificateur d’image, pour vérifier les horodateurs, vous devez veiller à faire confiance à la fois au signataire de l’image et à la TSA associée, et à établir la confiance par le biais de magasins de confiance et de stratégies d’approbation. L’horodatage réduit les coûts en éliminant la nécessité de réinscrire régulièrement des images en raison de l’expiration du certificat, ce qui est particulièrement critique lors de l’utilisation de certificats de courte durée. Pour obtenir des instructions détaillées sur la façon de signer et de vérifier à l’aide de l’horodatage, reportez-vous au guide sur l’horodatage du projet notarié.

Étapes suivantes

La notation fournit également des solutions CI/CD sur Azure Pipeline et le workflow GitHub Actions :

Pour valider le déploiement d’images signées dans AKS ou Kubernetes :