Kritis Signer で証明書を作成する

このチュートリアルでは、Binary Authorization 証明書を作成する前に、Kritis Signer をビルドし、コンテナ イメージの脆弱性をチェックする方法を説明します。

概要

Kritis Signer はオープンソースのコマンドライン ツールで、構成したポリシーに基づいて Binary Authorization 証明書を作成できます。Artifact Analysis により特定されたイメージに脆弱性がないか確認してから、Kritis Signer を使用して証明書を作成することもできます。

さらに、Cloud Build では、ビルド パイプラインのカスタム ビルダーとして Kritis Signer を実行できます。

このチュートリアルでは、Kritis Signer カスタム ビルダーの 1 回限りのビルドを実行し、サンプルのビルド パイプラインを実行します。各サンプル パイプラインには、次のビルドステップが含まれます。

  1. サンプル コンテナ イメージを作成します。
  2. イメージを Container Registry に push します。
  3. イメージを確認して署名します。ポリシーに基づいて、Kritis Signer を使用して証明書を作成します。

各パイプラインの確認と署名のビルドステップで、Kritis Signer は次の処理を行います。

  1. Artifact Analysis を使用して、新しくビルドされたイメージをスキャンし、脆弱性のリストを取得します。
  2. ポリシーの脆弱性署名ルールと脆弱性のリストを比較して、次の処理を行います。
    1. 特定された脆弱性すべてが脆弱性署名ルールを満たしている場合、Kritis Signer が証明書を作成します。
    2. 特定した脆弱性のいずれかが脆弱性署名ルールに違反している場合、Kritis Signer は証明書を作成しません。

デプロイ時に、Binary Authorization 適用者が検証可能な証明書を確認します。検証可能な証明書がない場合、適用者はイメージのデプロイを拒否します。

このチュートリアルでは、Cloud Build パイプラインで Kritis Signer をチェック専用モードで実行する方法についても説明します。このモードでは、Kritis Signer は証明書を作成しません。脆弱性の結果がポリシーの脆弱性署名ルールを満たすかどうかの確認のみを行います。ルールを満たしている場合、Kritis Signer のビルドステップは成功し、パイプラインが引き続き実行されます。違反している場合は、ステップが失敗し、パイプラインが終了します。

目標

このチュートリアルでは、次のことを行います。

  1. Cloud Build カスタム ビルダーとして Kritis Signer を設定します。
  2. 脆弱性署名ルールを含むポリシーを確認します。
  3. Kritis Signer を実行して、脆弱性スキャンの結果に基づいて証明書を作成します。
  4. チェック専用モードで Kritis Signer を実行します。

費用

このチュートリアルでは、次の Google Cloud プロダクトを使用します。

  • Container Registry
  • Artifact Analysis
  • Cloud Build
  • Cloud Key Management Service

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。

始める前に

このセクションでは、システムを 1 回だけ設定します。

環境を設定する

  1. Google Cloud プロジェクトを環境変数に記録します。

    export PROJECT_ID=PROJECT_ID
    

    PROJECT_ID は、Google Cloud プロジェクトに置き換えます。

  2. デフォルトのプロジェクト ID を Google Cloud プロジェクトに設定します。

    gcloud config set project $PROJECT_ID
    
  3. 以降の手順で使用するため、プロジェクト番号を環境変数に記録します。

    export PROJECT_NUMBER=$(gcloud projects list --filter="${PROJECT_ID}" \
     --format="value(PROJECT_NUMBER)")
    
  4. API を有効にします。

    このガイドに必要なサービスを有効にするには、次のコマンドを実行します。

    gcloud services enable \
      cloudbuild.googleapis.com \
      containerregistry.googleapis.com \
      containerscanning.googleapis.com \
      cloudkms.googleapis.com
    

IAM ロールを設定する

