Verificar imagens de contêiner em fluxos de trabalho do GitHub usando Notação e Assinatura de Artefato

Este artigo faz parte de uma série sobre como garantir a integridade e a autenticidade de imagens de contêiner e outros artefatos da OCI (Open Container Initiative). Para a imagem completa, comece com a visão geral, que explica por que a assinatura importa e descreve os vários cenários.

Você pode usar este guia em dois cenários:

  • Consumir imagens assinadas: verifique as imagens de contêiner que outras equipes ou organizações já assinaram usando Notação e Assinatura de Artefato.
  • Verificando suas próprias imagens: se você publicar imagens você mesmo, primeiro assine-as usando um fluxo de trabalho do GitHub ou a interface de linha de comando (CLI) Notation. Em seguida, siga este guia para verificar as assinaturas.

Neste artigo, você aprenderá a:

  • Configure um fluxo de trabalho do GitHub.
  • Verifique se as imagens de contêiner foram assinadas usando a Assinatura de Artefato e o GitHub Actions para Notação.

Pré-requisitos

  • Um registro de contêiner que contém imagens assinadas.
  • Um repositório GitHub para armazenar o arquivo de fluxo de trabalho, a política de confiança e o repositório de confiança.

Autenticar do Azure para o GitHub

De acordo com o Uso do GitHub Actions para se conectar ao Azure, primeiro você deve se autenticar com o Azure em seu fluxo de trabalho usando a ação de Logon do Azure antes de executar comandos da CLI do Azure ou do Azure PowerShell. A ação de Logon do Azure dá suporte a vários métodos de autenticação.

Neste guia, você entra com o OpenID Connect (OIDC), usa uma identidade gerenciada atribuída pelo usuário e segue as etapas em Usar a ação de Logon do Azure com o OpenID Connect.

  1. Criar uma identidade gerenciada atribuída pelo usuário. Ignore esta etapa se você tiver uma identidade gerenciada existente.

    az login
    az identity create -g <identity-resource-group> -n <identity-name>
    

  1. Obtenha a ID de cliente da sua identidade gerenciada.

    CLIENT_ID=$(az identity show -g <identity-resource-group> -n <identity-name> --query clientId -o tsv)
    

  1. Atribua funções à identidade gerenciada para acessar o Registro de Contêiner do Azure.

    Para registros que não estão habilitados com o ABAC (controle de acesso baseado em atributo), atribua a AcrPull função:

    ACR_SCOPE=/subscriptions/<subscription-id>/resourceGroups/<acr-resource-group>
    az role assignment create --assignee $CLIENT_ID --scope $ACR_SCOPE --role "acrpull"
    

    Para registros com ABAC habilitado, atribuir a função Container Registry Repository Reader:

    ACR_SCOPE=/subscriptions/<subscription-id>/resourceGroups/<acr-resource-group>
    az role assignment create --assignee $CLIENT_ID --scope $ACR_SCOPE --role "Container Registry Repository Reader"
    

  1. Configure o GitHub para confiar em sua identidade. Siga as instruções de Configuração de uma identidade gerenciada atribuída pelo usuário para confiar em um provedor de identidade externo.

  2. Crie segredos do GitHub seguindo as instruções para criar segredos para um repositório.

    Mapeie os valores de identidade gerenciada para esses segredos:

    Segredo do GitHub Valor da identidade gerenciada
    AZURE_CLIENT_ID ID do cliente
    AZURE_SUBSCRIPTION_ID ID da assinatura
    AZURE_TENANT_ID ID do diretório (locatário)

Preparar o depósito de confiança e a política de confiança

A verificação requer um armazenamento confiável do Projeto Notary e uma política de confiança verificados em seu repositório.

Criar o repositório de confiança

O repositório confiável (.github/truststore/) contém os certificados de autoridade de certificação (CA) e os certificados raiz da autoridade de carimbo de data/hora (TSA) necessários para verificação.

Baixe o certificado raiz de Assinatura de Artefato e armazene-o no ca diretório:

curl -o .github/truststore/x509/ca/mycerts/msft-identity-verification-root-cert-2020.crt \
    "https://www.microsoft.com/pkiops/certs/Microsoft%20Enterprise%20Identity%20Verification%20Root%20Certificate%20Authority%202020.crt"

Baixe o Certificado raiz TSA de Assinatura de Artefato e armazene-o no diretório tsa:

curl -o .github/truststore/x509/tsa/mytsacerts/msft-identity-verification-tsa-root-cert-2020.crt \
  "http://www.microsoft.com/pkiops/certs/microsoft%20identity%20verification%20root%20certificate%20authority%202020.crt"

