Create attestations with OpenSSF Scorecard

This tutorial demonstrates how to use OpenSSF Scorecard to check container images for supply chain security best practices. The Scorecard Attestor runs as part of Cloud Build pipeline to generate an attestation that can be verified by Binary Authorization before deployment. This verification step prevents compromised container artifacts from being deployed to production, which can prevent several classes of supply chain vulnerabilities.

Overview

The Open Source Security Foundation (OpenSSF) is an organization that provides tools, services, and infrastructure for open source security initiatives. Scorecard is a tool, maintained by the OpenSSF, that scans source code management (SCM) repositories for supply chain security best-practices.

Scorecard Attestor is a tool built into Scorecard that allows you to create Binary Authorization attestations based on a policy that you configure. Scorecard Attestor runs Scorecard against the SCM repository of a container image, generates results, evaluates the results against the policy, and generates an attestation if the policy is satisfied.

In this tutorial, you build a sample repository and then use Scorecard Attestor. Each sample pipeline contains the following build steps:

  1. build : Build a sample container image.
  2. push : Push the image to Container Registry.
  3. attest : Check and sign the image, using Scorecard Attestor to create an attestation based on the policy.

In the attest step of each pipeline, Scorecard Attestor does the following:

  1. Fetches data about the SCM repository for the newly built container image.
  2. Runs Scorecard on the raw data and evaluates the SCM repository against the user-specified policy.
    1. If all policies are satisfied, Scorecard Attestor creates the attestation.
    2. If any of the policies aren't satisfied, Scorecard Attestor doesn't create the attestation.

At deployment time, Binary Authorization checks for a verifiable attestation. Without one, the enforcer disallows the image from deploying.

Costs

This tutorial uses the following Google Cloud products.

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

Use the Pricing Calculator to generate a cost estimate based on your projected usage.

Objectives

In this tutorial you do the following:

  1. Set up Scorecard Attestor as a Cloud Build custom builder.
  2. View and configure Scorecard Attestor policy.
  3. Run Scorecard Attestor on a sample repository to create an attestation based on a policy.
  4. Run Scorecard Attestor on a sample repository in verify-only mode without creating an attestation. ## Before you begin

In this section, you perform a one-time setup of the system.

Set up your environment

  1. Store your Google Cloud project in an environment variable.

    export PROJECT_ID= PROJECT_ID 
    

    Replace PROJECT_ID with your Google Cloud project.

  2. Set the default project ID to your Google Cloud project:

     gcloud  
    config  
     set 
      
    project  
     $PROJECT_ID 
     
    
  3. Store the project number in an environment variable for future steps:

      export 
      
     PROJECT_NUMBER 
     = 
     $( 
    gcloud  
    projects  
    list  
    --filter = 
     " 
     ${ 
     PROJECT_ID 
     } 
     " 
      
     \ 
      
    --format = 
     "value(PROJECT_NUMBER)" 
     ) 
     
    
  4. Enable APIs:

    To ensure the services required for this guide are enabled, execute the following command:

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

Set up IAM roles

Run the following commands to configure the Cloud Build service account with the following roles:

  • containeranalysis.notes.editor : adds the Artifact Analysis Notes Editorrole to manage the attestor.
  • containeranalysis.notes.occurrences.viewer : adds the Artifact Analysis Occurrences for Notesrole to manage both the vulnerability and attestation occurrences.
  • roles/containeranalysis.occurrences.editor : adds the Artifact Analysis Occurrences Editorrole to create attestation occurrences in Artifact Analysis.
  • cloudkms.signer : adds the Cloud KMS CryptoKey Signerrole that allows the service account to access the Cloud KMS signing service.

     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 
    

Create a Cloud KMS signing key

Cloud Key Management Service keys are used to create the attestation.

  1. Create a new Cloud KMS key ring with the name scorecard-attestor-key-ring :

     gcloud  
    kms  
    keyrings  
    create  
     scorecard-attestor-key-ring 
      
     \ 
      
    --location  
    global 
    
  2. Create a new Cloud KMS key called scorecard-attestor-key within the key ring:

     gcloud  
    kms  
    keys  
    create  
     scorecard-attestor-key 
      
     \ 
      
    --keyring  
     scorecard-attestor-key-ring 
      
     \ 
      
    --location  
    global  
     \ 
      
    --purpose  
     "asymmetric-signing" 
      
     \ 
      
    --default-algorithm  
     "rsa-sign-pkcs1-2048-sha256" 
     
    
  3. Store the digest algorithm and Cloud KMS in an environment variable for future steps:

      export 
      
     KMS_DIGEST_ALG 
     = 
    SHA256 export 
      
     KMS_KEY_NAME 
     = 
    projects/ $PROJECT_ID 
    /locations/global/keyRings/ scorecard-attestor-key-ring 
    /cryptoKeys/ scorecard-attestor-key 
    /cryptoKeyVersions/1 
    
  4. Create the Binary Authorization attestor. Later, Scorecard Attestor creates a note associated with this attestor.

     gcloud  
    container  
    binauthz  
    attestors  
    create  
     scorecard-attestor 
      
     \ 
      
    --attestation-authority-note = 
    scorecard-attestation  
     \ 
      
    --attestation-authority-note-project = 
     $PROJECT_ID 
      
     \ 
      
    --description = 
     "Attest that ossf/scorecard policy checks pass" 
     
    
  5. Associate the Binary Authorization attestor with the KMS key:

     gcloud  
    container  
    binauthz  
    attestors  
    public-keys  
    add  
     \ 
      
    --attestor = 
     scorecard-attestor 
      
     \ 
      
    --keyversion = 
     1 
      
     \ 
      
    --keyversion-key = 
     scorecard-attestor-key 
      
     \ 
      
    --keyversion-keyring = 
     scorecard-attestor-key-ring 
      
     \ 
      
    --keyversion-location = 
    global  
     \ 
      
    --keyversion-project = 
     $PROJECT_ID 
     
    

