Assinar imagens de contêiner com Notação e Cofre de Chaves do Azure usando um certificado autoassinado

A assinatura de imagens de contêiner é um processo que garante sua autenticidade e integridade. Isso é conseguido adicionando uma assinatura digital à imagem do contêiner, que pode ser validada durante a implantação. A assinatura ajuda a verificar se a imagem é de um editor confiável e não foi modificada. Notation é uma ferramenta de segurança da cadeia de suprimentos de código aberto desenvolvida pela comunidade Notary Project e apoiada pela Microsoft, que suporta a assinatura e verificação de imagens de contêiner e outros artefatos. O Azure Key Vault (AKV) é usado para armazenar certificados com chaves de assinatura que podem ser usados pelo Notation com o plug-in Notation AKV (azure-kv) para assinar e verificar imagens de contêiner e outros artefatos. O Azure Container Registry (ACR) permite anexar assinaturas a imagens de contêiner e outros artefatos, bem como exibir essas assinaturas.

Neste tutorial:

  • Instale o plugin Notation CLI e AKV
  • Criar um certificado auto-assinado no AKV
  • Criar e enviar por push uma imagem de contêiner com tarefas ACR
  • Assinar uma imagem de contentor com a CLI de Notação e o plug-in do AKV
  • Validar uma imagem de contêiner em relação à assinatura com a CLI de notação
  • Carimbo de data/hora

Pré-requisitos

Instale o plugin Notation CLI e AKV

  1. Instale o Notation v1.2.0 em um ambiente Linux amd64. Siga o guia de instalação do Notation para baixar o pacote para outros ambientes.

    # 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. Instale o plug-in azure-kv Notation Azure Key Vault v1.2.0 em um ambiente Linux amd64.

    Nota

    A URL e a soma de verificação SHA256 para o plug-in Notation Azure Key Vault podem ser encontradas na página de lançamento do 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. Liste os plugins disponíveis e confirme se o plugin com versão azure-kv 1.2.0 está incluído na lista.

    notation plugin ls
    

Configurar variáveis de ambiente

Nota

Para facilitar a execução de comandos no tutorial, forneça valores para que os recursos do Azure correspondam aos recursos ACR e AKV existentes.

  1. Configure nomes de recursos 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. Configure nomes de recursos ACR e de imagem.

    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
    

Iniciar sessão com a CLI do Azure

az login

Para saber mais sobre a CLI do Azure e como entrar com ela, consulte Entrar com a CLI do Azure.

Permissões de acesso seguro para ACR e AKV

Ao trabalhar com ACR e AKV, é essencial conceder as permissões apropriadas para garantir acesso seguro e controlado. Você pode autorizar o acesso para diferentes entidades, como entidades de usuário, entidades de serviço ou identidades gerenciadas, dependendo de seus cenários específicos. Neste tutorial, o acesso é autorizado a um usuário do Azure conectado.

Autorizar o acesso ao ACR

As AcrPull funções e AcrPush são necessárias para assinar imagens de contêiner no ACR.

  1. Definir a assinatura que contém o recurso ACR

    az account set --subscription $ACR_SUB_ID
    
  2. Atribuir as funções

    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"
    

Autorizar o acesso ao AKV

Nesta seção, exploraremos duas opções para autorizar o acesso ao AKV.

As seguintes funções são necessárias para assinar usando certificados autoassinados:

  • Key Vault Certificates Officer para criar e ler certificados
  • Key Vault Certificates Userpara leitura de certificados existentes
  • Key Vault Crypto User para operações de assinatura

Para saber mais sobre o acesso ao Cofre da Chave com o RBAC do Azure, consulte Usar um RBAC do Azure para gerenciar o acesso.

  1. Definir a subscrição que contém o recurso AKV

    az account set --subscription $AKV_SUB_ID
    
  2. Atribuir as funções

    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"
    

Atribuir política de acesso em AKV (legado)

As seguintes permissões são necessárias para uma identidade:

  • Create Permissões para criar um certificado
  • Get Permissões para ler certificados existentes
  • Sign Permissões para operações de assinatura

Para saber mais sobre como atribuir política a uma entidade de segurança, consulte Atribuir política de acesso.

  1. Defina a assinatura que contém o recurso AKV:

    az account set --subscription $AKV_SUB_ID
    
  2. Defina a política de acesso em 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
    

Importante

Este exemplo mostra as permissões mínimas necessárias para criar um certificado e assinar uma imagem de contêiner. Dependendo dos seus requisitos, poderá ter de conceder permissões adicionais.

Criar um certificado autoassinado em AKV (CLI do Azure)

As etapas a seguir mostram como criar um certificado autoassinado para fins de teste.

  1. Crie um arquivo de política de certificado.

    Uma vez que o arquivo de política de certificado é executado como abaixo, ele cria um certificado válido compatível com o requisito de certificado do Projeto Notarial no AKV. O valor for ekus é para assinatura de código, mas não é necessário para notação para assinar artefatos. O assunto é usado posteriormente como identidade de confiança na qual o usuário confia durante a verificação.

    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. Crie o certificado.

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

Assinar uma imagem de contentor com a CLI de Notação e o plug-in do AKV

  1. Autentique-se em seu ACR usando sua identidade individual do Azure.

    az acr login --name $ACR_NAME
    