以下のコマンドを実行して、次のロールを Cloud Build サービス アカウントに構成します。

  • containeranalysis.notes.editor: 認証者を管理するために、Artifact Analysis メモの編集者のロールを追加します。
  • containeranalysis.notes.occurrences.viewer: 脆弱性と証明書の両方のオカレンスを管理するために、メモに対する Artifact Analysis のオカレンスの閲覧者のロールを追加します。
  • roles/containeranalysis.occurrences.editor: Artifact Analysis で証明書のオカレンスを作成するために、Artifact Analysis のオカレンスの編集者のロールを追加します。
  • cloudkms.signer: サービス アカウントが Cloud KMS 署名サービスにアクセスできるように、Cloud KMS CryptoKey 署名者のロールを追加します。

    gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com --role roles/containeranalysis.notes.editor
    gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com --role roles/containeranalysis.notes.occurrences.viewer
    gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com --role roles/containeranalysis.occurrences.editor
    gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com --role roles/cloudkms.signer
    

Kritis Signer カスタム ビルダーを設定する

このセクションでは、Kritis Signer カスタム ビルダーの 1 回限りの設定を行います。Kritis Signer を取得、ビルド、push したら、任意の Cloud Build パイプラインで使用できます。

このセクションでは、次の方法について説明します。

  • Kritis リポジトリのクローンを作成します。
  • Kritis Signer の Cloud Build カスタム ビルダーをビルドします。
  • Cloud Build ビルドステップとして使用できるように Kritis Signer を Container Registry に push します。

次のコマンドを実行して、このガイドで使用されているコードと構成ファイルを取得します。

  1. Kritis リポジトリのクローンを作成します。

    git clone https://github.com/grafeas/kritis.git
    

    このリポジトリには次のものが含まれます。

    • Kritis Signer が含まれている Kritis のソースコード。
    • Cloud Build が Kritis Signer カスタム ビルダーをビルドするために使用する Cloud Build 構成ファイル
    • 脆弱性署名ルールを含むサンプル ポリシー。
    • Cloud Build 構成ファイルの例。各構成ファイルは、脆弱性スキャン パイプラインで Kritis Signer を使用します。
  2. kritis/ ディレクトリに移動します。

    cd kritis
    
  3. Kritis Signer カスタム ビルダーをビルドして登録します。

    この 1 回限りの設定手順で Kritis Signer カスタム ビルダーをビルドして、Cloud Build に登録します。登録すると、カスタム ビルダーを任意の Cloud Build パイプラインで使用できるようになります。

    gcloud builds submit . --config deploy/kritis-signer/cloudbuild.yaml
    

既存のポリシーを表示する

このセクションでは、Kritis Signer ポリシーの例を示します。

このポリシーでは、脆弱性がないかイメージをスキャンするように Artifact Analysis にリクエストするように Kritis Signer を構成します。スキャンが完了すると、Kritis Signer は、返された脆弱性の結果をポリシーの脆弱性署名ルールと比較します。

このポリシーの脆弱性署名ルールを編集して、以下に基づいて証明書を作成できます。

  • 特定された脆弱性の重大度。
  • 特定の脆弱性。

証明書を無条件に作成する(ALLOW_ALL)か、作成しない(BLOCK_ALL)かをポリシーを設定することもできます。

Kritis Signer ポリシーを表示するには、次のコマンドを実行します。

cat samples/signer/policy-strict.yaml

このポリシーは次のようになります。

apiVersion: kritis.grafeas.io/v1beta1
kind: VulnzSigningPolicy
metadata:
  name: my-vsp
spec:
  imageVulnerabilityRequirements:
    maximumFixableSeverity: MEDIUM
    maximumUnfixableSeverity: MEDIUM
    allowlistCVEs:
    - projects/goog-vulnz/notes/CVE-2021-20305

ここで

  • maximumUnfixableSeveritymaximumFixableSeverity は、Kritis Signer が証明書を作成する共通脆弱性識別子(CVE)の重大度しきい値を定義します。maximumUnfixableSeverity は、修正が現在利用できない場合の重大度のしきい値を定義します。maximumFixableSeverity は、修正が現在利用できる場合の重大度のしきい値を定義します。maximumUnfixableSeveritymaximumFixableSeverity は、次のいずれかの重大度に設定できます。

    • CRITICAL
    • HIGH
    • MEDIUM
    • LOW

    重大度の詳細については、重大度をご覧ください。

    maximumUnfixableSeveritymaximumFixableSeverity を次のように設定することもできます。

    • BLOCK_ALL: 脆弱性が見つかった場合に証明書は作成されません。
    • ALLOW_ALL: 証明書は常に作成されます。
  • allowlistCVEs は、許可リストに登録する特定の CVE のリストです。Kritis Signer は、証明書を作成するかどうかを評価するときに、このリストにある CVE を無視します。許可リストの各エントリは、CVE の Artifact Analysis ノート名と完全に一致する必要があります。Artifact Analysis の脆弱性ソースについて詳細を確認してください。メモの詳細については、メタデータ ストレージをご覧ください。

