Attestierungen erstellen

Auf dieser Seite werden die Schritte zum Erstellen einer Attestierung einer Binärautorisierung beschrieben.

Mit einer einzelnen Attestierung können identische Images autorisiert werden, die an mehreren verschiedenen Speicherorten oder in verschiedenen Registries gespeichert sind, z. B. Artifact Registry, Container Registry oder eine externe Container Registry.

Zum Zeitpunkt der Bereitstellung verwendet die Binärautorisierung Attestierer, um Attestierungen zu prüfen.

Eine End-to-End-Anleitung, die die auf Attestierung basierende Erzwingung mit Binärautorisierung und Google Kubernetes Engine (GKE) beschreibt, finden Sie unter Erste Schritte mit dem Befehlszeilentool oder Erste Schritte mit der Google Cloud Console.

Hinweis

Im Überblick über Attestierungen finden Sie Schritte, die vor dem Erstellen einer Attestierung abgeschlossen werden müssen.

Umgebung einrichten

  1. Geben Sie Ihre Projekt-IDs an:

    ATTESTOR_PROJECT_ID=ATTESTOR_PROJECT_ID
    ATTESTATION_PROJECT_ID=ATTESTATION_PROJECT_ID
    

    Dabei gilt:

    • ATTESTOR_PROJECT_ID: Der Name des Projekts, in dem Sie die Attestierer speichern
    • ATTESTATION_PROJECT_ID: Der Name des Projekts, in dem Sie die Attestierungen speichern

    Wenn Ihre Attestierung im selben Projekt wie Ihre Attestierer erstellt werden soll, verwenden Sie für beide Variablen dieselbe Projekt-ID. Eine End-to-End-Anleitung, die die Aufgabentrennung mit verschiedenen Projekten veranschaulicht, finden Sie unter Mehrere Projekte einrichten.

  2. Geben Sie den Namen des Attestierers und die Image-Informationen an:

    ATTESTOR_NAME=ATTESTOR_NAME
    IMAGE_PATH=IMAGE_PATH
    IMAGE_DIGEST=IMAGE_DIGEST
    IMAGE_TO_ATTEST="${IMAGE_PATH}@${IMAGE_DIGEST}"
    

    Dabei gilt:

    • ATTESTOR_NAME: Der Name des Attestierers, z. B. build-secure oder prod-qa.
    • IMAGE_PATH: Ein URI, der einen Image-Pfad darstellt. Obwohl der URI eine Domain und einen Image-Namen enthalten muss, muss er nicht auf ein tatsächliches Image verweisen. Auf Images wird während der Attestierungserstellung nicht zugegriffen. Im Folgenden finden Sie Beispiele für Image-Pfade:

      • us-docker.pkg.dev/google-samples/containers/gke/hello-app
      • gcr.io/example-project/quickstart-image
      • example.com/hello-app.
    • IMAGE_DIGEST: Der Digest des Image-Manifests. Beispiel: sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567 ist der Image-Digest-Wert, der dem Beispielpfad us-docker.pkg.dev/google-samples/containers/gke/hello-app zugeordnet ist. Wie Sie den Digest eines Images in Artifact Registry erhalten, erfahren Sie unter Images verwalten. Informationen zu einem Image in Container Registry finden Sie unter Versionen eines Images auflisten.

Identity and Access Management-Rollen zuweisen

Zum Erstellen von Attestierungen müssen Sie der Identität, die den Attestierer erstellt, die folgenden IAM-Rollen (Identity and Access Management) so zuweisen:

  • roles/containeranalysis.notes.attacher für die mit dem Attestierer verknüpfte Hinweisressource.
  • roles/containeranalysis.occurrences.editor für die Attestierungsprojektressource.

Sie erstellen eine Attestierung basierend auf einem Attestierer. Der Attestierer ist einem Container Analysis-Hinweis zugeordnet. Wenn Sie eine Attestierung erstellen, wird ein Container Analysis-Vorkommen erstellt und an den Hinweis angehängt.

Weitere Informationen finden Sie unter Zugriff auf Ressourcen erteilen, ändern und entziehen.

Informationen zum Erstellen einer Attestierung in einer Cloud Build-Pipeline finden Sie unter Attestierungen mit Kritis Signer erstellen.

Attestierung erstellen

Attestierung mit einem lokal gespeicherten Schlüssel erstellen

