Cosign is an awesome tool used to sign and verify containers. In this post we will guide you through creating a container, pushing it to the registry, signing it, and finally verifying the signature.

Developed by Sigstore in collaboration with industry giants like Google, Github, and many more. It is specifically designed to elevate the security of your software supply chain while ensuring scalability and privacy. With attacks like Solar Winds it is more important than ever to have a secure software supply chain that don’t allow any tampering or forgery of the software inside your application.

As always you can follow along and check out the source code or clone it here .

Create a Container

Let’s get started by creating a container that we can sign. In this example we will use a simple Dockerfile.

1
2
FROM alpine
CMD ["echo", "Hello world!"]

Let’s build the container.

1
docker build -t <registry-name>/<repo-name>:<tag> .

…and finally push the container.

1
docker push <registry-name>/<repo-name>:<tag>

Cosign Keyless

The container can now be signed using Cosign’s keyless feature. This method guarantees a swift, hassle-free, and highly secure signing process. Keyless signing utilizes OpenID Connect and prompts you to sign in using either your Google, Microsoft or Github account. In this example we will use our Google account.

1
cosign sign <registry-name>/<repo-name>:<tag>

The signing process is complete and the output from the previous command will indicate that the signature has been successfully pushed to the registry.

Let’s explore how we can verify the container we just signed. For the verification to work seamlessly, we need to provide certain identity details that we expect to find in the signature. Specifically, we need to know the issuer and the identity certificate. Let’s initiate the verification process.

1
2
3
4
cosign verify \
  --certificate-identity <name@example.com> \
  --certificate-oidc-issuer https://accounts.google.com \
  <registry-name>/<repo-name>:<tag>

The output you receive from above command will provide you with confirmation regarding the verification and validation status of the container.

Self Managed Keys

It is also possible to sign and verify a container using a traditional keypair. Please make sure you will store the private key safely preferably in a password manager or similar. If you are using a KMS provider you can let the provider handle the private key for you. Supported KMS providers are AWS, GCP, Azure and Hashicorp Vault. You can also use a hardware tokens such as Yubikey to sign the container. However, this might not be the most suitable option if you plan on doing the signing process as part of your CI. I will not dive in to each provider but if you are interested you can read about provider specific information here .

1
cosign generate-key-pair

The private and public key will be written to the directory you ran the command from at cosign.key and cosign.pub. If you used KMS the keys will be stored at your provider.

The keys are created and we can again sign and verify the container we created using the private key.

1
cosign sign --key cosign.key <registry-name>/<repo-name>:<tag>

…and the verification is just as simple but this time we only use the public key.

1
cosign verify --key cosign.pub <registry-name>/<repo-name>:<tag>

That’s it! Thank you for reading!