Importante

Se você tiver o Docker instalado em seu sistema e usado az acr login ou docker login para autenticar em seu ACR, suas credenciais já estão armazenadas e disponíveis para notação. Nesse caso, você não precisa executar notation login novamente para autenticar no seu ACR. Para saber mais sobre as opções de autenticação para notação, consulte Autenticar com registros compatíveis com OCI.

  1. Crie e envie uma nova imagem com as Tarefas ACR. Use sempre o valor digest para identificar a imagem para assinatura, pois as tags são mutáveis e podem ser substituídas.

    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
    

    Neste tutorial, se a imagem já tiver sido criada e estiver armazenada no Registro, a tag servirá como um identificador para essa imagem por conveniência.

    IMAGE=$REGISTRY/${REPO}:$TAG
    
  2. Obtenha o ID da chave de assinatura. Um certificado no AKV pode ter várias versões, o comando a seguir obtém o ID da chave da versão mais recente.

    KEY_ID=$(az keyvault certificate show -n $CERT_NAME --vault-name $AKV_NAME --query 'kid' -o tsv)
    
  3. Assine a imagem do contêiner com o formato de assinatura COSE usando o ID da chave de assinatura. Para assinar com um certificado autoassinado, você precisa definir o valor self_signed=truede configuração do plug-in.

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

    Para autenticar com AKV, por padrão, os seguintes tipos de credenciais, se ativados, serão testados na ordem:

    Se você quiser especificar um tipo de credencial, use uma configuração de plug-in adicional chamada credential_type. Por exemplo, você pode definir credential_type explicitamente para azurecli usar a credencial da CLI do Azure, conforme demonstrado abaixo:

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

    Consulte a tabela abaixo para obter os valores de para vários tipos de credential_type credenciais.

    Tipo de credencial Valor para credential_type
    Credencial de ambiente environment
    Credencial de identidade da carga de trabalho workloadid
    Credencial de identidade gerenciada managedid
    Credencial da CLI do Azure azurecli
  4. Veja o gráfico de imagens assinadas e assinaturas associadas.

    notation ls $IMAGE
    

Verificar uma imagem de contentor com a CLI de Notação

Para verificar a imagem do contêiner, adicione o certificado raiz que assina o certificado folha ao armazenamento confiável e crie políticas de confiança para verificação. Para o certificado autoassinado usado neste tutorial, o certificado raiz é o próprio certificado autoassinado.

  1. Faça o download do certificado público.

    az keyvault certificate download --name $CERT_NAME --vault-name $AKV_NAME --file $CERT_PATH
    
  2. Adicione o certificado público baixado ao armazenamento confiável nomeado para verificação de assinatura.

    STORE_TYPE="ca"
    STORE_NAME="wabbit-networks.io"
    notation cert add --type $STORE_TYPE --store $STORE_NAME $CERT_PATH
    
  3. Liste o certificado a confirmar.

    notation cert ls
    
  4. Configure a política de confiança antes da verificação.

    As políticas de confiança permitem que os usuários especifiquem políticas de verificação ajustadas. O exemplo a seguir configura uma política de confiança chamada wabbit-networks-images, que se aplica a todos os artefatos e $REGISTRY/$REPO usa o armazenamento $STORE_NAME de confiança nomeado do tipo $STORE_TYPE. Ele também assume que o usuário confia em uma identidade específica com o assunto $CERT_SUBJECTX.509. Para obter mais detalhes, consulte Armazenamento confiável e especificação de política de confiança.

    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. Use notation policy para importar a configuração da política de confiança de um arquivo JSON que criamos anteriormente.

    notation policy import ./trustpolicy.json
    notation policy show
    
  6. Use notation verify para verificar se a imagem do contêiner não foi alterada desde o tempo de compilação.

    notation verify $IMAGE
    

    Após a verificação bem-sucedida da imagem usando a política de confiança, o resumo sha256 da imagem verificada é retornado em uma mensagem de saída bem-sucedida.

Carimbo de data/hora

Desde o lançamento do Notation v1.2.0, o Notation suporta carimbo de data/hora compatível com RFC 3161 . Esse aprimoramento amplia a confiança das assinaturas criadas dentro do período de validade do certificado confiando em uma Autoridade de Carimbo de Data/Hora (TSA), permitindo a verificação bem-sucedida da assinatura mesmo depois que os certificados expirarem. Como signatário de imagem, você deve garantir que assina imagens de contêiner com carimbos de data/hora gerados por um TSA confiável. Como verificador de imagem, para verificar carimbos de data/hora, você deve garantir que confia no signatário da imagem e no TSA associado e estabelecer confiança por meio de armazenamentos de confiança e políticas de confiança. O carimbo de data/hora reduz os custos, eliminando a necessidade de assinar imagens novamente periodicamente devido à expiração do certificado, o que é especialmente crítico ao usar certificados de curta duração. Para obter instruções detalhadas sobre como assinar e verificar usando o carimbo de data/hora, consulte o guia de carimbo de data/hora do Projeto Notarial.

Próximos passos

A Notation também fornece soluções de CI/CD no Pipeline do Azure e no Fluxo de Trabalho de Ações do GitHub:

Para validar a implantação de imagem assinada no AKS ou Kubernetes: