ソフトウェア セキュリティの未来を形作るために、2021 年の State of DevOps アンケートに参加して、あなたの声を聞かせてください。

REST API を使用した認証者の作成

このページでは、REST API を使用して Binary Authorization で認証者を作成する方法を説明します。ここで説明する手順は、コマンドラインgcloud コマンドまたは Google Cloud Console でも実行できます。このタスクは、Binary Authorization の設定の一部です。

概要

認証者は、Binary Authorization が証明書の検証で使用する GCP リソースです。証明書の詳細については、Binary Authorization の概要をご覧ください。

認証者を作成するには、次のことを行います。

  • Container Analysisメモを作成して、認証プロセスで使用される信頼できるメタデータを保存します。
  • 認証者の ID 確認に使用する PKIX 鍵ペアを設定します。Cloud Key Management Service(Cloud KMS)で生成された非対称鍵ペアは PKIX と互換性があります。PKIX 鍵の代わりに PGP 鍵ペアを使用することもできます。
  • Binary Authorization で認証者を作成し、作成したメモと公開鍵を関連付けます。

単一プロジェクト設定では、Binary Authorization ポリシーを構成した Google Cloud プロジェクトに認証者を作成します。マルチプロジェクト設定では、多くの場合、デプロイ担当者プロジェクトにポリシーを構成し、それとは別の認証者プロジェクトに認証者を保存します。

デフォルト プロジェクトを設定する

デフォルトの Google Cloud プロジェクトを設定します(まだ行っていない場合)。

PROJECT_ID=PROJECT_ID
gcloud config set project ${PROJECT_ID}

環境を設定する

プロジェクト名と番号を格納する環境変数を設定します。

DEPLOYER_PROJECT_ID=${PROJECT_ID}
DEPLOYER_PROJECT_NUMBER="$(
    gcloud projects describe "${DEPLOYER_PROJECT_ID}" \
      --format="value(projectNumber)"
)"
ATTESTOR_PROJECT_ID=${PROJECT_ID}
ATTESTOR_PROJECT_NUMBER="$(
    gcloud projects describe "${ATTESTOR_PROJECT_ID}" \
    --format="value(projectNumber)"
)"

証明書とデプロイ担当者のプロジェクトが同じプロジェクトの場合は、両方の変数に同じプロジェクト ID を使用します。

プロジェクトのサービス アカウント名も取得する必要があります。

DEPLOYER_SERVICE_ACCOUNT="service-${DEPLOYER_PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"
ATTESTOR_SERVICE_ACCOUNT="service-${ATTESTOR_PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"

Container Analysis メモを作成する

Binary Authorization は、Container Analysis を使用して、認証プロセスで使用される信頼できるメタデータを保存します。作成する認証者ごとに、1 つの Container Analysis メモを作成する必要があります。それぞれの証明書が、このメモのオカレンスとして保存されます。

Container Analysis メモを作成するには:

  1. メモ ID と人が読める形式の説明を保存する環境変数を設定します。

    NOTE_ID=NOTE_ID
    NOTE_URI="projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}"
    DESCRIPTION=DESCRIPTION
    

    ここで

    • NOTE_ID はメモの内部名です。スペースを含まない英数字で指定します(例: test-attestor-note)。
    • NOTE_URI は、メモリリソースの完全修飾パスです。
    • DESCRIPTION は、人が読める形式のメモ名です(例: Test Attestor Note)。
  2. テキスト エディタで、Container Analysis メモを記述する JSON ファイルを /tmp/note_payload.json に作成します。

    cat > /tmp/note_payload.json << EOM
    {
      "name": "${NOTE_URI}",
      "attestation": {
        "hint": {
          "human_readable_name": "${DESCRIPTION}"
        }
      }
    }
    EOM
    
  3. HTTP リクエストを Container Analysis REST API に送信して、メモを作成します。

    curl -X POST \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
        -H "x-goog-user-project: ${ATTESTOR_PROJECT_ID}" \
        --data-binary @/tmp/note_payload.json  \
        "https://containeranalysis.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/notes/?noteId=${NOTE_ID}"
    

メモが正常に作成されたことを確認するには:

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

メモに権限を設定する

