Recent articles
Harbor v2.11 release - The SBOMs release
Bonjour Harbor KubeCon + CloudNativeCon Europe 2024 - Paris
Harbor v2.10 release
Harbor Recap from KubeCon Chicago 2023
Introducing Cosign in Harbor v2.5.0
Introducing Cosign in Harbor v2.5.0
April 11, 2022
Orlin Vasilev
TL;DR;
Artifact signing and signature verification are critical security capabilities that allow you to verify the integrity of an artifact. Harbor supports content trust through integrations with
Notary and
Cosign.
Harbor v2.5 integrates support for Cosign, a OCI artifact signing and verification solution that is part of the Sigstore project.
Cosign signs OCI artifacts and pushes the generated signature into Harbor. This signature is stored as an artifact accessory along side the signed artifact. Harbor manages a link between the signed artifact and cosign signature, allowing you to apply things like tag retention rules and immutable rules to a signed artifact, and it will extend to both the signed artifact and the signature. In this way you can use Harbor’s built in functionality to manage signed artifacts and Cosign signature accessories.
A key feature of using Cosign with Harbor is the ability use Harbor’s replication capabilities to replicate signatures with their associated signed artifact. This means that if a replication rule applies to a signed artifact, Harbor will apply the replication rule to the signature in the same way it applies it to the signed artifact.
Full Documentation you will be able to find here
Configure two Harbor instances with Cosign enabled(default in v2.5.0) per repo and configure replication
We will have two instances harbor1 and harbor2, project “cosign” and replication rule(push based) between harbor1-to-harbor2, using robo-account.
Check out a video of this demo:
In our setup we use offline installer.
# ./install.sh --with-notary --with-trivy
[Step 0]: checking if docker is installed ...
...
...
...
[Step 5]: starting Harbor ...
Creating network "harbor_harbor" with the default driver
Creating network "harbor_harbor-notary" with the default driver
Creating network "harbor_notary-sig" with the default driver
Creating harbor-log ... done
Creating harbor-portal ... done
Creating redis ... done
Creating registryctl ... done
Creating registry ... done
Creating harbor-db ... done
Creating trivy-adapter ... done
Creating notary-signer ... done
Creating harbor-core ... done
Creating harbor-jobservice ... done
Creating nginx ... done
Creating notary-server ... done
✔ ----Harbor has been installed and started successfully.----
Setup new target registry:
Setup Replication from harbor1 -> harbor2:
To be able to perform the follwing steps you need to have “cosign” installed. Here are the instructions for the installation.
$ cosign generate-key-pair
Enter password for private key:
Enter again:
Private key written to cosign.key
Public key written to cosign.pub
You can export the password for the key(aka pass-phrase) so you can use it in automation:
export COSIGN_PASSWORD=Your_Super_P1$$w0rD
Use your cosign-demo user to sign into the first Harbor instance.
$ docker login harbor1.orlix.org
Authenticating with existing credentials...
Login Succeeded
Then push an image to the cosign project you have set up, the example below uses pause:1.
$ docker push harbor1.orlix.org/cosign/pause:1
The push refers to repository [harbor1.orlix.org/cosign/pause]
5f70bf18a086: Layer already exists
e16a89738269: Layer already exists
1: digest: sha256:b31bfb4d0213f254d361e0079deaaebefa4f82ba7aa76ef82e90b4935ad5b105 size: 938
Once we have the image available in the registry we can sign the image with cosign.
$ cosign sign --key cosign.key harbor1.orlix.org/cosign/pause:1
Enter password for private key:
Pushing signature to: harbor1.orlix.org/cosign/pause
Verify replication:
After triggering the replication rule harbor1->harbor2 on the harbor1 instance, you can see that the image is signed by Cosign in both Harbor instances or by running cosign verify.
$ cosign verify --key cosign.pub harbor1.orlix.org/cosign/pause:1 | jq .
Verification for harbor1.orlix.org/cosign/pause:1 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
[
{
"critical": {
"identity": {
"docker-reference": "harbor1.orlix.org/cosign/pause"
},
"image": {
"docker-manifest-digest": "sha256:b31bfb4d0213f254d361e0079deaaebefa4f82ba7aa76ef82e90b4935ad5b105"
},
"type": "cosign container image signature"
},
"optional": null
}
]
$ cosign verify --key cosign.pub harbor2.orlix.org/cosign/pause:1 | jq .
Verification for harbor2.orlix.org/cosign/pause:1 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
[
{
"critical": {
"identity": {
"docker-reference": "harbor1.orlix.org/cosign/pause"
},
"image": {
"docker-manifest-digest": "sha256:b31bfb4d0213f254d361e0079deaaebefa4f82ba7aa76ef82e90b4935ad5b105"
},
"type": "cosign container image signature"
},
"optional": null
}
Both verification returns result and exit code zero which indicates for valid signature! As well the digest is the same!
Hurray!!!
Join the
Harbor Community meetings and distribution lists
Get updates on Twitter at
@project_harbor
Chat with us on Slack at
#harbor on the
CNCF Slack
Collaborate with us on GitHub:
github.com/goharbor/harbor
Orlin Vasilev
Harbor Community Manager
github.com/OrlinVasilev