To explore other signing algorithms, refer to Creating asymmetric keys .

Create attestations with Scorecard Attestor in a Cloud Build pipeline

Submit the failure-case sample build

In this section, you build a container image and check its supply chain security practices with OpenSSF Scorecard. The image builds successfully, but does not create an attestation. The base repository contains some discouraged supply chain security practices, such as an unpinned dependency to Debian 10 in the Dockerfile, and a compiled binary artifact checked into the source repository. These are violations of the attestation policy in the repository.

  1. Clone the test repository: scorecard-binauthz-test-bad .

  2. View the attestation policy file for the failure case.

     cat  
    policy-binauthz.yaml 
    
  3. (Optional) View the build configuration file for the failure case.

     cat  
    samples/signer/cloudbuild.yaml 
    
  4. Submit the build:

     gcloud  
    builds  
    submit  
     \ 
      
    --substitutions = 
     _KMS_KEY_NAME 
     = 
     $KMS_KEY_NAME 
    ,_KMS_DIGEST_ALG = 
     $KMS_DIGEST_ALG 
      
     \ 
      
    --config = 
    cloudbuild.yaml 
    

You should see output like the following:

 time="2022-12-20T22:30:14Z" level=info msg="image failed scorecard attestation policy check" 
  1. Save the build ID from the last build:

    export BUILD_ID=$(gcloud builds list --limit=1 --format="value('ID')")
  2. Verify the result:

     gcloud  
    storage  
    cat  
    gs:// ${ 
     PROJECT_NUMBER 
     } 
    .cloudbuild-logs.googleusercontent.com/log- ${ 
     BUILD_ID 
     } 
    .txt  
     | 
      
    grep  
     "failed scorecard attestation policy check" 
     
    

Submit the success-case sample build

In this section you build a container image that satisfies its Scorecard attestation policy. In this case, the Scorecard Attestor creates an attestation.

To submit the success-case sample build to Cloud Build, do the following:

  1. Clone the test repository: scorecard-binauthz-test-good .

  2. View the attestation policy file for the failure case. sh cat policy-binauthz.yaml

  3. (Optional) View the build configuration file for the failure case.

     cat  
    samples/signer/cloudbuild.yaml 
    
  4. Submit the build:

     gcloud  
    builds  
    submit  
     \ 
      
    --substitutions = 
     _KMS_KEY_NAME 
     = 
     $KMS_KEY_NAME 
    ,_KMS_DIGEST_ALG = 
     $KMS_DIGEST_ALG 
      
     \ 
      
    --config = 
    cloudbuild.yaml 
    
  5. Verify the result:

     gcloud  
    storage  
    cat  
    gs:// ${ 
     PROJECT_NUMBER 
     } 
    .cloudbuild-logs.googleusercontent.com/log- ${ 
     BUILD_ID 
     } 
    .txt  
     | 
      
    grep  
     "passed scorecard attestation policy check" 
     
    
  6. Get the URL of the container image that was built and checked by scorecard

      export 
      
     IMAGE_URI 
     = 
     $( 
    gcloud  
    storage  
    cat  
    gs:// ${ 
     PROJECT_NUMBER 
     } 
    .cloudbuild-logs.googleusercontent.com/log- ${ 
     BUILD_ID 
     } 
    .txt  
     | 
      
    grep  
    -o  
     "Attestation for image .* is successfully uploaded" 
      
    txt  
     | 
      
    cut  
    -d ' ' 
      
    -f4  
     | 
      
    tr  
    -d  
     '"' 
     ) 
     
    
  7. Confirm that an attestation was created for the container image. Scorecard Attestor uses the Note ID ossf-scorecard-attestation , and the note name projects/${PROJECT_ID}/notes/ossf-scorecard-attestation .

     gcloud  
    container  
    binauthz  
    attestations  
    list  
     \ 
      
    --attestor = 
     "projects/ 
     ${ 
     PROJECT_ID 
     } 
     /attestors/ossf-scorecard-attestor" 
      
     \ 
      
    --filter = 
     "resourceUri='https:// 
     ${ 
     IMAGE_URI 
     } 
     '" 
     
    

Clean up

To clean up resources used in this document, you can delete the project:

 gcloud projects delete $PROJECT_ID 

What's next

Create a Mobile Website
View Site in Mobile | Classic
Share by: