証明書を作成する

このページでは、Binary Authorization 証明書の作成手順について説明します。

1 つの証明書で、異なる場所または異なるレジストリ(Artifact RegistryContainer Registry、外部コンテナ レジストリなど)に保存されている同一のイメージを承認できます。

デプロイ時に、Binary Authorization は証明書を使用して証明書を検証します。

Binary Authorization と Google Kubernetes Engine(GKE)を使用した証明書ベースの適用について詳しく説明しているチュートリアルがあります。コマンドライン ツールの使用を開始するまたは Google Cloud Console の使用を開始するをご覧ください。

他のすべてのプラットフォームの詳細な手順については、プラットフォームのセットアップを参照して、プラットフォームを選択してください。

始める前に

証明書の概要には、証明書の作成前に完了する必要がある手順が記載されています。

環境を設定する

  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 のロールを付与する

証明書を作成するには、認証者を作成する ID に次の Identity and Access Management(IAM)ロールを付与する必要があります。

  • 認証者に関連付けられているメモリソースに対する roles/containeranalysis.notes.attacher
  • 証明書プロジェクト リソースに対する roles/containeranalysis.occurrences.editor

証明書に基づいて証明書を作成します。認証者は Container Analysis メモに関連付けられています。証明書を作成すると、Container Analysis のオカレンスが作成され、メモに添付されます。

詳しくは、アクセス権の付与をご覧ください。

Cloud Build パイプラインで証明書を作成する方法については、Kritis Signer を使用して証明書を作成するをご覧ください。

証明書を作成する

ローカルに保存された鍵を使用して証明書を作成する

ローカルの鍵で署名された証明書を作成する手順は次のとおりです。

  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 ダイジェストを使用します。sha256sha384、または sha512 を使用できます。

      この例では、出力は次のようになります。

      {
        "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: 認証者に関連付けられている Container Analysis メモの 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 リポジトリと Container 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}
    

    証明書を再度一覧表示して、証明書が削除されたことを確認します。

次のステップ