また、作成した Container Analysis メモに権限を設定して、認証者プロジェクトのサービス アカウントにアクセスできるようにする必要があります。これを行うには、メモの IAM ポリシーを更新して、アカウントに containeranalysis.notes.occurrences.viewer ロールを割り当てます。

権限を設定するには:

  1. メモに IAM ポリシーを設定するために必要な情報を含む JSON ファイルを生成します。

    cat > /tmp/iam_request.json << EOM
    {
      'resource': '${NOTE_URI}',
      'policy': {
        'bindings': [
          {
            'role': 'roles/containeranalysis.notes.occurrences.viewer',
            'members': [
              'serviceAccount:${ATTESTOR_SERVICE_ACCOUNT}'
            ]
          }
        ]
      }
    }
    EOM
    
  2. 作成したメモのサービス アカウントとリクエストされたアクセス ロールを IAM ポリシーに追加します。

    curl -X POST  \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "x-goog-user-project: ${ATTESTOR_PROJECT_ID}" \
        --data-binary @/tmp/iam_request.json \
        "https://containeranalysis.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}:setIamPolicy"
    

暗号鍵を設定する

Binary Authorization では、PKIX 鍵を使用して、証明書を作成した署名者の ID を安全に確認できます。これにより、確認済みの当事者のみがコンテナ イメージを承認できるようになります。PKIX の代わりに PGP 鍵を使用することもできます。

PKIX 鍵ペアを作成する

Binary Authorization では、非対称 PKIX 鍵ペアを使用して証明書を検証できます。鍵ペアは、署名者がデジタル署名に使用する秘密鍵と、認証者に追加する公開鍵で構成されます。後で、Binary Authorization 施行者は認証者の公開鍵を使用して、証明書が署名者によって作成されたことを確認します。

このガイドでは、PKIX 鍵ペアの生成に推奨の楕円曲線デジタル署名アルゴリズム(ECDSA)を使用していますが、RSA 鍵または PGP 鍵で署名することもできます。署名アルゴリズムの詳細については、鍵の目的とアルゴリズムをご覧ください。

Cloud KMS で生成され、保存されている非対称鍵ペアは PKIX 形式に準拠しています。Binary Authorization で使用する Cloud KMS 鍵を作成する方法については、非対称鍵の作成をご覧ください。鍵を作成する場合は、鍵の目的として非対称署名を必ず選択してください。

新しいローカル非対称 PKIX 鍵ペアを生成してファイルに保存するには:

  1. 鍵を生成します。

    PRIVATE_KEY_FILE="/tmp/ec_private.pem"
    openssl ecparam -genkey -name prime256v1 -noout -out ${PRIVATE_KEY_FILE}
    
  2. このファイルには公開鍵と秘密鍵が含まれているため、認証者に追加するには公開鍵を別のファイルに抽出する必要があります。

    PUBLIC_KEY_FILE="/tmp/ec_public.pem"
    openssl ec -in ${PRIVATE_KEY_FILE} -pubout -out ${PUBLIC_KEY_FILE}
    

認証者を作成する

次に、関連付けられた Container Analysis メモを使用して、Binary Authorization で認証者を作成します。また、暗号公開鍵も追加する必要があります。

