Creazione di attestazioni

Questa pagina descrive i passaggi per creare un'Autorizzazione binaria attestazione.

Utilizza le attestazioni per autorizzare il deployment di immagini container specifiche su piattaforme come Google Kubernetes Engine (GKE) e Cloud Run. Per utilizzare le attestazioni, devi richiederle nella regola appropriata della tua policy.

Una singola attestazione può autorizzare immagini identiche archiviate in più posizioni o registri diversi, come Artifact Registry, Container Registry o un registro container esterno.

In fase di deployment, Autorizzazione binaria utilizza gli attestatori per verificare le attestazioni.

Per configurare Autorizzazione binaria su Cloud Run, GKE, Google Distributed Cloud e Cloud Service Mesh, consulta Configurazione per piattaforma e seleziona la tua piattaforma.

Utenti di GKE: per un tutorial end-to-end che descrive l'applicazione basata su attestazioni utilizzando Autorizzazione binaria e Google Kubernetes Engine (GKE), consulta Inizia a utilizzare lo strumento a riga di comando o Inizia a utilizzare la Google Cloud console.

Prima di iniziare

La panoramica delle attestazioni fornisce i passaggi da completare prima di creare un'attestazione.

  1. Attiva Autorizzazione binaria

  2. Crea gli attestatori utilizzando la Google Cloud console, il Google Cloud CLI, o l'API REST.

Configura l'ambiente

  1. Specifica gli ID progetto:

    ATTESTOR_PROJECT_ID=ATTESTOR_PROJECT_ID
    ATTESTATION_PROJECT_ID=ATTESTATION_PROJECT_ID
    

    Sostituisci quanto segue:

    • ATTESTOR_PROJECT_ID: il nome del progetto in cui memorizzi gli attestatori
    • ATTESTATION_PROJECT_ID: il nome del progetto in cui memorizzi le attestazioni

    Se vuoi che l'attestazione venga creata nello stesso progetto degli attestatori, utilizza lo stesso ID progetto per entrambe le variabili. Per un tutorial end-to-end che illustra la separazione dei compiti con progetti diversi, consulta Configurazione per più progetti.

  2. Specifica il nome dell'attestatore e le informazioni sull'immagine:

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

    Sostituisci quanto segue:

    • ATTESTOR_NAME: il nome dell'attestatore, ad esempio build-secure o prod-qa.
    • IMAGE_PATH: un URI che rappresenta un percorso dell'immagine. Sebbene l'URI debba comprendere un dominio e un nome dell'immagine, non deve necessariamente fare riferimento a un'immagine effettiva. Non si accede alle immagini durante la creazione dell'attestazione. Di seguito sono riportati alcuni esempi di percorsi delle immagini:

      • us-docker.pkg.dev/google-samples/containers/gke/hello-app
      • gcr.io/example-project/quickstart-image
      • example.com/hello-app.
    • IMAGE_DIGEST: il digest del manifest dell'immagine. Ad esempio, sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567 è il digest dell'immagine associato al percorso dell'immagine di esempio us-docker.pkg.dev/google-samples/containers/gke/hello-app. Per scoprire come ottenere il digest di un'immagine in Artifact Registry, consulta Gestire le immagini; per un'immagine in Container Registry, consulta Elencare le versioni di un'immagine.

Concedi i ruoli Identity and Access Management

Per creare le attestazioni, devi concedere i seguenti ruoli Identity and Access Management (IAM) all'identità che crea l'attestatore:

  • roles/containeranalysis.notes.attacher sulla risorsa della nota associata all'attestatore.
  • roles/containeranalysis.occurrences.editor sulla risorsa del progetto di attestazione.

Crea un'attestazione basata su un attestatore. L'attestatore è associato a una nota di Artifact Analysis. La creazione di un'attestazione crea a sua volta un'occorrenza di Artifact Analysis e la associa alla nota.

Scopri di più su concessione dell'accesso.

Per scoprire come creare un'attestazione in una pipeline di Cloud Build, consulta Creare attestazioni con Cloud Build.

Crea un'attestazione

Crea un'attestazione utilizzando una chiave archiviata localmente

Per creare attestazioni firmate con una chiave locale:

  1. Crea un file di payload della firma:

    gcloud

    Per creare il file di payload della firma, inserisci il comando seguente:

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

    Il file di payload in formato JSON è simile all'output seguente:

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

    API REST

    Crea un file di payload denominato /tmp/generated_payload.json utilizzando le variabili di ambiente che hai impostato in precedenza in questo documento:

    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. Firma il payload con la tua chiave privata per generare un file di firma.

    Questa guida utilizza l'algoritmo Elliptic Curve Digital Signature Algorithm (ECDSA) consigliato per la firma. Puoi anche utilizzare l'algoritmo RSA. Per ulteriori informazioni sugli algoritmi di firma, consulta Scopi e algoritmi delle chiavi. Questa guida utilizza anche il formato di firma PKIX (Public-Key Infrastructure (X.509)). Puoi anche utilizzare PGP.

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

    Sostituisci PRIVATE_KEY_FILE con il percorso della chiave privata che hai generato quando hai creato l'attestatore.

  3. Recupera l'ID della chiave pubblica.

    Puoi recuperare l'ID della chiave pubblica dall'attestatore inserendo il comando seguente:

    PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \
      --format='value(userOwnedGrafeasNote.publicKeys[0].id)')
    
  4. Crea l'attestazione:

    gcloud

    Per creare e convalidare l'attestazione, inserisci quanto segue:

    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
    

    Il flag validate verifica che l'attestazione possa essere verificata dall'attestatore configurato nella policy.

    Nota: l'ID chiave può essere qualsiasi stringa.

    API REST

    Per creare l'attestazione:

    1. Recupera l'attestatore associato all'attestazione ed estrai l'ID della chiave pubblica memorizzata:

      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/"
      

      Autorizzazione binaria restituisce un oggetto JSON simile al seguente:

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

      La chiave pubblica è disponibile nel campo id.

    2. Crea un file JSON in /tmp/attestation.json che descriva l'attestazione:

      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. Crea l'attestazione:

      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/"
      

