서명된 출처 및 Binary Authorization 사용

이 페이지에서는 Cloud Build로 빌드 출처 메타데이터를 보고 배포를 제어할 수 있는 방법을 설명합니다.

빌드 출처는 Cloud Build에서 실행되는 빌드에 대해 검증 가능한 데이터 모음입니다. 출처 메타데이터에는 빌드된 이미지의 다이제스트, 입력 소스 위치, 빌드 인수, 빌드 기간과 같은 세부정보가 포함됩니다.

소프트웨어 공급망을 보호할 수 있도록 Cloud Build는 출처 메타데이터를 기록하고 빌드 시 컨테이너 이미지에 대한 증명을 만듭니다. 감사 목적으로 증명 메타데이터를 사용하고 증명을 사용하여 Binary Authorization으로 배포를 제어할 수 있습니다.

제한사항

Cloud Build는 동일한 프로젝트에 모든 Binary Authorization 및 컨테이너 분석 리소스를 생성합니다. 다른 프로젝트에서 배포 플랫폼을 실행하는 경우 Binary Authorization을 구성할 때는 built-by-cloud-build 증명자를 추가할 때 Cloud Build 프로젝트를 참조해야 합니다.

시작하기 전에

  • 생성된 빌드 출처 메타데이터를 보려면 다음 안내를 따르세요.

    Cloud Build, Container Analysis, and Artifact Registry API를 사용 설정합니다.

    API 사용 설정

  • Binary Authorization으로 배포를 제어하고 증명자 메타데이터를 보려면 다음 안내를 따르세요.

    1. Cloud Build, Binary Authorization, and Artifact Registry API를 사용 설정합니다.

      API 사용 설정

    2. 플랫폼에 Binary Authorization을 설정합니다.

빌드 출처 보기

이 섹션에서는 Cloud Build에서 만든 빌드 출처 메타데이터를 보는 방법을 설명합니다.

Cloud Build로 이미지를 빌드할 때 이미지의 빌드 출처는 자동으로 기록됩니다. 나중에 감사 목적으로 이 정보를 가져올 수 있습니다. 출처 메타데이터를 생성하려면 Cloud Build로 빌드를 실행합니다.

출처 메타데이터를 보려면 다음 명령어를 실행합니다.

gcloud artifacts docker images describe \
LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH \
--show-provenance

명령어의 자리 표시자 값을 다음으로 바꿉니다.

  • LOCATION: 리전 또는 멀티 리전 위치입니다.
  • PROJECT_ID: Google Cloud 프로젝트 ID입니다.
  • REPOSITORY: 저장소 이름입니다.
  • IMAGE: 이미지 이름입니다.
  • HASH: 이미지의 sha256 해시 값입니다. 빌드 출력에서 확인할 수 있습니다.

출력은 SLSA 출처 사양에 설명된 컨테이너 컨테이너입니다. 예를 들면 다음과 같습니다.

image_summary:
  digest: sha256:991ff3a4548c72e671070be2e86ff684fd0924f6b75ee60d25d85c8cdfde1293
  fully_qualified_digest: us-east1-docker.pkg.dev/PROJECT_ID/my-repo/my-image@sha256:991ff3a4548c72e671070be2e86ff684fd0924f6b75ee60d25d85c8cdfde1293
  registry: us-east1-docker.pkg.dev
  repository: my-repo
provenance_summary:
  provenance:
  - createTime: '2021-09-24T16:20:36.854156Z'
    dsseAttestation:
      envelope:
        payload: eyJfdHlwZS...
        payloadType: application/vnd.in-toto+json
        signatures:
        - keyid: projects/verified-builder/locations/global/keyRings/attestor/cryptoKeys/builtByGCB/cryptoKeyVersions/1
          sig: MEQCIHusA75t6LoyCngZ1_ACc-wWOlTThW6VKCyz75bnmSU0AiBYV50eFWQlDlp2cF-OV1u6j1_CtmrFdCNJCdyB6pYFsw==
      statement:
        predicateType: https://slsa.dev/provenance/v0.1
        provenance:
          builderConfig:
            id: https://cloudbuild.googleapis.com/Worker@v336731714
          metadata:
            buildFinishedOn: '2021-09-24T16:20:35.828284Z'
            buildInvocationId: c2f645df-f705-4aab-8d8f-ba2b1260f8ab
            buildStartedOn: '2021-09-24T16:20:23.224165401Z'
          recipe:
            arguments:
            - '@type': type.googleapis.com/google.devtools.cloudbuild.v1.BuildStep
              args:
              - build
              - --network
              - cloudbuild
              - --no-cache
              - -t
              - us-east1-docker.pkg.dev/PROJECT_ID/my-repo/my-image:tag1
              ....

메타데이터가 조작되지 않았는지 확인하려면 다음 단계를 수행하여 출처 유효성을 검사할 수 있습니다.

  1. 새 디렉터리를 만든 후 해당 디렉터리로 이동합니다.

    mkdir provenance && cd provenance
    
  2. keyid 필드의 정보를 사용하여 공개 키를 가져옵니다.

    gcloud kms keys versions get-public-key 1 --location global --keyring attestor \
    --key builtByGCB --project verified-builder --output-file my-key.pub
    
  3. payload에는 base64url로 인코딩된 출처의 JSON 표현이 포함됩니다. 데이터를 디코딩하여 파일에 저장합니다.

    gcloud artifacts docker images describe \
    LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH --show-provenance \
    --format=json | jq -r '.provenance_summary.provenance[0].dsseAttestation.envelope.payload' | tr '\-_' '+/' | base64 -d > provenance.json
    
  4. 봉투에는 출처에 대한 서명도 포함됩니다. 데이터를 디코딩하여 파일에 저장합니다.

    gcloud artifacts docker images describe LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH --show-provenance \
    --format=json | jq -r '.provenance_summary.provenance[0].dsseAttestation.envelope.signatures[0].sig' | tr '\-_' '+/' | base64 -d > signature.bin
    
  5. 서명 유효성을 검사합니다.

    openssl dgst -sha256 -verify my-key.pub -signature signature.bin provenance.json
    

    유효성 검사에 성공하면 출력은 Verified OK입니다.

이미지에 출처 메타데이터를 연결하도록 요구

Cloud Build가 출처 메타데이터를 생성하지 않더라도 빌드는 완료된 것입니다. Cloud Build가 이미지의 출처 메타데이터를 생성하지 않는 경우 기본 동작을 덮어쓰고 빌드에 실패하려면 cloudbild.yaml 파일에 requestedVerifyOption: VERIFIED 옵션을 추가하세요.

steps:
- name: 'gcr.io/cloud-builders/docker'
  args: [ 'build', '-t', 'us-central1-docker.pkg.dev/$PROJECT_ID/quickstart-docker-repo/quickstart-image:tag1', '.' ]
images:
- 'us-central1-docker.pkg.dev/$PROJECT_ID/quickstart-docker-repo/quickstart-image:tag1'
options:
  requestedVerifyOption: VERIFIED

requestedVerifyOption을 추가하면 Cloud Build는 해당 출처 메타데이터를 생성할 수 있는 경우에만 빌드를 성공한 것으로 표시합니다. 이는 비공개 풀에 빌드된 이미지에도 영향을 미쳐 해당 이미지의 출처 메타데이터 및 증명 생성을 지원합니다.

Binary Authorization으로 배포 제어

Binary Authorization의 정책은 이미지 배포를 제어하는 규칙 집합입니다. 규칙에서 디지털 서명된 증명을 요구하도록 구성할 수 있습니다.

Cloud Build는 빌드 시 증명을 생성하고 서명합니다. Binary Authorization을 통해 built-by-cloud-build 증명자를 사용하여 증명을 확인하고 Cloud Build로 빌드된 이미지만 배포할 수 있습니다. built-by-cloud-build 증명자는 프로젝트에서 빌드를 처음 실행할 때 만들어집니다.

Cloud Build에서 빌드한 이미지만 배포하도록 허용하려면 다음 단계를 수행합니다.

콘솔

  1. Google Cloud Console의 Binary Authorization 페이지로 이동합니다.

    Binary Authorization으로 이동

  2. 정책 탭에서 정책 수정을 클릭합니다.

  3. 정책 수정 대화상자에서 다음 모든 증명자가 승인한 이미지만 허용을 선택합니다.

  4. 증명자 추가를 클릭합니다.

  5. 증명자 추가 대화상자에서 다음을 수행합니다.

    1. 프로젝트 및 증명자 이름으로 추가를 선택하고 다음 단계를 수행합니다.
      1. 프로젝트 이름 필드에 Cloud Build를 실행할 프로젝트를 입력합니다.
      2. 증명자 이름 필드를 클릭하고 built-by-cloud-build 증명자를 사용할 수 있는지 확인합니다.
      3. built-by-cloud-build를 클릭합니다.
    2. 또는 증명자 리소스 ID로 추가를 선택합니다. 증명자 리소스 IDprojects/PROJECT_ID/attestors/built-by-cloud-build을 입력하고 PROJECT_ID를 Cloud Build를 실행하는 프로젝트로 바꿉니다.
  6. 증명자 1개 추가를 클릭합니다.

  7. 정책 저장을 클릭합니다.

