Sigstore: A Solution to Software Supply Chain Security
Tags: devops, cloud, security
Published: 2021-08-16 18:17:57


In the recent months there's been a lot of noise in the area of supply chain security, because of increase in attacks, with notable ones like _Microsoft Exchange Server_, _Colonial pipeline_ or _SolarWinds_ breach. These attacks could have been prevented with proper tools in place, yet finding the right tool for the job might be difficult as this area is hard to navigate and most of us - developers - aren't security experts. Recently however, a new project was announced that might solve a lot of problems for all of us. It's name is _sigstore_ and in this article we will look at what it does, why we need it and how it fits into landscape of existing tools in this area. 

## sig-what?

sigstore is a new kid on the block. It's a project under CNCF umbrella that was _"donated"_ to the foundation in March. It's purpose is to provide software signing public-good service. Which means that it should become a software-signing equivalent to _Let's Encrypt_. sigstore however, isn't just one tool or piece of software, it's a collection of projects that aim to simplify software signing and transparency. It's main components as of right now are `fulcio`, `rekor` and `cosign` (more details on those a bit later).

Now you might be asking _"Why do we actually need this?"_ - software-signing is not a new problem, so there must be some solution already, right? Yes, but signing software and maintaining keys is very difficult especially for non-security folks and UX of existing tools such as PGP leave much to be desired. That's why we need something like sigstore - an easy to use software/toolset for signing software artifacts.

Additionally, there are couple of reasons why sigstore's solution is superior to tools like PGP that try to solve the same problem. Unlike with other tools, with sigstore you don't need to manage private keys. You also don't have to understand ins-and-outs of security standards thanks to better UX. sigstore also makes it simpler to manage revocations and with all this it still provides all the required features of software signing, that being _integrity_, _non-repudiation_ and _authentication_.

Bottom line is that sigstore aims to make artifact signing so simple that it can be done by default and transparently, and is ubiquitous across all registries and artifact storages.

## Alternatives

From the above it might seem like sigstore is the tool that can solve it all, but if you start googling around, you will find plenty of great tools in supply chain security space. Most of these tools however, don't serve exactly the same purpose and they really are complementary to what sigstore is doing. So, let's also review rest of the landscape to see what else is out there:

- One of the many tools you'll come across is _[The Update Framework (TUF)](https://theupdateframework.io/overview/)_. It's also part of CNCF and its purpose is specifically to protect the process of finding and downloading patches/updates for some particular system (e.g. YUM, PyPI). This system is suitable for artifacts that are meant to be distributed using an update system.

- While talking about TUF, it also makes sense to mention _Notary_ which is an implementation of TUF specification. It is most notably used in _Docker Notary_ which provides the ability to use digital signatures for data sent to and received from remote Docker registries. You can read more about _Docker Content Trust_ [here](https://docs.docker.com/engine/security/trust/) or can also try playing with `docker trust` command. In case you might want to implement something like that, then you can checkout this article for full [demo](https://www.cncf.io/blog/2021/07/28/enforcing-image-trust-on-docker-containers-using-notary/).

- Another great tool is _[in-toto](https://github.com/in-toto/in-toto)_. This tool isn't just for signing artifacts, it rather produces _attestations_ about how the software was produced. Essentially, verifying that each task in a pipeline was carried out as planned and therefore providing assurance that final product was not tampered with. You can use _in-toto_ as part of _Tekton Chains_.

- Finally, I also want to mention [Trillian](https://transparency.dev/#trillian) which is a tamper-evident log that stores an accurate, immutable and verifiable history of activity. This kind of log can be used for example to add tamper-checking to a system, simplify regulatory compliance or track modifications of documents. sigstore also includes tamper-evident log called `rekor` which is will talk about later.

- There's much more we could talk about, but that would take a while. If you want to dig deeper, then checkout [CNCF Landscape page](https://landscape.cncf.io/) and more specifically _Security and Compliance_ (e.g. OPA) and _Key Management_ (e.g. SPIFFE and SPIRE) sections.

All of these tools have their pros and cons and could be combined and extended to provide stronger security. For more details about this you can checkout [document](https://github.com/sigstore/community/blob/main/docs/zero-trust-supply-chains.pdf) in sigstore's community repository (see _Further Work_ section).

## Components

Before we dig deeper into components of sigstore, we first need to understand the basics of the signing process. The basic steps are as follows:

1. Short-lived code-signing credentials (a keypair) are generated.
2. User authenticates with _OpenID Connect (OIDC)_ provider such as Google or GitHub to verify ownership of email address and possession of previously generated keys.
3. If authentication is successful, user receives code-signing certificate.
4. Code-signing certificate is published to transparency log, so that it can be verified by others.
5. User signs an artifact (e.g. container image) using code-signing certificate and their keypair.
6. Signature from the artifact is published to transparency log.
7. Short-lived code-signing credentials used to create signature are destroyed.
8. Signed artifact can be published (e.g. on container registry).

Different explanation of the process can be also found on sigstore website in [What is sigstore? section](https://sigstore.dev/what_is_sigstore/).

Now that we have a better idea about how it all works, let's look at all the components. There are couple of things that apply to all of them, namely, they can (and should) run in cloud by default (runs on Kubernetes). Even though sigstore hosts a public-good service you can take any of these components and host them yourself (for example behind firewall) and you also don't need to use all of the service, but maybe just one of them, for example just the transparency log server.

As for the individual components, there are currently 3 main pieces:

- [cosign](https://github.com/sigstore/cosign) is a container signing tool. Its responsibility is to sign containers and publish that information to OCI registries. In the above process that matches the steps 1, 5, 6 and 7.
- [fulcio](https://github.com/sigstore/fulcio) is a root CA for code signing certs. Its job is to issue code-signing certificates and to embed OIDC identity into code-signing certificate. From this description we can see that it performs these tasks in steps 2, 3, 4 and 8.
- [rekor](https://github.com/sigstore/rekor) is the transparency log. It's append-only, immutable ledger that serves as transparent source of truth of what was signed by whom. 

Now, in practice the above tools and services would be used in the following way to perform the signing process:

`cosign` generates an ephemeral keypair and requests code-signing certificate from `fulcio` which then asks you to login with OIDC provider of your choice. It uses the authentication to verify that you're owner of the ephemeral private key. `cosign` will then retrieve container image manifest of the image you want to sign and will generate a signature using the key it previously generated. Next, `cosign` uploads the signature, certificate and public key to registry. Finally, it sends the information to `rekor`, which verifies the signature and adds entry into transparency log. Here, this entry includes the artifact digest, signature and public key. At this point ephemeral keypair can be deleted.

In addition to these pieces of software, there also needs to be a monitoring service that checks the transparency log (`rekor`) for any anomalies. Example of such anomaly could be if someone stole your password and used your OpenID identity to sign and publish an artifact, which would be clear from the transparency log.

Finally, there needs to a way to - for example - say who are the maintainers who are actually trusted to sign artifacts/releases of some project. This could be done e.g. using Open Policy Agent (OPA) and by maintaining list emails (OpenID identities) in the project repository and allowing to sign artifacts only the people in this list.

## Closing Thoughts

This kind of security practices are not exactly common right now and in some cases really neglected. So, the more people start using this, the more likely it's to become the default process and good practice. With that said, at the time of writing, sigstore is a very young project and is not yet production-ready but it should be by the end of summer, so very soon you might be able to put this knowledge to some good use and help the software supply chain be a bit more secure.

With all that said, this article should serve as a primer on supply chain security and to give you a general idea about sigstore and in follow-up article we will tackle the actual signing process in detail with hands-on examples.