建立認證

本頁說明如何建立二進位授權 驗證記錄

您可以使用驗證,授權特定容器映像檔部署至 Google Kubernetes Engine (GKE) 和 Cloud Run 等平台。如要使用認證,您必須在政策的適當規則中要求認證。

單一驗證可授權儲存在多個不同位置或不同登錄檔 (例如 Artifact RegistryContainer Registry 或外部容器登錄檔) 的相同映像檔。

在部署時,二進位授權會使用驗證者驗證認證。

如要在 Cloud Run、GKE、Google Distributed Cloud 和 Cloud Service Mesh 上設定二進位授權,請參閱「依平台設定」一文,然後選取您的平台。

GKE 使用者:如需端對端教學課程,瞭解如何使用二進位授權和 Google Kubernetes Engine (GKE) 執行以驗證為基礎的強制執行作業,請參閱使用指令列工具開始使用使用 Google Cloud 控制台開始使用

事前準備

認證總覽一文提供建立認證前必須完成的步驟。

  1. 啟用二進位授權

  2. 使用Google Cloud 控制台Google Cloud CLIREST API 建立驗證者。

設定環境

  1. 指定專案 ID:

    ATTESTOR_PROJECT_ID=ATTESTOR_PROJECT_ID
    ATTESTATION_PROJECT_ID=ATTESTATION_PROJECT_ID
    

    更改下列內容:

    • ATTESTOR_PROJECT_ID:您儲存驗證者的專案名稱
    • ATTESTATION_PROJECT_ID:您儲存認證的專案名稱

    如要讓認證與認證者在同一個專案中建立,請為這兩個變數使用相同的專案 ID。如需示範如何透過不同專案劃分職責的端對端教學課程,請參閱「多專案設定」。

  2. 指定認證者姓名和圖片資訊:

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

    更改下列內容:

    • ATTESTOR_NAME:驗證者名稱,例如 build-secureprod-qa
    • IMAGE_PATH:代表圖片路徑的 URI。雖然 URI 必須包含網域和圖片名稱,但不需要參照實際圖片。建立認證時不會存取圖片。以下是圖片路徑範例:

      • us-docker.pkg.dev/google-samples/containers/gke/hello-app
      • gcr.io/example-project/quickstart-image
      • example.com/hello-app
    • IMAGE_DIGEST:圖片資訊清單的摘要。舉例來說,sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567 是與範例 us-docker.pkg.dev/google-samples/containers/gke/hello-app 圖片路徑相關聯的圖片摘要。如要瞭解如何取得 Artifact Registry 中映像檔的摘要,請參閱管理映像檔;如要取得 Container Registry 中映像檔的摘要,請參閱列出映像檔版本

授予 Identity and Access Management 角色

如要建立認證,您必須將下列 Identity and Access Management (IAM) 角色授予建立認證者的身分

  • roles/containeranalysis.notes.attacher
  • 認證專案資源的 roles/containeranalysis.occurrences.editor 權限。

您會根據認證者建立認證。驗證者與 Artifact Analysis 附註相關聯。建立認證時,系統會建立 Artifact Analysis 項目,並附加至附註。

進一步瞭解如何授予存取權

如要瞭解如何在 Cloud Build 管道中建立認證,請參閱「使用 Cloud Build 建立認證」。

建立認證

使用本機儲存的金鑰建立認證

如要建立以本機金鑰簽署的認證,請執行下列步驟:

  1. 建立簽章酬載檔案:

    gcloud

    如要建立簽章酬載檔案,請輸入下列指令:

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

    JSON 格式的酬載檔案類似於下列輸出內容:

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

    使用您在本文件稍早設定的環境變數,建立名為 /tmp/generated_payload.json 的酬載檔案:

    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. 使用私密金鑰簽署酬載,產生簽章檔案。

    本指南使用建議的橢圓曲線數位簽章演算法 (ECDSA) 進行簽署。您也可以使用 RSA 演算法。如要進一步瞭解簽署演算法,請參閱金鑰用途與演算法一文。本指南也使用公用金鑰基礎架構 (X.509) (PKIX) 簽章格式。您也可以使用 PGP。

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

    PRIVATE_KEY_FILE 替換為您在建立驗證者時產生的私密金鑰路徑。

  3. 取得公開金鑰 ID。

    如要從驗證者擷取公開金鑰 ID,請輸入下列指令:

    PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \
      --format='value(userOwnedGrafeasNote.publicKeys[0].id)')
    
  4. 建立認證:

    gcloud

    如要建立及驗證認證,請輸入下列內容:

    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
    

    validate 旗標會檢查您在政策中設定的認證者是否可驗證認證。

    注意:金鑰 ID 可以是任何字串。

    REST API

    如要建立認證,請按照下列步驟操作:

    1. 擷取與認證相關聯的認證者,並擷取儲存的公開金鑰 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/"
      

      Binary Authorization 會傳回類似下列內容的 JSON 物件:

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

      公開金鑰位於 id 欄位。

    2. /tmp/attestation.json 中建立 JSON 檔案,說明認證:

      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. 建立認證:

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