So erstellen Sie Attestierungen, die mit einem lokalen Schlüssel signiert wurden:

  1. Erstellen Sie eine Signaturnutzlastdatei:

    gcloud

    Geben Sie den folgenden Befehl ein, um die Signaturnutzlastdatei zu erstellen:

    gcloud container binauthz create-signature-payload \
        --artifact-url="${IMAGE_TO_ATTEST}" > /tmp/generated_payload.json
    

    Die JSON-formatierte Nutzlastdatei sieht in etwa so aus:

    {
      "critical": {
        "identity": {
          "docker-reference": "us-docker.pkg.dev/google-samples/containers/gke/hello-app"
        },
        "image": {
          "docker-manifest-digest": "sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567"
        },
        "type": "Google cloud binauthz container signature"
      }
    }
    

    REST API

    Erstellen Sie eine Nutzlastdatei namens /tmp/generated_payload.json mit den zuvor in diesem Dokument festgelegten Umgebungsvariablen:

    cat > /tmp/generated_payload.json << EOM
    {
      "critical": {
        "identity": {
          "docker-reference": "${IMAGE_PATH}"
        },
        "image": {
          "docker-manifest-digest": "${IMAGE_DIGEST}"
        },
        "type": "Google cloud binauthz container signature"
      }
    }
    EOM
    
  2. Signieren Sie die Nutzlast mit dem privaten Schlüssel, um eine Signaturdatei zu generieren.

    In dieser Anleitung wird der empfohlene Elliptic Curve Digital Signing Algorithm (ECDSA) zum Signieren verwendet. Sie können auch den RSA-Algorithmus verwenden. Weitere Informationen zu Signaturalgorithmen finden Sie unter Schlüsselzwecke und Algorithmen. In dieser Anleitung wird auch das Signaturformat Public-Key-Infrastruktur (X.509) (PKIX) verwendet. Sie können auch PGP verwenden.

    PRIVATE_KEY_FILE=PRIVATE_KEY_FILE
    openssl dgst -sha256 -sign ${PRIVATE_KEY_FILE} /tmp/generated_payload.json > /tmp/ec_signature
    

    Ersetzen Sie PRIVATE_KEY_FILE durch den Pfad zu dem privaten Schlüssel, den Sie beim Erstellen des Attestierers generiert haben.

  3. Rufen Sie die ID des öffentlichen Schlüssels ab.

    Sie können die ID des öffentlichen Schlüssels vom Attestierer abrufen. Geben Sie dafür den folgenden Befehl ein:

    PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \
      --format='value(userOwnedGrafeasNote.publicKeys[0].id)')
    
  4. Erstellen Sie eine Attestierung:

    gcloud

    Geben Sie zum Erstellen und Validieren der Attestierung Folgendes ein:

    gcloud container binauthz attestations create \
        --project="${ATTESTATION_PROJECT_ID}" \
        --artifact-url="${IMAGE_TO_ATTEST}" \
        --attestor="projects/${ATTESTOR_PROJECT_ID}/attestors/${ATTESTOR_NAME}" \
        --signature-file=/tmp/ec_signature \
        --public-key-id="${PUBLIC_KEY_ID}" \
        --validate
    

    Das Flag validate prüft, ob die Attestierung von dem Attestierer geprüft werden kann, den Sie in Ihrer Richtlinie konfiguriert haben.

    Hinweis: Die Schlüssel-ID kann ein beliebiger String sein.

    REST API

    So erstellen Sie die Attestierung:

    1. Rufen Sie den mit der Attestierung verknüpften Attestierer ab und extrahieren Sie die gespeicherte ID des öffentlichen Schlüssels:

      curl \
          -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
          -H "x-goog-user-project: ${ATTESTOR_PROJECT_ID}" \
          "https://binaryauthorization.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/attestors/"
      

      Die Binärautorisierung gibt ein JSON-Objekt zurück, das in etwa so aussieht:

      {
        "name": "projects/example-project/attestors/test-attestor",
        "userOwnedGrafeasNote": {
          "noteReference": "projects/example-project/notes/test-attestor",
          "publicKeys": [
            {
              "id": "ni:///sha-256;EwVxs8fNUAHq9FI2AMfh8WNIXVBuuTMeGtPH72U-I70",
              "pkixPublicKey": {
                "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXnpuYEfvLl1kj4fjxViFRwY1a+zC\n5qzlf9LJIK+rnjq42tiKGyyXMbnZKJiYPPdMDGyltnkrABnztg2jJ48aYQ==\n-----END PUBLIC KEY-----\n",
                "signatureAlgorithm": "ECDSA_P256_SHA256"
              }
            }
          ],
          "delegationServiceAccountEmail": "service-363451293945@gcp-sa-binaryauthorization.iam.gserviceaccount.com"
        },
        "updateTime": "2019-06-26T16:58:33.977438Z"
      }
      

      Der öffentliche Schlüssel befindet sich im Feld id.

    2. Erstellen Sie unter /tmp/attestation.json eine JSON-Datei, die die Attestierung beschreibt:

      cat > /tmp/attestation.json << EOM
      {
        "resourceUri": "${IMAGE_TO_ATTEST}",
        "note_name": "${NOTE_URI}",
        "attestation": {
           "serialized_payload": "$(base64 --wrap=0 /tmp/generated_payload.json)",
           "signatures": [
              {
               "public_key_id": "${PUBLIC_KEY_ID}",
               "signature": "$(base64 --wrap=0 /tmp/ec_signature)"
              }
           ]
        }
       }
      EOM
      
    3. Erstellen Sie eine Attestierung:

      curl -X POST \
          -H "Content-Type: application/json" \
          -H "X-Goog-User-Project: ${ATTESTATION_PROJECT_ID}" \
          -H "Authorization: Bearer $(gcloud auth print-access-token)" \
          --data-binary @/tmp/attestation.json \
          "https://containeranalysis.googleapis.com/v1/projects/${ATTESTATION_PROJECT_ID}/occurrences/"
      