Criar a política de confiança

A política de confiança (.github/trustpolicy/trustpolicy.json) define quais identidades e CAs são confiáveis.

Aqui está um exemplo de trustpolicy.json. Substitua URIs de repositórios, nomes de lojas confiáveis e assuntos de perfis de certificados de Assinatura de Artefato pelos seus valores.

{
 "version": "1.0",
 "trustPolicies": [
    {
         "name": "mypolicy",
         "registryScopes": [ "myregistry.azurecr.io/myrepo1","myregistry.azurecr.io/myrepo2" ],
         "signatureVerification": {
             "level" : "strict"
         },
         "trustStores": [ "ca:mycerts", "tsa:mytsacerts" ],
         "trustedIdentities": [
           "x509.subject: C=US, ST=WA, L=Seattle, O=MyCompany.io, OU=Tools"
         ]
     }
 ]
}

Confirmar a estrutura do diretório

Seu repositório deve ser semelhante a este exemplo:

.github/
├── trustpolicy/
│   └── trustpolicy.json
└── truststore/
    └── x509/
        ├── ca/
        │   └── mycerts/
        │       └── msft-identity-verification-root-cert-2020.crt
        └── tsa/
            └── mytsacerts/
                └── msft-identity-verification-tsa-root-cert-2020.crt

Criar o fluxo de trabalho do GitHub Actions

Quando a autenticação e a configuração de confiança estiverem prontas, crie o fluxo de trabalho:

  1. Crie um .github/workflows diretório em seu repositório se ele não existir.

  2. Criar um novo arquivo de fluxo de trabalho; por exemplo, verify-with-artifact-signing.yml.

  3. Copie o modelo de fluxo de trabalho a seguir em seu arquivo.

    Expanda para exibir o modelo de fluxo de trabalho de verificação.
    name: notation-verify-with-artifact-signing
    
    on:
      push:
    
    env:
      ACR_LOGIN_SERVER: <registry-name>.azurecr.io                      # example: myRegistry.azurecr.io
      ACR_REPO_NAME: <repository-name>                                  # example: myRepo
      IMAGE_TAG: <image-tag>                                            # example: v1
      #IMAGE_DIGEST: <image-digest>                                     # example: sha256:xxx
    jobs:
      notation-verify:
        runs-on: ubuntu-latest
        permissions:
          id-token: write
          contents: read
        steps:
          - name: Checkout
            uses: actions/checkout@v3
          # Log in to Azure with your service principal secret
          # - name: Azure login
          #  uses: Azure/login@v1
          #  with:
          #    creds: ${{ secrets.AZURE_CREDENTIALS }}
          # If you're using OIDC and federated credentials, make sure to replace the preceding step with the following:
          - name: Azure login
            uses: Azure/login@v2
            with:
              client-id: ${{ secrets.AZURE_CLIENT_ID }}
              tenant-id: ${{ secrets.AZURE_TENANT_ID }}
              subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
    
          # Log in to your container registry
          - name: ACR login
            run: |
                az acr login --name ${{ env.ACR_LOGIN_SERVER }}
    
          # Set up the Notation CLI
          - name: setup notation
            uses: notaryproject/notation-action/setup@v1.2.2
    
          # Verify the OCI artifact, such as container images
          - name: verify OCI artifact
            uses: notaryproject/notation-action/verify@v1
            with:
              target_artifact_reference: ${{ env.ACR_LOGIN_SERVER }}/${{ env.ACR_REPO_NAME }}:${{ env.IMAGE_TAG }}
              # Alternatively, use the image digest
              # target_artifact_reference: ${{ env.ACR_LOGIN_SERVER }}/${{ env.ACR_REPO_NAME }}@${{ env.IMAGE_DIGEST }}
              trust_policy: .github/trustpolicy/trustpolicy.json
              trust_store: .github/truststore
    
  4. Atualize as variáveis de ambiente com seu próprio registro, repositório e marca/resumo de imagem. Salve e confirme o arquivo.

Acionar o fluxo de trabalho do GitHub Actions

Uma transmissão aciona o fluxo de trabalho de exemplo. Para iniciar o trabalho, confirme o arquivo de fluxo de trabalho em seu repositório.

Você pode exibir os logs de fluxo de trabalho para confirmar se o trabalho foi concluído com êxito. Por exemplo, verifique se a política de confiança é importada, os certificados do repositório de confiança são carregados e a assinatura é verificada.