Cloud KMS 署名鍵を作成する

Cloud Key Management Service 鍵は証明書の作成に使用されます。

  1. KEY_RING という名前の新しい Cloud KMS キーリングを作成します。

    gcloud kms keyrings create KEY_RING \
       --location global
    
  2. キーリング内に KEY_NAME という新しい Cloud KMS 鍵を作成します。

    gcloud kms keys create KEY_NAME \
        --keyring KEY_RING \
        --location global \
        --purpose "asymmetric-signing" \
        --default-algorithm "rsa-sign-pkcs1-2048-sha256"
    
  3. 以降の手順のために、ダイジェスト アルゴリズムと Cloud KMS を環境変数に格納します。

    export KMS_DIGEST_ALG=SHA256
    export KMS_KEY_NAME=projects/$PROJECT_ID/locations/global/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/1
    

メモ名を定義する

すべての証明書は、Artifact Analysis のメモを参照します。Kritis Signer は、指定した名前のメモを自動的に作成します。既存のメモ名を再利用することもできます。

export NOTE_ID=my-signer-note
export NOTE_NAME=projects/${PROJECT_ID}/notes/${NOTE_ID}

Cloud Build パイプラインで Kritis Signer を使用して証明書を作成する

このセクションでは、Kritis Signer カスタム クラウド ビルダーを使用して、脆弱性スキャンの結果に基づいて Binary Authorization 証明書を作成する方法を説明します。

以下では、Kritis Signer リポジトリのサンプルビルド構成ファイルを使用して Kritis Signer がどのように機能するかを説明します。各サンプル構成ファイルには、次のビルドステップが含まれています。

  1. docker build ステップ。Docker コンテナ イメージをビルドします。
  2. docker push ステップ。新しくビルドされたコンテナ イメージを Container Registry に push します。
  3. vulnsign ステップ。次のように、コンテナ イメージを確認して署名します。

    1. Artifact Analysis が新しくビルドされたコンテナ イメージの脆弱性の検出結果を返すまで待機します。
    2. 検出結果をポリシーの脆弱性署名ルールと比較します。
    3. 調査結果が脆弱性ルールを満たしている場合、証明書を作成します。

各サンプルビルドを Cloud Build に送信します。各ビルドで脆弱性の結果が生成されます。

  • 失敗例: 脆弱性の結果が脆弱性署名ルールに違反しています。このビルドは失敗し、証明書は作成されません。
  • 成功例: 脆弱性の結果が脆弱性署名ルールを満たしています。ビルドに成功し、証明書が作成されます。

失敗例のサンプルビルドを送信する

このセクションでは、コンテナ イメージをビルドして脆弱性をスキャンします。コンテナ イメージが Debian 10 の特定のスナップショットに基づいているため、このビルドは失敗します。スナップショットには、重大度 HIGH の脆弱性が複数含まれています。これらの脆弱性は脆弱性署名ルールに違反しています。このため、ビルダーは証明書を生成しません。

  1. (省略可)失敗例の脆弱性署名ポリシー ファイルを表示します。

    cat samples/signer/policy-strict.yaml
    
  2. ビルドを送信します。

    gcloud builds submit \
      --substitutions=_KMS_KEY_NAME=$KMS_KEY_NAME,_KMS_DIGEST_ALG=$KMS_DIGEST_ALG,_NOTE_NAME=$NOTE_NAME \
      --config=samples/signer/cloudbuild-bad.yaml samples/signer
    

    次のような出力が表示されます。

    "ERROR: (gcloud.builds.submit) build BUILD_ID completed with status "FAILURE"
    
  3. 最後のビルドのビルド ID を保存します。

    export BUILD_ID=$(gcloud builds list --limit=1 --format="value('ID')")
    
  4. 結果を確認します。

     gcloud storage cat gs://${PROJECT_NUMBER}.cloudbuild-logs.googleusercontent.com/log-${BUILD_ID}.txt | grep "does not pass VulnzSigningPolicy"
    

