How to use Harness CIE build to scan the container image before pushing it to a container registry?

When we use “build and push” step in a Harness CI pipeline, we would not have access on the image which is built as it will be pushed to the container registry as part of the same step. If we need to have access on the image before it is pushed to container registry to perform image scan, below steps can be followed.

  • Build an image using kaniko without push
  • Run trivy scan on created tarball (or any other scan)
  • Use crane to push the image tarball

Please refer the yaml representation of a sample pipeline given below which does the above steps.

pipeline:
  name: kaniko
  identifier: kaniko
  projectIdentifier: test-project
  orgIdentifier: default
  tags: {}
  stages:
    - stage:
        name: build
        identifier: build
        type: CI
        spec:
          cloneCodebase: false
          infrastructure:
            type: KubernetesDirect
            spec:
              connectorRef: ciplay
              namespace: default
              nodeSelector: {}
              os: Linux
          execution:
            steps:
              - step:
                  type: Run
                  name: create dockerfile
                  identifier: create_dockerfile
                  spec:
                    connectorRef: hdevdockerpt
                    image: alpine
                    shell: Sh
                    command: |-
                      cat << EOF > Dockerfile
                      FROM alpine

                      ENTRYPOINT [ "echo", "hello" ]
                      EOF
                      cat Dockerfile
              - step:
                  type: Run
                  name: kaniko no push
                  identifier: kaniko_no_push
                  spec:
                    connectorRef: hdevdockerpt
                    image: gcr.io/kaniko-project/executor:v1.9.1-debug
                    shell: Sh
                    command: |
                      /kaniko/executor --dockerfile Dockerfile --context . --no-push --destination $CI_IMAGE --tarPath image.tar
              - step:
                  type: Run
                  name: trivy scan
                  identifier: trivy_scan
                  spec:
                    connectorRef: hdevdockerpt
                    image: aquasec/trivy:0.32.1
                    shell: Sh
                    command: "trivy image --input=image.tar "
              - step:
                  type: Run
                  name: push
                  identifier: push
                  spec:
                    connectorRef: hdevdockerpt
                    image: gcr.io/go-containerregistry/crane:debug
                    shell: Sh
                    command: |-
                      crane auth login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
                      crane push image.tar $CI_IMAGE
        variables:
          - name: CI_IMAGE
            type: String
            description: ""
            value: <ci-image>
          - name: CI_REGISTRY_USER
            type: String
            description: ""
            value: <user-name>
          - name: CI_REGISTRY_PASSWORD
            type: Secret
            description: ""
            value: CI_REGISTRY_PASSWORD
          - name: CI_REGISTRY
            type: String
            description: ""
            value: index.docker.io

Note that the above additional steps would not be needed when we perform build using docker-in-docker(dind) image where you would have access to the image that is built and you can integrate any image scan before the image is pushed to a container registry. Also you can consider using Harness STO for more security testings use cases

4 Likes