증명 만들기

이 페이지에서는 명령줄에서 Binary Authorization에 증명을 만드는 방법을 설명합니다.

이 페이지의 안내에서는 배포를 위해 컨테이너 이미지를 승인하기 위해 서명자가 수행해야 하는 단계를 설명합니다. 실제 시나리오에서는 이러한 단계를 명령줄에서 직접 입력하는 대신 머신 프로세스 또는 실제 사용자가 트리거할 수 있는 스크립트나 자동화에 통합하세요.

개요

증명서명자가 만든 디지털 서명 문서로, 파이프라인의 필수 프로세스가 완료되었고 결과 컨테이너 이미지가 GKE에서 배포를 위해 승인되었음을 인증합니다. 증명 자체에는 컨테이너 이미지 레지스트리에 저장된 컨테이너 이미지 버전의 전체 경로와 특정 컨테이너 이미지 빌드를 식별하는 전역 고유 다이제스트에 서명하여 만든 서명이 포함됩니다.

PKIX(권장) 또는 PGP 서명을 사용하여 증명을 만들 수 있습니다. 이 가이드에서는 암호화 키에 공개 키 인프라(X.509)(PKIX) 형식을 사용하고 서명하고 증명을 만드는 데 권장 타원 곡선 디지털 서명 알고리즘(ECDSA)을 사용합니다. 서명에 RSA 또는 PGP 키를 사용할 수도 있습니다. 서명 알고리즘에 대한 자세한 내용은 키 용도 및 알고리즘을 참조하세요.

기본 프로젝트 설정

기본 Google Cloud 프로젝트를 아직 설정하지 않은 경우 다음을 입력하세요.

PROJECT_ID=PROJECT_ID
gcloud config set project ${PROJECT_ID}

여기서 PROJECT_ID는 프로젝트 이름입니다.

환경 설정

  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
    PUBLIC_KEY_ID=PUBLIC_KEY_ID
    PRIVATE_KEY_FILE=PRIVATE_KEY_FILE
    IMAGE_TO_ATTEST="${IMAGE_PATH}@${IMAGE_DIGEST}"
    

    각 항목의 의미는 다음과 같습니다.

    • ATTESTOR_NAME은 증명자의 이름입니다(예: build-secure 또는 prod-qa).
    • IMAGE_PATH는 Container Registry에서 배포하려는 이미지의 경로입니다(예: gcr.io/example-project/quickstart-image).
    • PUBLIC_KEY_ID는 생성한 키 쌍의 공개 키와 연결된 ID입니다. 공개 키 자체는 증명자에 저장됩니다.
    • PRIVATE_KEY_FILE은 생성한 키 쌍의 비공개 키를 포함하는 파일입니다. 증명 페이로드는 이 키로 서명됩니다.
    • IMAGE_DIGEST는 이미지 매니페스트의 SHA-256 다이제스트입니다(예: sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea882eb722c3be4). 이미지 다이제스트 가져오기에 대한 자세한 내용은 Container Registry에서 이미지 버전 나열을 참조하세요.

Container Registry 또는 다른 레지스트리에 저장된 각 컨테이너 이미지에는 해당 위치에 대한 고유한 경로와 해당 버전을 고유하게 식별하는 SHA-256 다이제스트가 있습니다. 증명은 이미지의 특정 버전을 승인할 수 있는 전체 이미지 경로 및 다이제스트를 참조합니다.

다음은 전체 레지스트리 경로의 예시입니다.

gcr.io/example-project/quickstart-image@sha256:bedb3feb23e81d162e33976fd7b245adff00379f4755c0213e84405e5b1e0988

로컬에 저장된 키를 사용하여 PKIX 서명으로 증명 만들기

PKIX 공개 키로 서명된 증명의 경우 다음을 수행하세요.

  1. 레지스트리 경로를 참조하는 Binary Authorization으로 전송할 증명 페이로드 만들기
  2. 페이로드에 서명하고 PKIX 서명 파일 생성
  3. 공개 키 ID 가져오기
  4. 서명 파일과 공개 키 ID로 증명 만들기

증명 페이로드 만들기

증명 페이로드는 컨테이너 이미지의 위치를 참조하는 JSON 형식의 파일입니다.

페이로드 파일을 만들려면 다음을 수행하세요.

gcloud

다음을 입력합니다.

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

페이로드 파일은 다음과 유사합니다.

{
  "critical": {
    "identity": {
      "docker-reference": "gcr.io/google-samples/hello-app"
    },
    "image": {
      "docker-manifest-digest": "sha256:bedb3feb23e81d162e33976fd7b245
adff00379f4755c0213e84405e5b1e0988"
    },
    "type": "Google cloud binauthz container signature"
  }
}

REST

위에서 설정한 환경 변수를 사용하여 /tmp/generated_payload.json이라는 페이로드 파일을 만듭니다.

cat > /tmp/generated_payload.json << EOM
{
  "critical": {
    "identity": {
      "docker-reference": "${IMAGE_PATH}"
    },
    "image": {
      "${IMAGE_DIGEST}"
    },
    "type": "Google cloud binauthz container signature"
  }
}
EOM

페이로드에 서명하고 서명 파일 생성

