Udostępnij przez


Podpisywanie obrazów kontenerów w przepływach pracy usługi GitHub przy użyciu notacji i zaufanego podpisywania

Ten artykuł jest częścią serii dotyczącej zapewniania integralności i autentyczności obrazów kontenerów oraz innych artefaktów Open Container Initiative (OCI). Aby uzyskać pełny obraz, zacznij od omówienia, co wyjaśnia, dlaczego podpisywanie ma znaczenie i przedstawia różne scenariusze.

Z tego artykułu dowiesz się, jak utworzyć przepływ pracy funkcji GitHub Actions w celu:

  • Skompiluj obraz i wypchnij go do usługi Azure Container Registry.
  • Podpisz obraz przy użyciu akcji GitHub Notation i zaufanego podpisywania.
  • Automatycznie przechowuj wygenerowany podpis w usłudze Container Registry.

Wymagania wstępne

Uwaga / Notatka

Obecnie zaufane podpisywanie jest dostępne tylko dla organizacji z siedzibą w Stanach Zjednoczonych i Kanadzie, które mają weryfikowalną historię trzech lat lub więcej.

Uwierzytelnij się na platformie Azure do usługi GitHub

Zgodnie z Use GitHub Actions to connect to Azure, przed uruchomieniem poleceń Azure CLI lub Azure PowerShell należy uwierzytelnić się na platformie Azure w przepływie pracy przy użyciu akcji Azure Login. Akcja logowania platformy Azure obsługuje wiele metod uwierzytelniania.

W tym przewodniku zalogujesz się przy użyciu protokołu OpenID Connect (OIDC), użyjesz tożsamości zarządzanej przypisanej przez użytkownika, a następnie wykonaj kroki opisane w temacie Korzystanie z akcji Logowanie do platformy Azure w programie OpenID Connect.

  1. Utwórz tożsamość zarządzaną przypisaną przez użytkownika. Pomiń ten krok, jeśli masz istniejącą tożsamość zarządzaną.

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

  1. Pobierz identyfikator klienta tożsamości zarządzanej:

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

  1. Przypisz role do tożsamości zarządzanej na potrzeby uzyskiwania dostępu do usługi Azure Container Registry.

    W przypadku rejestrów, które nie mają włączonej kontroli dostępu opartej na atrybutach (ABAC), przypisz role AcrPush i AcrPull:

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

    W przypadku rejestrów z włączoną obsługą ABAC przypisz role Container Registry Repository Reader i Container Registry Repository Writer.

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

  1. Trusted Signing Certificate Profile Signer Przypisz rolę do tożsamości zarządzanej w celu uzyskania dostępu do zaufanego podpisywania:

    TS_SCOPE=/subscriptions/<subscription-id>/resourceGroups/<ts-account-resource-group>/providers/Microsoft.CodeSigning/codeSigningAccounts/<ts-account>/certificateProfiles/<ts-cert-profile>
    az role assignment create --assignee $CLIENT_ID --scope $TS_SCOPE --role "Trusted Signing Certificate Profile Signer"
    

  1. Skonfiguruj usługę GitHub tak, aby ufała twojej tożsamości. Postępuj zgodnie z Konfigurowaniem tożsamości zarządzanej przypisanej przez użytkownika, aby zaufać zewnętrznemu dostawcy tożsamości.

  2. Utwórz wpisy tajne GitHub, postępując zgodnie z instrukcją Tworzenie wpisów tajnych dla repozytorium.

    Zamapuj wartości tożsamości zarządzanej z tymi sekretami.

    Wpis tajny usługi GitHub Wartość tożsamości zarządzanej
    AZURE_CLIENT_ID ID klienta
    AZURE_SUBSCRIPTION_ID Identyfikator subskrypcji
    AZURE_TENANT_ID Identyfikator katalogu (klienta)

Przechowaj certyfikat główny TSA

Sygnatura czasowa (RFC 3161) przedłuża zaufanie do podpisów poza okresem ważności certyfikatu podpisywania. Zaufane podpisywanie używa certyfikatów krótkotrwałych, więc sygnatura czasowa ma krytyczne znaczenie. Adres URL serwera urzędu sygnatury czasowej (TSA) jest dostępny pod adresem http://timestamp.acs.microsoft.com/, zgodnie z zaleceniami w artykule Sygnatura czasowa kontrapisy.

  1. Pobierz certyfikat główny TSA:

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

  1. Zapisz certyfikat główny w repozytorium; na przykład .github/certs/msft-identity-verification-root-cert-authority-2020.crt. Użyjesz ścieżki pliku w przepływie pracy.

Tworzenie przepływu pracy funkcji GitHub Actions

  1. .github/workflows Utwórz katalog w repozytorium, jeśli nie istnieje.

  2. Utwórz nowy plik przepływu pracy; na przykład .github/workflows/sign-with-trusted-signing.yml.

  3. Skopiuj następujący szablon przepływu pracy podpisywania do pliku.

Rozwiń, aby wyświetlić szablon przepływu podpisywania.
# Build and push an image to Azure Container Registry, set up notation, and sign the image
name: notation-github-actions-sign-with-trusted-signing-template

on:
  push:

env:
  ACR_LOGIN_SERVER: <registry-login-server>             # example: myregistry.azurecr.io
  ACR_REPO_NAME: <repository-name>                      # example: myrepo
  IMAGE_TAG: <image-tag>                                # example: v1
  PLUGIN_NAME: azure-trustedsigning                     # name of Notation Trusted Signing plug-in; do not change
  PLUGIN_DOWNLOAD_URL: <plugin-download-url>            # example: "https://github.com/Azure/trustedsigning-notation-plugin/releases/download/v1.0.0-beta.1/notation-azure-trustedsigning_1.0.0-beta.1_linux_amd64.tar.gz"
  PLUGIN_CHECKSUM: <plugin-package-checksum>            # example: 538b497be0f0b4c6ced99eceb2be16f1c4b8e3d7c451357a52aeeca6751ccb44
  TSA_URL: "http://timestamp.acs.microsoft.com/"        # timestamping server URL
  TSA_ROOT_CERT: <root-cert-file-path>                  # example: .github/certs/msft-identity-verification-root-cert-authority-2020.crt
  TS_ACCOUNT_NAME: <trusted-signing-account-name>       # Trusted Signing account name
  TS_CERT_PROFILE: <trusted-signing-cert-profile-name>  # Trusted Signing certificate profile name 
  TS_ACCOUNT_URI: <trusted-signing-account-uri>         # Trusted Signing account URI; for example, "https://eus.codesigning.azure.net/"

jobs:
  notation-sign:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
     # packages: write
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: prepare
        id: prepare
        run: |
          echo "target_artifact_reference=${{ env.ACR_LOGIN_SERVER }}/${{ env.ACR_REPO_NAME }}:${{ env.IMAGE_TAG }}" >> "$GITHUB_ENV"
      
      # 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 }}
      # Build and push an image to the registry
      # Use `Dockerfile` as an example to build an image
      - name: Build and push
        id: push
        uses: docker/build-push-action@v4
        with:
          push: true
          tags: ${{ env.target_artifact_reference }}
          build-args: |
            IMAGE_TAG={{ env.IMAGE_TAG }}
      # Get the manifest digest of the OCI artifact
      - name: Retrieve digest
        run: |
          echo "target_artifact_reference=${{ env.ACR_LOGIN_SERVER }}/${{ env.ACR_REPO_NAME }}@${{ steps.push.outputs.digest }}" >> "$GITHUB_ENV" 
      # Set up the Notation CLI
      - name: setup notation
        uses: notaryproject/notation-action/setup@v1.2.2
      # Sign your container images and OCI artifacts by using a private key stored in Azure Key Vault
      - name: sign OCI artifacts with Trusted Signing
        uses: notaryproject/notation-action/sign@v1
        with:
          timestamp_url: ${{ env.TSA_URL}}
          timestamp_root_cert: ${{env.TSA_ROOT_CERT }}
          plugin_name: ${{ env.PLUGIN_NAME }}
          plugin_url: ${{ env.PLUGIN_DOWNLOAD_URL }}
          plugin_checksum: ${{ env.PLUGIN_CHECKSUM }}
          key_id: ${{ env.TS_CERT_PROFILE }}
          target_artifact_reference: ${{ env.target_artifact_reference }}
          signature_format: cose
          plugin_config: |-
            accountName=${{ env.TS_ACCOUNT_NAME }}
            baseUrl=${{ env.TS_ACCOUNT_URI }}
            certProfile=${{ env.TS_CERT_PROFILE }}
          force_referrers_tag: 'false'

Uwagi dotyczące zmiennych środowiskowych:

  • PLUGIN_NAME: Zawsze używaj azure-trustedsigning.
  • PLUGIN_DOWNLOAD_URL: Pobierz URL ze strony wydania wtyczki Trusted Signing.
  • PLUGIN_CHECKSUM: Użyj pliku sumy kontrolnej na stronie wydania; na przykład notation-azure-trustedsigning_<version>_checksums.txt.
  • TS_ACCOUNT_URI: użyj punktu końcowego dla konta zaufanego podpisywania, specyficznego dla jego regionu; na przykład https://eus.codesigning.azure.net/.

Uruchom przepływ pracy GitHub Actions

Składnia on:push wyzwala przykładowy przepływ pracy. Zatwierdzanie zmian powoduje uruchomienie przepływu pracy. W obszarze nazwy repozytorium GitHub wybierz pozycję Akcje , aby wyświetlić dzienniki przepływu pracy.

W przypadku powodzenia przepływ pracy tworzy obraz, przesyła go do Azure Container Registry i podpisuje przy użyciu Zaufanego Podpisywania. Możesz wyświetlić dzienniki przepływu pracy, aby potwierdzić, że azure-trustedsigning wtyczka została zainstalowana, a obraz został pomyślnie podpisany.

Ponadto możesz otworzyć rejestr kontenerów w witrynie Azure Portal. Przejdź do obszaru Repozytoria, przejdź do obrazu, a następnie wybierz pozycję Odwołania. Potwierdź, że artefakty (podpisy) typu application/vnd.cncf.notary.signature są wyświetlane.