Attestierung mit Cloud KMS erstellen

So erstellen Sie eine Attestierung mithilfe des Cloud Key Management Service:

  1. Erstellen Sie Umgebungsvariablen:

    KMS_KEY_PROJECT_ID=KMS_KEY_PROJECT_ID
    KMS_KEY_LOCATION=KMS_KEY_LOCATION
    KMS_KEYRING_NAME=KMS_KEYRING_NAME
    KMS_KEY_NAME=KMS_KEY_NAME
    KMS_KEY_VERSION=KMS_KEY_VERSION
    

    Dabei gilt:

    • KMS_KEY_PROJECT_ID: Die ID des Projekts, in dem Ihre Cloud Key Management Service-Schlüssel gespeichert sind.
    • KMS_KEY_LOCATION: Der Speicherort des Schlüssels (global ist die Standardeinstellung)
    • KMS_KEYRING_NAME: Der Name des Schlüsselbunds
    • KMS_KEY_NAME: Der Name des Schlüssels
    • KMS_KEY_VERSION: Die Schlüsselversion
  2. Signieren Sie die Attestierung und erstellen Sie sie:

    gcloud

    Geben Sie den folgenden Befehl ein:

    gcloud beta container binauthz attestations sign-and-create \
        --project="${ATTESTATION_PROJECT_ID}" \
        --artifact-url="${IMAGE_TO_ATTEST}" \
        --attestor="${ATTESTOR_NAME}" \
        --attestor-project="${ATTESTOR_PROJECT_ID}" \
        --keyversion-project="${KMS_KEY_PROJECT_ID}" \
        --keyversion-location="${KMS_KEY_LOCATION}" \
        --keyversion-keyring="${KMS_KEYRING_NAME}" \
        --keyversion-key="${KMS_KEY_NAME}" \
        --keyversion="${KMS_KEY_VERSION}"
    

    REST API

    1. Erstellen Sie eine Nutzlastdatei namens /tmp/generated_payload.json mit den oben festgelegten Umgebungsvariablen:

      cat > /tmp/generated_payload.json << EOM
      {
        "critical": {
          "identity": {
            "docker-reference": "${IMAGE_PATH}"
          },
          "image": {
            "docker-manifest-digest": "${IMAGE_DIGEST}"
          },
          "type": "Google cloud binauthz container signature"
        }
      }
      EOM
      
    2. Signieren Sie die Nutzlastdatei:

      curl \
        --header "Content-Type: application/json" \
        --header "Authorization: Bearer $(gcloud auth print-access-token)" \
        --header "x-goog-user-project: ${ATTESTOR_PROJECT_ID}" \
        --data '{"digest":  {"DIGEST_ALGORITHM": "'$(openssl dgst -sha256 -binary /tmp/generated_payload.json | openssl base64)'" }}' \
      https://cloudkms.googleapis.com/v1/projects/${KMS_KEY_PROJECT_ID}/locations/${KMS_KEY_LOCATION}/keyRings/${KMS_KEYRING_NAME}/cryptoKeys/${KMS_KEY_NAME}/cryptoKeyVersions/${KMS_KEY_VERSION}:asymmetricSign?alt=json
      

      Ersetzen Sie DIGEST_ALGORITHM durch den Algorithmus zum Verarbeiten der Eingabe. In diesem Leitfaden wird ein sha256-Digest verwendet. Sie können sha256, sha384 oder sha512 verwenden.

      In diesem Beispiel sieht die Ausgabe etwa so aus:

      {
        "signature": "<var>SIGNATURE</var>": "996305066",
        "name": "projects/<var>KMS_KEY_PROJECT_ID</var>/locations/<var>KMS_KEY_LOCATION</var>/keyRings/<var>KMS_KEYRING_NAME</var>/cryptoKeys/<var>KMS_KEY_NAME</var>/cryptoKeyVersions/<var>KMS_KEY_VERSION</var>"
      }
      

      In dieser Ausgabe ist SIGNATURE die base64-codierte Signatur der Nutzlastdatei.

    3. Speichern Sie die Signatur in einer Umgebungsvariablen:

      PAYLOAD_SIGNATURE=PAYLOAD_SIGNATURE
      
    4. Rufen Sie den Attestierer ab, in dessen Namen Sie die Attestierung signieren, und extrahieren Sie die gespeicherte ID des öffentlichen Schlüssels und die Hinweis-ID:

      curl \
          -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
          -H "x-goog-user-project: ${ATTESTOR_PROJECT_ID}" \
          "https://binaryauthorization.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/attestors/"
      

      Die Binärautorisierung gibt ein JSON-Objekt zurück, das in etwa so aussieht:

      {
        "name": "projects/example-project/attestors/test-attestor",
        "userOwnedGrafeasNote": {
          "noteReference": "projects/example-project/notes/test-attestor",
          "publicKeys": [
            {
              "id": "ni:///sha-256;EwVxs8fNUAHq9FI2AMfh8WNIXVBuuTMeGtPH72U-I70",
              "pkixPublicKey": {
                "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXnpuYEfvLl1kj4fjxViFRwY1a+zC\n5qzlf9LJIK+rnjq42tiKGyyXMbnZKJiYPPdMDGyltnkrABnztg2jJ48aYQ==\n-----END PUBLIC KEY-----\n",
                "signatureAlgorithm": "ECDSA_P256_SHA256"
              }
            }
          ],
          "delegationServiceAccountEmail": "service-363451293945@gcp-sa-binaryauthorization.iam.gserviceaccount.com"
        },
        "updateTime": "2019-06-26T16:58:33.977438Z"
      }
      

      Die ID des öffentlichen Schlüssels befindet sich im Feld id und die ID im Hinweisfeld noteReference.

    5. Speichern Sie die ID des öffentlichen Schlüssels in einer Umgebungsvariablen:

      PUBLIC_KEY_ID="PUBLIC_KEY_ID"
      NOTE_URI="NOTE_URI"
      

      Dabei gilt:

      • PUBLIC_KEY_ID: Die ID des öffentlichen Schlüssels des Attestierers.
      • NOTE_URI: Der URI des Container Analysis-Hinweises, der dem Attestierer zugeordnet ist.
    6. Erstellen Sie unter /tmp/attestation.json eine JSON-Datei, die die Attestierung beschreibt:

      cat > /tmp/attestation.json << EOM
      {
        "resourceUri": "${IMAGE_TO_ATTEST}",
        "note_name": "${NOTE_URI}",
        "attestation": {
           "serialized_payload": "$(base64 --wrap=0 /tmp/generated_payload.json)",
           "signatures": [
               {
                   "public_key_id": "${PUBLIC_KEY_ID}",
                   "signature": "${PAYLOAD_SIGNATURE}"
               }
           ]
        }
      }
      EOM
      
    7. Erstellen Sie eine Attestierung:

      curl -X POST \
          -H "Content-Type: application/json" \
          -H "X-Goog-User-Project: ${ATTESTATION_PROJECT_ID}" \
          -H "Authorization: Bearer $(gcloud auth print-access-token)" \
          --data-binary @/tmp/attestation.json \
      "https://containeranalysis.googleapis.com/v1/projects/${ATTESTATION_PROJECT_ID}/occurrences/"
      

