Проверка образов контейнеров в рабочих процессах GitHub с помощью нотации и подписывания артефактов

Эта статья является частью серии по обеспечению целостности и подлинности образов контейнеров и других артефактов Open Container Initiative (OCI). Для полного рисунка начните с обзора, в котором объясняется, почему подписывание имеет значение и описывает различные сценарии.

Это руководство можно использовать в двух сценариях:

  • Использование подписанных образов: проверьте контейнерные образы, которые уже подписаны другими командами или организациями, с помощью Notation и подписывания артефактов.
  • Проверка собственных образов. Если вы публикуете образы самостоятельно, сначала подпишите их с помощью рабочего процесса GitHub или интерфейса командной строки Нотации (CLI). Затем следуйте этому руководству, чтобы проверить подписи.

В этой статье вы узнаете, как:

  • Настройте рабочий процесс GitHub.
  • Убедитесь, что образы контейнеров подписаны с помощью подписи артефактов и GitHub Actions для нотации.

Предпосылки

  • Реестр контейнеров, содержащий подписанные образы.
  • Репозиторий GitHub для хранения файла рабочего процесса, политики доверия и хранилища доверия.

Аутентификация в GitHub через Azure

В соответствии с Использованием GitHub Actions для подключения к Azure необходимо сначала авторизоваться в Azure в рабочем процессе, используя действие входа в Azure, перед выполнением команд Azure CLI или Azure PowerShell. Действие входа Azure поддерживает несколько методов проверки подлинности.

В этом руководстве вы войдите в OpenID Connect (OIDC), используйте управляемое удостоверение, назначаемое пользователем, и выполните действия, описанные в разделе "Использование действия входа Azure с OpenID Connect".

  1. Создайте управляемый идентификатор, назначенный пользователем. Пропустите этот шаг, если у вас есть существующее управляемое удостоверение.

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

  1. Получите идентификатор (ID) вашего управляемого удостоверения.

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

  1. Назначение ролей управляемому удостоверению для доступа к реестру контейнеров Azure.

    Для реестров, в которых не включено управление доступом на основе атрибутов (ABAC), назначьте роль AcrPull.

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

    Для реестров с поддержкой ABAC назначьте роль 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. Настройте GitHub, чтобы он доверял вашей учетной записи. Следуйте инструкциям по настройке управляемого удостоверения, назначаемого пользователем, чтобы доверять внешнему поставщику удостоверений.

  2. Создайте секреты GitHub, следуя инструкции по созданию секретов для репозитория.

    Сопоставление значений управляемых идентификаторов с этими секретами:

    Секрет GitHub Значение управляемого удостоверения
    AZURE_CLIENT_ID Идентификатор клиента
    AZURE_SUBSCRIPTION_ID ID подписки
    AZURE_TENANT_ID Идентификатор каталога (арендатора)

Подготовка хранилища доверия и политики доверия

Для проверки требуется хранилище доверия Notary Project и политика доверия, проверенные в вашем репозитории.

Создание хранилища доверия

Хранилище доверия (.github/truststore/) содержит сертификаты удостоверяющего центра (ЦС) и корневые сертификаты центра меток времени (TSA), необходимые для проверки.

Скачайте корневой сертификат подписи артефакта и сохраните его в каталоге ca :

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"

Скачайте корневой сертификат TSA для подписывания артефактов и сохраните его в каталоге 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"

Создание политики доверия

Политика доверия (.github/trustpolicy/trustpolicy.json) определяет, какие идентичности и центры сертификации считаются надежными.

Ниже приведен пример trustpolicy.json. Замените URI репозитория, имена хранилища доверия и профиль сертификата подписывания артефактов вашими значениями.

{
 "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"
         ]
     }
 ]
}

Подтверждение структуры каталогов

Ваш репозиторий должен выглядеть следующим образом:

.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

Создание рабочего процесса GitHub Actions

После готовности к настройке проверки подлинности и доверия создайте рабочий процесс:

  1. .github/workflows Создайте каталог в репозитории, если он не существует.

  2. Создание файла рабочего процесса; например, verify-with-artifact-signing.yml.

  3. Скопируйте следующий шаблон рабочего процесса в файл.

    Разверните, чтобы просмотреть шаблон рабочего процесса проверки.
    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. Обновите переменные среды с помощью собственного реестра, репозитория и тега образа или дайджеста. Сохраните и зафиксируйте файл.

Активация рабочего процесса GitHub Actions

Push-триггер активирует пример рабочего процесса. Чтобы запустить задание, зафиксируйте файл рабочего процесса в репозитории.

Журналы рабочих процессов можно просмотреть, чтобы убедиться, что задание успешно завершено. Например, убедитесь, что политика доверия импортирована, сертификаты из хранилища доверия загружаются, а подпись проверяется.