Verifying the Artifact
After you sign the artifact using the Artifact Signing step, it’s crucial to verify that the artifact has not been tampered and was signed by a trusted source. The Artifact Verification process enables you to validate the integrity and authenticity of the signed artifact before it’s deployed.
Artifact Verification in SCS
The artifact verification step ensures the authenticity of the signed artifact by validating it with the corresponding public key. If the public key matches the signed artifact it confirms that the artifact is intact, secure, and originates from a trusted source.
Artifact Verification step configuration
The Artifact Verification step pulls the .sig
file from the artifact registry and verifies it with the corresponding public key. In the artifact signing step, if you chosen not to push the .sig
file to the registry, then for the artifact verification .sig
file will instead be pulled from the Harness database . This process ensures that the artifact was signed by a trusted entity, thereby confirming its integrity and authenticity.
Follow the instructions below to configure the Artifact Verification step.
-
Name: Provide a name for the verification step.
-
Artifact Source: Select the source container registry (e.g., DockerHub, ACR, GCR, ECR, etc.).
- DockerHub
- ECR
- GCR
- ACR
- GAR
-
Container Registry: Select the Docker Registry connector that is configured for the DockerHub container registry where the artifact is stored.
-
Image: Enter the name of your image using a tag or digest, example
my-docker-org/repo-name:tag
or you can use the digestmy-docker-org/repo-name@sha256:<digest>
-
Container Registry: Select the Docker Registry connector that is configured for the Elastic container registry where the artifact is stored.
-
Image: Enter the name of your image using a tag or digest, example
my-docker-repo/my-artifact:tag
or you can use the digestmy-docker-repo/my-artifact@sha256:<digest>
-
Artifact Digest: Specify the digest of your artifact. After building your image using the Build and Push step or a Run step, save the digest in a variable. You can then reference it here using a Harness expression. Refer to the workflows described below for detailed guidance.
-
Region: The geographical location of your ECR repository, example
us-east-1
-
Account ID: The unique identifier associated with your AWS account.
-
Container Registry: Select the Docker Registry connector that is configured for the Google container registry where the artifact is stored.
-
Image: Enter the name of your image using a tag or digest, example
my-image:tag
or you can use digestmy-image@sha256:<digest>
-
Artifact Digest: Specify the digest of your artifact. After building your image using the Build and Push step or a Run step, save the digest in a variable. You can then reference it here using a Harness expression. Refer to the workflows described below for detailed guidance.
-
Host: Enter your GCR Host name. The Host name is regional-based. For instance, a common Host name is
gcr.io
, which serves as a multi-regional hostname for the United States. -
Project ID: Enter the unique identifier of your Google Cloud Project. The Project-ID is a distinctive string that identifies your project across Google Cloud services. example:
my-gcp-project
-
Container Registry: Select the Docker Registry connector that is configured for the Azure container registry where the artifact is stored.
-
Image: Enter your image details in the format
<registry-login-server>/<repository>
. The<registry-login-server>
is a fully qualified name of your Azure Container Registry. It typically follows the format<registry-name>.azurecr.io
, where<registry-name>
is the name you have given to your container registry instance in Azure. Example input:automate.azurecr.io/<my-repo>:tag
or you can use digestautomate.azurecr.io/<my-repo>@sha256:<digest>
-
Artifact Digest: Specify the digest of your artifact. After building your image using the Build and Push step or a Run step, save the digest in a variable. You can then reference it here using a Harness expression. Refer to the workflows described below for detailed guidance.
-
Subscription Id: Enter the unique identifier that is associated with your Azure subscription.
-
Container Registry: Select the Docker Registry connector that is configured for the Google container registry where the artifact is stored.
-
Image:: Enter the name of your image using tag or digest, example
repository-name/image:tag
or you can use digestrepository-name/image:digest
-
Artifact Digest: Specify the digest of your artifact. After building your image using the Build and Push step or a Run step, save the digest in a variable. You can then reference it here using a Harness expression. Refer to the workflows described below for detailed guidance.
-
Host: Enter your GAR Host name. The Host name is regional-based. For example,
us-east1-docker.pkg.dev
. -
Project ID: Enter the unique identifier of your Google Cloud Project. The Project-ID is a distinctive string that identifies your project across Google Cloud services. example:
my-gcp-project
The image used for the artifact verification step must be the same as the image used for the artifact signing step
You can verify the signed artifact with Cosign or Cosign with Secret Manager
- Cosign
- Cosign with Secret Manager
To perform the attestation verification with Cosign selected, you need to pass the key from the Harness Secret Manager
- Public Key: Input your Public key from the Harness file secret.
If you used HashiCorp Vault as your Secret Manager for attestation, you can also use it for verifying the attestation.
- Connector: Select the same HashiCorp Vault connector that was used during the attestation process.
- Key: Enter the path to the Transit Secrets Engine in your HashiCorp Vault where your public key is stored. This should be the same path used for the attestation process. Note that HashiCorp Vault does not allow viewing the private key directly.
View Verified Artifacts
Once the artifact is signed and verified, you will be able to see the Artifact Integrity Verification status from the Artifacts Overview tab.
-
If the signed artifact is successfully verified using the public key, the verification status is displayed as Passed, along with a link to the corresponding Rekor log entry.
-
If the verification fails, the status is displayed as Failed.
Example Pipeline For Artifact Verification
This example demonstrates how to implement artifact Verification in the Build stage of the pipeline.
At present, Harness does not support artifact verification in the deployment stage, However this is part of our roadmap.
This example Build stage has three steps:
-
Build and Push an Image to Docker Registry: This step pulls the code, build the image and push it to a Docker registry (e.g., DockerHub, ACR, GCR, etc.).
-
Artifact Signing: Pulls the artifact from the registry and signs it with a private key pair and pushes the .sig file back to the artifact registry.
-
Artifact Verification: Verify the signed artifact using the corresponding public key to confirm its source and integrity.
To replicate the Artifact Verification step you can use the below sample pipeline YAML
Sample Pipeline YAML
pipeline:
name: ArtifactVerification
identifier: ArtifactVerification
tags: {}
projectIdentifier: Harness
orgIdentifier: default
properties:
ci:
codebase:
connectorRef: Harnessgithub
build: <+input>
stages:
- stage:
name: Build
identifier: Build
description: ""
type: CI
spec:
cloneCodebase: true
caching:
enabled: true
buildIntelligence:
enabled: true
execution:
steps:
- step:
type: BuildAndPushDockerRegistry
name: BuildAndPushDockerRegistry_1
identifier: BuildAndPushDockerRegistry_1
spec:
connectorRef: lavakushDockerhub
repo: lavakush07/easy-buggy-app
tags:
- v5
caching: true
- step:
type: SscaArtifactSigning
name: Artifact Signing_1
identifier: ArtifactSigning_1
spec:
source:
type: docker
spec:
connector: lavakushDockerhub
image: lavakush07/easy-buggy-app:v5
signing:
type: cosign
spec:
private_key: account.Cosign_Private_Key
password: account.Cosign_Password
uploadSignature:
upload: true
- step:
type: SscaArtifactVerification
name: Artifact Verification_1
identifier: ArtifactVerification_1
spec:
source:
type: docker
spec:
connector: lavakushDockerhub
image: lavakush07/easy-buggy-app:v5
verifySign:
type: cosign
spec:
public_key: account.Cosign_Public_Key
infrastructure:
type: KubernetesDirect
spec:
connectorRef: account.harness_kubernetes_connector
namespace: artifactsigning
automountServiceAccountToken: true
nodeSelector: {}
os: Linux
variables:
- name: LOG_LEVEL
type: String
description: ""
required: false
value: TRACE