페이로드 파일을 만든 후에는 앞에서 생성한 키 쌍의 비공개 암호화 키를 사용하여 서명해야 합니다. 해당 공개 키가 연결된 증명자에 저장되었다는 점을 떠올려 보세요. 해당 증명자의 공개 키는 배포 시 이 서명을 확인하는 데 사용됩니다.

증명자를 만드는 방법을 검토하려면 CLI를 사용하여 증명자 만들기 또는 Console을 사용하여 증명자 만들기를 참조하세요.

이러한 단계를 모두 포함하는 엔드 투 엔드 예시를 보려면 CLI를 사용하여 시작하기 또는 Console을 사용하여 시작하기를 참조하세요.

페이로드 파일에 서명하려면 다음을 수행하세요.

  1. 로컬 PKIX 비공개 키로 페이로드에 서명하고 서명 파일을 출력합니다.

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

    서명 파일은 위에서 만든 페이로드 JSON 파일의 디지털 서명 버전입니다.

공개 키 ID 가져오기

증명을 만들 때 공개 키 ID를 서명 파일과 함께 Binary Authorization에 전송해야 합니다.

공개 키 ID를 가져오려면 다음을 수행하세요.

  1. 공개 키 ID를 저장합니다.

    이후에 증명자의 공개 키 ID를 보려면 gcloud container binauthz attestors describe ${ATTESTOR_NAME}을 사용합니다.

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

증명 만들기

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

또는 증명을 만들고 제공된 증명자가 해당 증명을 확인할 수 있음을 검증하려면 다음을 실행하세요.

gcloud alpha 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

참고: 키 ID는 문자열일 수 있습니다.

REST

증명을 만들려면 다음을 수행하세요.

  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"
    }
    
  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": "KEY_ID",
             "signature": "$(base64 --wrap=0 /tmp/ec_signature)"
             }
         ]
      }
     }
    EOM
    

    여기서 KEY_ID는 이전 단계에서 반환된 공개 키 ID입니다.

  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 Key Management Service 기반 PKIX 서명으로 증명 만들기

Cloud Key Management Service 기반 PKIX 서명으로 증명을 만들려면 다음을 수행하세요.

  1. 환경 변수를 설정하여 PKIX 키 쌍에 대한 정보와 함께 증명, 증명자, Cloud Key Management Service 키가 저장된 프로젝트에 대한 정보를 저장합니다.

    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

    1. 위에서 설정한 환경 변수를 사용하여 /tmp/generated_payload.json이라는 페이로드 파일을 만듭니다.

      cat > /tmp/generated_payload.json << EOM
      {
        "critical": {
          "identity": {
            "docker-reference": "${IMAGE_PATH}"
          },
          "image": {
            "${IMAGE_DIGEST}"
          },
          "type": "Google cloud binauthz container signature"
        }
      }
      EOM
      
    2. 페이로드 파일에 서명합니다.

      gcloud --project="${KMS_KEY_PROJECT_ID}"  \
          alpha kms asymmetric-sign \
          --location="${KMS_KEY_LOCATION}" \
          --keyring="${KMS_KEYRING_NAME}" \
          --key="${KMS_KEY_NAME}" \
          --version="${KMS_KEY_VERSION}" \
          --digest-algorithm="DIGEST_ALGORITHM" \
          --input-file=/tmp/generated_payload.json \
          --signature-file=/tmp/generated_payload.json.sig
      

      여기서 DIGEST_ALGORITHMsha256, sha384, sha512 중 하나입니다. 이는 서명에 사용하는 키 버전의 다이제스트 알고리즘입니다.

      이 명령어는 디지털 서명이 포함된 /tmp/generated_payload.json.sig라는 파일을 출력합니다.

    3. 사용자를 대신하여 증명에 서명하는 증명자를 검색하고 저장된 공개 키 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"
      }
      
    4. 텍스트 편집기에서 /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": "KEY_ID",
                   "signature": "$(base64 --wrap=0 /tmp/generated_payload.json.sig)"
               }
           ]
        }
      
      }
      EOM
      

      여기서 KEY_ID는 이전 단계에서 반환된 공개 키 ID입니다.

    5. 증명을 만듭니다.

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

REST

증명 목록을 가져옵니다.

curl -X GET \
    -H "Content-Type: application/json" \
    -H "X-Goog-User-Project: ${ATTESTATION_PROJECT_ID}" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://containeranalysis.googleapis.com/v1/projects/${ATTESTATION_PROJECT_ID}/occurrences?filter=kind%3D%22ATTESTATION%22"

증명이 여러 개 있는 경우 nextPageToken이 응답에서 반환될 수 있습니다. 이 경우 요청을 반복해야 하지만 pageToken 쿼리 매개변수를 이 nextPageToken 값으로 설정하여 더 많은 증명을 가져와야 합니다. nextPageToken이 비어 있으면 더 이상 결과가 없음을 나타냅니다.

curl -X GET \
    -H "Content-Type: application/json" \
    -H "X-Goog-User-Project: ${ATTESTATION_PROJECT_ID}" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://containeranalysis.googleapis.com/v1/projects/${ATTESTATION_PROJECT_ID}/occurrences/?filter=kind%3D%22ATTESTATION%22&pageToken=${NEXT_PAGE_TOKEN}"

다음 단계