Sie haben die Attestierung erstellt.

Attestierung auf Erstellung prüfen

Sie können die mit dem Image verknüpften Attestierungen auflisten, um zu prüfen, ob die Attestierung erstellt wurde.

gcloud

Geben Sie den folgenden Befehl ein, um eine Liste der Attestierungen abzurufen:

gcloud container binauthz attestations list\
    --project="${ATTESTATION_PROJECT_ID}"\
    --attestor="projects/${ATTESTOR_PROJECT_ID}/attestors/${ATTESTOR_NAME}"\
    --artifact-url="${IMAGE_TO_ATTEST}"

REST API

Geben Sie den folgenden Befehl ein, um eine Liste der Attestierungen anzufragen:

curl -X GET \
    -H "Content-Type: application/json" \
    -H "X-Goog-User-Project: ${ATTESTOR_PROJECT_ID}" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
https://containeranalysis.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}/occurrences?filter=resourceUrl%3D%22https%3A%2F%2F$(jq -rn --arg x ${IMAGE_TO_ATTEST} '$x|@uri')%22

Wenn viele Attestierungen vorhanden sind, enthält die Antwort möglicherweise einen nextPageToken-Wert. In diesem Fall können Sie die nächste Ergebnisseite abrufen. Wiederholen Sie dazu die Anfrage und fügen dabei einen pageToken-Abfrageparameter hinzu:

NEXT_PAGE_TOKEN=NEXT_PAGE_TOKEN
curl -X GET \
    -H "Content-Type: application/json" \
    -H "X-Goog-User-Project: ${ATTESTOR_PROJECT_ID}" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
https://containeranalysis.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}/occurrences?filter=resourceUrl%3D%22https%3A%2F%2F$(jq -rn --arg x ${IMAGE_TO_ATTEST} '$x|@uri')%22&pageToken=${NEXT_PAGE_TOKEN}

Ersetzen Sie NEXT_PAGE_TOKEN durch den Wert nextPageToken in der Antwort der vorherigen Anfrage.

Wenn nextPageToken leer ist, bedeutet dies, dass keine weiteren Ergebnisse vorhanden sind.

Attestierung löschen

Bevor Sie die Attestierung löschen, sollten Sie Folgendes tun:

  1. Informieren Sie sich über die Auswirkungen des Löschens. Durch das Löschen einer Attestierung wird verhindert, dass mit der Attestierung verknüpfte Container-Images bereitgestellt werden.

  2. Beenden Sie alle ausgeführten Container, die den Attestierungen zugeordnet sind, die Sie löschen möchten.

  3. Löschen Sie alle Kopien der Attestierungen, wo auch immer sie sich befinden, z. B. Attestierungen in den Repositories Artifact Registry und Container Analysis.

  4. Prüfen Sie, ob die betroffenen Images tatsächlich von der Bereitstellung blockiert sind. Versuchen Sie dazu, sie noch einmal bereitzustellen.

Führen Sie die folgenden Befehle aus, um eine Attestierung zu löschen:

  1. Listen Sie die Attestierungen auf:

    gcloud container binauthz attestations list \
      --attestor-project=${ATTESTOR_PROJECT_ID} \
      --attestor=${ATTESTOR_NAME}
    

    Die Attestierung enthält eine Vorkommen-ID. Die Ausgabe sieht dann ungefähr so aus:

    projects/ATTESTOR_PROJECT_ID/occurrences/OCCURRENCE_ID
    
  2. Speichern Sie die Vorkommen-ID.

    Speichern Sie die Vorkommen-ID der Attestierung, die Sie löschen möchten.

    OCCURRENCE_ID=OCCURRENCE_ID
    
  3. Löschen Sie die Attestierung:

    curl -H "Authorization: Bearer $(gcloud auth print-access-token)" -X DELETE \
      https://containeranalysis.googleapis.com/v1beta1/projects/${ATTESTATION_PROJECT_ID}/occurrences/${OCCURRENCE_ID}
    

    Prüfen Sie, ob die Attestierungen gelöscht wurden. Listen Sie dazu die Attestierungen noch einmal auf.

Nächste Schritte