認証者を作成するには:

  1. Binary Authorization で定義されている認証者の名前を格納する環境変数を設定します。

    ATTESTOR_NAME=ATTESTOR_NAME
    

    ATTESTOR_NAME は、作成する認証者の名前です(例: build-secureprod-qa)。

  2. 認証者を作成し、公開セキュリティ キーを関連付けます。

    PKIX(ローカルキー)

    1. 認証者の作成に必要な情報を含む JSON ファイルを生成します。

      cat > /tmp/attestor.json << EOM
      {
         "userOwnedGrafeasNote": {
             "noteReference": "${NOTE_URI}",
             "publicKeys": {
                 "pkixPublicKey": {
                     "signatureAlgorithm": "ecdsa_p256_sha256",
                     "publicKeyPem": $( \
                         python < ${PUBLIC_KEY_FILE} \
                         -c 'import json, sys; print(json.dumps(sys.stdin.read()))' \
                     )
                 }
             }
         }
      }
      EOM
      
    2. 認証者を作成します。

      curl -X POST  \
         -H "Content-Type: application/json" \
         -H "Authorization: Bearer $(gcloud auth print-access-token)" \
         -H "X-Goog-User-Project: ${ATTESTOR_PROJECT_ID}" \
         --data-binary @/tmp/attestor.json \
      "https://binaryauthorization.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/attestors?attestorId=${ATTESTOR_NAME}"
      

    PKIX(Cloud KMS)

    1. Cloud KMS で管理される鍵ペアに関する情報を保存する環境変数を設定します。

      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_TYPE=KMS_KEY_TYPE
      KMS_CRYPTO_KEY_URI="projects/${KMS_KEY_PROJECT_ID}/locations/${KMS_KEY_LOCATION}/keyRings/${KMS_KEYRING_NAME}/cryptoKeys/${KMS_KEY_NAME}"
      KMS_CRYPTO_KEY_VERSION_URI="${KMS_CRYPTO_KEY_URI}/cryptoKeyVersions/${KMS_KEY_VERSION}"
      KMS_KEY_ID="//cloudkms.googleapis.com/v1/${KMS_CRYPTO_KEY_VERSION_URI}"
      

      ここで

      • KMS_KEY_PROJECT_ID は、鍵が格納されているプロジェクトの ID です。
      • KMS_KEY_LOCATION は鍵の場所です(例: global)。
      • KMS_KEYRING_NAME はキーリングの名前です。
      • KMS_KEY_NAME は鍵の名前です。
      • KMS_KEY_VERSION は鍵バージョンです。
      • KMS_KEY_TYPE は鍵の暗号化タイプです(例: ECDSA_P256_SHA256)。
    2. Cloud KMS から公開鍵ファイルをダウンロードし、ローカル システムの /tmp/kms_public_key.pem というファイルに保存します。

    3. 認証者の作成に必要な情報を含む JSON ファイルを生成します。

      cat > /tmp/attestor.json << EOM
      {
          "userOwnedDrydockNote": {
              "noteReference": "${NOTE_URI}",
              "publicKeys": {
                  "id": "${KMS_KEY_ID}",
                  "pkixPublicKey": {
                      "signatureAlgorithm": "${KMS_KEY_TYPE}",
                      "publicKeyPem": $( \
                          python < /tmp/kms_public_key.pem \
                          -c 'import json, sys; print(json.dumps(sys.stdin.read()))' \
                      )
                  }
              }
          }
      }
      EOM
      
    4. 認証者を作成します。

      curl -X POST  \
          -H "Content-Type: application/json" \
          -H "Authorization: Bearer $(gcloud auth print-access-token)" \
          -H "X-Goog-User-Project: ${ATTESTOR_PROJECT_ID}" \
          --data-binary @/tmp/attestor.json \
      "https://binaryauthorization.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/attestors?attestorId=${ATTESTOR_NAME}"
      
  3. デプロイ担当者プロジェクトの IAM ロール バインディングを認証者に追加します。これは、Binary Authorization でポリシーを評価する際に、プロジェクトがその認証者にアクセスする権限を持っているかどうかを判定するために使用されます。

    認証者に IAM ポリシーを設定するために必要な情報を含む JSON ファイルを生成します。

    cat > /tmp/iam_request.json << EOM
    {
      'resource': 'projects/${ATTESTOR_PROJECT_ID}/attestors/${ATTESTOR_NAME}',
      'policy': {
        'bindings': [
          {
            'role': 'roles/binaryauthorization.attestorsVerifier',
            'members': [
              'serviceAccount:${DEPLOYER_SERVICE_ACCOUNT}'
            ]
          }
        ]
      }
    }
    EOM
    

    作成したメモのサービス アカウントとリクエストされたアクセス ロールを IAM ポリシーに追加します。

    curl -X POST  \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "x-goog-user-project: ${ATTESTOR_PROJECT_ID}" \
        --data-binary @/tmp/iam_request.json \
        "https://binaryauthorization.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/attestors/${ATTESTOR_NAME}:setIamPolicy"
    

認証者が作成されたことを確認する

認証者が作成されたことを確認するには:

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

次のステップ