Crea un'attestazione utilizzando Cloud KMS

Per creare un'attestazione utilizzando Cloud Key Management Service:

  1. Crea le variabili di ambiente:

    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
    

    Sostituisci quanto segue:

    • KMS_KEY_PROJECT_ID: l'ID del progetto in cui sono archiviate le chiavi di Cloud Key Management Service
    • KMS_KEY_LOCATION: la località della chiave (global è il valore predefinito)
    • KMS_KEYRING_NAME: il nome del portachiavi
    • KMS_KEY_NAME: il nome della chiave
    • KMS_KEY_VERSION: la versione della chiave
  2. Firma e crea l'attestazione:

    gcloud

    Inserisci questo comando:

    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}" \
        --validate
    

    Il flag validate verifica che l'attestazione possa essere verificata dall'attestatore configurato nella policy.

    API REST

    1. Crea un file di payload denominato /tmp/generated_payload.json utilizzando le variabili di ambiente che hai impostato sopra:

      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. Firma il file di payload:

      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
      

      Sostituisci DIGEST_ALGORITHM con l'algoritmo per il digest dell'input. Gli esempi in questa guida utilizzano un digest sha256. Puoi utilizzare sha256, sha384 o sha512.

      In questo esempio, l'output è simile al seguente:

      {
        "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 questo output, SIGNATURE è la firma con codifica Base64 del file di payload.

    3. Memorizza la firma in una variabile di ambiente:

      PAYLOAD_SIGNATURE=PAYLOAD_SIGNATURE
      
    4. Recupera l'attestatore per conto del quale stai firmando l'attestazione ed estrai l'ID della chiave pubblica memorizzata e l'ID della nota:

      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/"
      

      Autorizzazione binaria restituisce un oggetto JSON simile al seguente:

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

      Puoi trovare l'ID della chiave pubblica nel campo id e l'ID della nota nel campo noteReference.

    5. Memorizza l'ID della chiave pubblica in una variabile di ambiente:

      PUBLIC_KEY_ID="PUBLIC_KEY_ID"
      NOTE_URI="NOTE_URI"
      

      Sostituisci quanto segue:

      • PUBLIC_KEY_ID: l'ID della chiave pubblica dell'attestatore.
      • NOTE_URI: l'URI della nota di Artifact Analysis associata all'attestatore.
    6. Crea un file JSON in /tmp/attestation.json che descriva l'attestazione:

      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. Crea l'attestazione:

      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/"
      

Hai creato l'attestazione.

Verifica che l'attestazione sia stata creata

Per verificare che l'attestazione sia stata creata, puoi elencare le attestazioni associate all'immagine.

gcloud

Per recuperare un elenco di attestazioni, inserisci il comando seguente:

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

API REST

Per richiedere un elenco di attestazioni, inserisci il comando seguente:

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

Se sono presenti molte attestazioni, la risposta potrebbe contenere un valore nextPageToken. In questo caso, puoi recuperare la pagina successiva dei risultati ripetendo la richiesta, aggiungendo un parametro di query pageToken come segue:

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}

Sostituisci NEXT_PAGE_TOKEN con il valore nextPageToken nella risposta della richiesta precedente.

Quando nextPageToken è vuoto, significa che non ci sono altri risultati.

Elimina l'attestazione

Prima di eliminare l'attestazione, devi:

  1. Comprendere le conseguenze dell'eliminazione. L'eliminazione di un'attestazione alla fine impedisce il deployment delle immagini container associate all'attestazione.

  2. Arresta tutti i container in esecuzione associati alle attestazioni che intendi eliminare.

  3. Elimina tutte le copie delle attestazioni ovunque si trovino, ad esempio le attestazioni nei repository di Artifact Registry e Artifact Analysis.

  4. Assicurati che il deployment delle immagini interessate sia effettivamente bloccato tentando di eseguirne di nuovo il deployment.

Per eliminare un'attestazione, esegui i seguenti comandi:

  1. Elenca le attestazioni:

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

    L'attestazione contiene un ID occorrenza. L'output è simile al seguente:

    projects/ATTESTOR_PROJECT_ID/occurrences/OCCURRENCE_ID
    
  2. Salva l'ID occorrenza.

    Salva l'ID occorrenza dell'attestazione che vuoi eliminare.

    OCCURRENCE_ID=OCCURRENCE_ID
    
  3. Elimina l'attestazione:

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

    Verifica che le attestazioni siano state eliminate elencandole di nuovo.

Passaggi successivi