成功例のサンプルビルドを送信する

このセクションでは、脆弱性署名ルールに違反しない脆弱性のあるコンテナ イメージを作成します。この場合、Kritis Signer カスタム ビルダーは証明書を作成します。

成功例のビルドを Cloud Build に送信する手順は次のとおりです。

  1. (省略可)成功例の脆弱性署名ポリシー ファイルを表示します。

    cat samples/signer/policy-loose.yaml
    
  2. ビルドを送信します。

    gcloud builds submit \
      --substitutions=_KMS_KEY_NAME=$KMS_KEY_NAME,_KMS_DIGEST_ALG=$KMS_DIGEST_ALG,_NOTE_NAME=$NOTE_NAME \
      --config=samples/signer/cloudbuild-good.yaml samples/signer
    
  3. 最後のビルドのビルド ID を保存します。

    export BUILD_ID=$(gcloud builds list --limit=1 --format="value('ID')")
    
  4. 結果を確認します。

    gcloud builds describe $BUILD_ID | grep status
    

チェック専用モードで Kritis Signer を使用する

このセクションでは、check-only モードで Kritis Signer を使用する方法を説明します。このモードでは、Kritis Signer は証明書を作成しません。脆弱性署名ルールに基づいてビルドステップが成功または失敗するまでは、イメージの脆弱性のみがチェックされます。

失敗例のサンプルビルドを送信する

  1. (省略可)失敗例の脆弱性署名ポリシー ファイルを表示します。

    cat samples/policy-check/policy-strict.yaml
    

    Kritis Signer のビルドステップでは、mode フラグが check-only に設定されています。

  2. ビルドを送信します。

    gcloud builds submit \
      --config=samples/policy-check/cloudbuild-bad.yaml samples/policy-check
    

    ビルドが失敗します。

  3. 最後のビルドのビルド ID を保存します。

    export BUILD_ID=$(gcloud builds list --limit=1 --format="value('ID')")
    
  4. 結果を確認します。

     gcloud storage cat gs://${PROJECT_NUMBER}.cloudbuild-logs.googleusercontent.com/log-${BUILD_ID}.txt | grep "does not pass VulnzSigningPolicy"
    

成功例のサンプルビルドを送信する

  1. (省略可)成功例の脆弱性署名ポリシー ファイルを表示します。

    cat samples/policy-check/policy-loose.yaml
    
  2. ビルドを送信します。

    gcloud builds submit \
     --config=samples/policy-check/cloudbuild-good.yaml samples/policy-check
    
  3. 最後のビルドのビルド ID を保存します。

    export BUILD_ID=$(gcloud builds list --limit=1 --format="value('ID')")
    
  4. 結果を確認します。

    gcloud builds describe $BUILD_ID | grep status
    

認証者を作成する

このガイドで説明する方法で作成した証明書を必要とするポリシーを作成するには、まず認証者を作成する必要があります。

認証者の作成手順は次のとおりです。

  1. このガイドの前半で作成した Cloud KMS 鍵から公開鍵マテリアルを取得します。

    gcloud kms keys versions get-public-key 1 \
    --key KEY_NAME \
    --keyring KEY_RING \
    --location global \
    --output-file OUTPUT_PATH
    
    • KEY_NAME: 鍵名
    • KEY_RING: キーリング名
    • OUTPUT_PATH: ファイルパス(例: my-key.pem
  2. ファイル内の公開鍵マテリアルとこのガイドの前半で作成したメモを使用して、認証者を作成します。認証者を作成するには、Google Cloud コンソールまたは gcloud CLI を使用します。

  3. 証明書を必要とするポリシーを作成し、このセクションで作成した認証者を指定します。ポリシーは、Google Cloud コンソールまたは gcloud CLI を使用して作成できます。

証明書を作成する

認証者を使用して証明書を作成するには、Cloud KMS を使用して証明書を作成するをご覧ください。

クリーンアップ

このドキュメントで使用されたリソースをクリーンアップするには、プロジェクトを削除します。

gcloud projects delete ${PROJECT_ID}

次のステップ