gcloud

  1. 다음 명령어를 사용하여 기존 정책을 파일로 내보냅니다.

    gcloud container binauthz policy export > /tmp/policy.yaml
    
  2. 정책 파일을 수정합니다.

  3. 다음 규칙 중 하나를 수정합니다.

    • defaultAdmissionRule
    • clusterAdmissionRules
    • istioServiceIdentityAdmissionRules
    • kubernetesServiceAccountAdmissionRules
  4. 아직 규칙이 없으면 requireAttestationsBy 블록을 규칙에 추가합니다.

  5. requireAttestationsBy 블록에서 projects/<var>PROJECT_ID</var>/attestors/built-by-cloud-build를 추가하고 PROJECT_ID를 Cloud Build를 실행하는 프로젝트로 바꿉니다.

  6. 정책 파일을 저장합니다.

  7. 정책 파일을 가져옵니다.

    gcloud container binauthz policy import /tmp/policy.yaml
    

    다음은 built-by-cloud-build-attestor에 대한 참조가 포함된 정책 파일 예시입니다.

    defaultAdmissionRule:
      evaluationMode: REQUIRE_ATTESTATION
      enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
      requireAttestationsBy:
        - projects/PROJECT_ID/attestors/built-by-cloud-build
    name: projects/PROJECT_ID/policy
    

    PROJECT_ID를 Cloud Build를 실행하는 프로젝트 ID로 바꿉니다.

GKE 또는 Cloud Run의 Binary Authorization 로그 메시지에서 정책 오류를 볼 수 있습니다.

테스트 실행 모드 사용

테스트 실행 모드에서 Binary Authorization은 배포를 실제로 차단하지 않고 정책 규정 준수를 확인합니다. 대신 정책 규정 준수 상태 메시지가 Cloud Logging에 로깅됩니다. 이러한 로그를 사용하여 차단 정책이 올바르게 작동하는지 확인하고 거짓양성을 식별할 수 있습니다.

테스트 실행을 사용 설정하려면 다음을 수행합니다.

Console

  1. Google Cloud Console의 Binary Authorization 페이지로 이동합니다.

    Binary Authorization으로 이동

  2. 정책 수정을 클릭합니다.

  3. 기본 규칙이나 특정 규칙에서 테스트 실행 모드를 선택합니다.

  4. 정책 저장을 클릭합니다.

gcloud

  1. Binary Authorization 정책을 YAML 파일로 내보냅니다.

    gcloud container binauthz policy export  > /tmp/policy.yaml
    
  2. 텍스트 편집기에서 enforcementModeDRYRUN_AUDIT_LOG_ONLY로 설정하고 파일을 저장합니다.

  3. 정책을 업데이트하려면 다음 명령어를 실행하여 파일을 가져옵니다.

    gcloud container binauthz policy import /tmp/policy.yaml
    

GKE 또는 Cloud Run의 Binary Authorization 로그 메시지에서 정책 오류를 볼 수 있습니다.

증명자 메타데이터 보기

프로젝트에서 빌드를 처음 실행하면 증명자가 생성됩니다. 증명자 ID는 projects/PROJECT_ID/attestors/built-by-cloud-build입니다. 다음 명령어를 사용하여 빌드 증명자 메타데이터를 확인할 수 있습니다.

curl -X GET -H "Content-Type: application/json" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    https://binaryauthorization.googleapis.com/v1beta1/projects/PROJECT_ID/attestors/built-by-cloud-build

PROJECT_ID를 Cloud Build를 실행하는 프로젝트 로 바꿉니다.

출력에는 증명자 및 해당 공개 키에 대한 정보가 포함됩니다. 예를 들면 다음과 같습니다.

name": "projects/PROJECT_ID/attestors/built-by-cloud-build",
  "userOwnedDrydockNote": {
    "noteReference": "projects/PROJECT_ID/notes/built-by-cloud-build",
    "publicKeys": [
      {
        "id": "//cloudkms.googleapis.com/v1/projects/verified-builder/locations/asia/keyRings/attestor/cryptoKeys/builtByGCB/cryptoKeyVersions/1",
        "pkixPublicKey": {
          "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEMMvFxZLgIiWOLIXsaTkjTmOKcaK7\neIZrgpWHpHziTFGg8qyEI4S8O2/2wh1Eru7+sj0Sh1QxytN/KE5j3mTvYA==\n-----END PUBLIC KEY-----\n",
          "signatureAlgorithm": "ECDSA_P256_SHA256"
        }
      },
...
      }
    ],
    "delegationServiceAccountEmail": "service-942118413832@gcp-binaryauthorization.iam.gserviceaccount.com"
  },
  "updateTime": "2021-09-24T15:26:44.808914Z",
  "description": "Attestor autogenerated by build ID fab07092-30f4-4f70-caf7-4545cbc404d6"

다음 단계