使用 Cloud KMS 建立認證

如要使用 Cloud Key Management Service 建立認證,請按照下列步驟操作:

  1. 建立環境變數:

    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
    

    更改下列內容:

    • KMS_KEY_PROJECT_ID:儲存 Cloud Key Management Service 金鑰的專案 ID
    • KMS_KEY_LOCATION:金鑰位置 (預設為 global)
    • KMS_KEYRING_NAME:金鑰環的名稱
    • KMS_KEY_NAME:金鑰名稱
    • KMS_KEY_VERSION:金鑰版本
  2. 簽署並建立認證:

    gcloud

    輸入下列指令:

    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. 使用您在上方設定的環境變數,建立名為 /tmp/generated_payload.json 的酬載檔案:

      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. 簽署酬載檔案:

      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
      

      DIGEST_ALGORITHM 改為用來摘要輸入內容的演算法。本指南中的範例使用 sha256 摘要。你可以使用 sha256sha384sha512

      在本例中,輸出內容會與以下內容類似:

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

      在這個輸出內容中,SIGNATURE 是承載檔案的 Base64 編碼簽章。

    3. 將簽章儲存在環境變數中:

      PAYLOAD_SIGNATURE=PAYLOAD_SIGNATURE
      
    4. 擷取您要代表簽署認證的驗證者,並擷取儲存的公開金鑰 ID 和附註 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/"
      

      Binary Authorization 會傳回類似下列內容的 JSON 物件:

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

      公開金鑰 ID 位於 id 欄位,記事 ID 則位於 noteReference 欄位。

    5. 將公開金鑰 ID 儲存在環境變數中:

      PUBLIC_KEY_ID="PUBLIC_KEY_ID"
      NOTE_URI="NOTE_URI"
      

      更改下列內容:

      • PUBLIC_KEY_ID:驗證者的公開金鑰 ID。
      • NOTE_URI:與驗證者相關聯的構件分析附註 URI。
    6. /tmp/attestation.json 中建立 JSON 檔案,說明認證:

      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. 建立認證:

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

您已建立認證。

確認認證已建立

如要確認是否已建立認證,可以列出與映像檔相關聯的認證。

gcloud

如要擷取認證清單,請輸入下列指令:

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

REST API

如要要求認證清單,請輸入下列指令:

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

如果認證數量眾多,回應可能會包含 nextPageToken 值。在這種情況下,您可以重複要求,並新增 pageToken 查詢參數,藉此擷取下一頁的結果,如下所示:

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}

NEXT_PAGE_TOKEN 替換為上一個要求回應中的 nextPageToken 值。

如果 nextPageToken 為空,表示沒有其他結果。

刪除認證

刪除認證前,請先完成下列事項:

  1. 瞭解刪除帳戶的影響。刪除驗證後,與驗證相關聯的容器映像檔最終會遭到封鎖,無法部署。

  2. 停止與您要刪除的認證相關聯的所有執行中容器。

  3. 刪除所有副本,包括 Artifact Registry 和 Artifact Analysis 存放區中的副本。

  4. 嘗試重新部署受影響的映像檔,確認映像檔確實遭到封鎖,無法部署。

如要刪除認證,請執行下列指令:

  1. 列出認證:

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

    認證包含事件 ID。輸出結果看起來與下列內容相似:

    projects/ATTESTOR_PROJECT_ID/occurrences/OCCURRENCE_ID
    
  2. 儲存發生次數 ID。

    儲存要刪除的認證發生 ID。

    OCCURRENCE_ID=OCCURRENCE_ID
    
  3. 刪除認證:

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

    再次列出認證,確認認證已刪除。

後續步驟