Andrew Block
6 min readJul 28, 2021

Rekor is an immutable transparency log server underneath the sigstore project that can be used by software maintainers to store signed records describing their application. Consumers can then lookup these records to verify the content for the software they are about to use. Rekor plays a pivotal role in the secure software supply chain as it provides another level of assurance that the software artifact that consumers are about to use has not been modified since the producer created it. Deploying your own instance of Rekor within a Kubernetes environment using Helm is a quick and easy way to advance your understanding of the role a transparency log has and how it can be incorporated into the software delivery process.

The sigstore community hosts a publicly available instance of Rekor at https://rekor.sigstore.dev. This is great for anyone who wants to distribute or make use of content targeted for the general public. However, given that most organizations create content that is not intended for public consumption, providing an alternative method of deploying Rekor is desired. In addition, if you are like me, when starting to learn about new concepts and beginning to get my hands dirty, I prefer to not have my “learnings” become public knowledge.

To support deploying an instance of Rekor within a Kubernetes environment, a Helm chart is available to simplify the deployment of the Rekor server along with its dependent components. The Rekor architecture consists of the following:

  • Rekor Server — Exposes an API based server for validation and a transparency log for storage
  • Redis — In-memory cache
  • Trillian — A transparent, highly scalable and cryptographically verifiable data store.
  • MySQL — Storage for Trillian
Rekor architecture

We won’t go into the details of Rekor’s architecture, but if you are interested, more information can be found on the Rekor project page.

Deploying Rekor using Helm

Rekor is just one of the available Helm charts located in the sigstore Helm chart repository. Adding a chart repository and managing Helm content is accomplished by making use of the Helm CLI. If you do not have the Helm CLI installed on your local machine, it can be installed using any of the methods described here.

Once the Helm CLI is installed, configured and available, execute the following commands to set up the sigstore Helm chart repository.

$ helm repo add sigstore https://sigstore.github.io/helm-charts$ helm repo update

You can view all of the charts available in the sigstore Helm repository by running the following command:

$ helm search repo sigstore/

The Rekor chart is quite extensible and supports being deployed to a variety of Kubernetes deployment targets. The options available can be inspected by viewing the content in the Git repository or using the CLI to display information about the chart.

$ helm show all sigstore/rekor

Given that Rekor exposes an API, the most important area to focus on is how traffic will reach the server itself. The chart supports exposing the server via an LoadBalancer service or as an Ingress in conjunction with an existing Ingress Controller. Additional options are available, but for the purpose of this discussion, let’s assume a Kubernetes deployment target with an existing Ingress controller. If you do not have an existing Kubernetes environment, you can use minikube and enable the ingress plugin which will deploy an instance of the NGINX ingress controller.

It is important to not only integrate tools, like Rekor, into the software delivery process, but do so using secure practices. This involves ensuring the communication between the client and server makes use of secure protocols, like TLS and HTTPS. In addition, this is also a requirement that is employed by Rekor itself. TLS certificates are associated with an Ingress resource by specifying the name of the Secret within the same namespace containing the certificates. Certificates can be provided from a variety of sources including generating your own manually (self signed), from a corporate Certificate Authority or using a tool like cert-manager which automates the generation and management within a Kubernetes environment. Regardless of how you provide the certificates, be sure that a Secret is available when the Helm chart is installed.

Note: As mentioned previously, there are multiple methods for managing the communication from external sources including facilitating TLS termination at Rekor itself.

Now, deploy the Rekor Helm chart. If you have not created a dedicated namespace for Rekor, create one. In the example below, a new namespace called rekor will be created and the current kubeconfig context will be changed to target this namespace.

$ kubectl create namespace rekor$ kubectl config set-context --current --namespace=rekor

Since we are using an Ingress for access to the Rekor server, two Helm values need to be specified: The hostname of the server which will be configured in the Ingress resource and the secret containing the TLS certificates.

Deploy the Rekor Helm chart by executing the following command:

$ helm upgrade -i -n rekor rekor sigstore/rekor --set=server.ingress.hostname=<hostname> --set=server.ingress.tls.secretName=<secret_name>

Note: Some ingress controllers support additional configurations through annotations placed on the Ingress resource. This can be accomplished by passing the --set=server.ingress.annotations."<annotation_name>"=<value> parameter. If the name of the annotation contains periods or forward slashes, they will need to be escaped with a \ preceding the character.

Once the chart has been installed, verify each of the pods are running and Ready

$ kubectl get pods -n rekorNAME                                         READY   STATUS    RESTARTS   AGErekor-mysql-55954594fb-lxv8b                 1/1     Running   0          1mrekor-redis-7db47db5f8-bgc4t                 1/1     Running   0          1mrekor-server-8655b97fb6-zp2rc                1/1     Running   2          1mrekor-trillian-log-server-866fc8d44d-79sph   1/1     Running   0          1mrekor-trillian-log-signer-7cf56bcf7-8pqgt    1/1     Running   0          1m

The rekor server pod may indicate multiple restarts under the status field. This is normal as it was waiting for dependencies to become available.

Next, confirm that you are able to query the Rekor API by retrieving the current state of the transparency log.

$ curl https://<hostname>/api/v1/log

A message similar to the following indicates a successful response:

{"rootHash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","signedTreeHead":"Rekor\n0\n47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=\nTimestamp: 1627450674310182057\n\n— rekor.sigstore.dev OTg2NzBFAiAdOitKMFxlww8GgyZL/rOUxDtIezdDkIg+y1qASSzlvgIhAMCug58E6rOhY74VkY2UapbV9S8weQKxL69vyZ6xV2MD\n","treeSize":0}

Upload an Entry

Several different types of records can be stored in Rekor. While entries can be submitted directly via the REST API, the easiest way to submit a record without having to be concerned with the underlying details is to use the Rekor CLI (rekor-cli). To confirm the functionality of the Rekor server deployed via the Helm chart, first install the Rekor CLI to your machine using the steps described here.

Once installed, use the rekor-cli to upload a recent version of the Jenkins CI server to your instance of Rekor:

$ rekor-cli upload --rekor_server=https://<hostname> --artifact=https://get.jenkins.io/war-stable/2.277.3/jenkins.war --type=jar --artifact-hash=3e22c7e8cd7c8ee1e92cbaa8d0d303a7b53e07bc2a152ddc66f8ce55caea91abCreated entry at index 0, available at: https://<hostname>/api/v1/log/entries/5bf721a65011f3c1273d728021cf669603e7b96b68d3e86249801a8eeb0a8c34

If the upload operation was successful, the log index and the url of the created record will be provided as a response. The value of the last path parameter (5bf721a65011f3c1273d728021cf669603e7b96b68d3e86249801a8eeb0a8c34 in the example response above is the uuid).

Note: Followers of the sigstore project may recall that this example was used in the March 2021 project update article.

To retrieve the entry from Rekor, use the get subcommand and reference the provided uuid value:

$ rekor-cli get --rekor_server=https://<hostname> --uuid=<uuid>

The details provided in the response allows you to both inspect how values are represented within the Rekor server, but also (more importantly) verify the content of software that you are attempting to utilize.