Supply chain security has been top-of-mind in light of recent software security incidents, including the Log4j vulnerability and the Solarwinds attack in 2021. At GitHub, we’ve been offering tools to help you respond to vulnerable dependencies since 2017, but attacks to the supply chain require a different approach.
Supply chain attacks take advantage of the fact that we cannot necessarily prove the software we get when we pull from an artifact or package repository is the same software that the developer authored and checked into their source code repository. It could have been modified, compromised through the build system, or may have bypassed CI/CD checks. This lack of assurance and visibility can leave developers vulnerable to supply chain compromises. To prevent supply chain threat vectors, GitHub has been working closely with our colleagues at the OpenSSF on a number of initiatives.
Last year, we announced that our default container publishing workflow would now generate signed images. Today, we’re applying that same method to Go projects. We’re also going a step further by adding support for automatically generating non-forgeable build provenance with GitHub Actions and Sigstore’s signing tools using a new GitHub workflow. This allows users to not only verify that the software they receive is authentic, but also to verify where it was built and with which software. This meets a new compliance standard from the OpenSSF called SLSA 3, which aims to help organizations improve their security posture against supply chain attacks. This workflow is available in the Actions tab in any GitHub repository.
What is Sigstore and SLSA?
Before jumping into the specifics, here’s a quick primer on the Sigstore project and other keywords in this blog.
Sigstore is made up of three projects:
- Cosign, which signs software.
- Fulcio, a certificate authority that lets anyone access short-lived certificates via OpenID Connect.
- Rekor, a secure log of signing events that allows you to verify the provenance of software artifacts.
Supply-chain Levels for Software Artifacts (SLSA) is a framework for improving the end-to-end integrity of a software artifact throughout its development lifecycle. The SLSA framework was built in response to National Institute of Standards and Technology’s (NIST) framework for software development, which emphasizes that users should verify the provenance of their software dependencies.
How does this workflow help implement SLSA 3?
In the SLSA framework, build processes create metadata called “provenance” that consumers can use to make risk-based assessments on what they consume. Provenance data supplies information about the origins of the software, in this case where it was built, who built it, and from what codebase it originated.
Cosign lets you not just sign the bytes of your end build product, but it can also include information on provenance, like the exact repository, commit, and Actions workflow that the build came from.
You can manage your own signing key for Cosign if you want, but you don’t have to! Fulcio lets you exchange an Actions OpenID Connect (OIDC) token for a Cosign certificate in return. Cosign will send a record of what it signs to the public Rekor server, which is both a useful datastore for retrieving validation information, as well as a transparency log to ensure your Actions OIDC token is being used the way you expect.
It’s hard to overstate how useful this is. Open source projects that build on GitHub Actions can use these parts of Sigstore to not just sign builds and provide information of provenance, but also do so without having to manage their own signing keys. If your organization maintains private Go modules, and would rather keep your information out of public transparency log, you can still use Cosign with your own signing key.
This workflow automates the end-to-end process for building Go modules. It can also be a model for other package management systems leveraging GitHub Actions and workflows to demonstrate the provenance needed to meet NIST’s recommendations.
How does this work?
Using GitHub Actions, we can create a reusable workflow that can act as a trusted build process and create non-forgeable metadata about the source and build process that generated the Go module.
GitHub Actions use an isolated virtual machine for each Actions workflow. The provenance information comes from the Actions OIDC token, which contains information specific to your run of an Actions workflow. This not only includes the repository, branch information, and specific commit of the code, but also the exact Actions workflow used to produce the build. This information lets anyone inspect, audit, or replicate a build.
Cosign, Fulcio, and Rekor help us to communicate this provenance information in a standard way. From a security-conscience internal team that manages deploys to an external party who wants to check your work, everyone can evaluate the integrity of the build.
The combination of GitHub Actions with the tooling from Sigstore makes it easier for more projects to sign their builds and is a huge leap forward for transparency in build provenance. We have more to do, but we’re excited to partner in ensuring the integrity of software through the build process.
Try it out
- To use this workflow you can follow the steps outlined here
- The build process will generate provenance metadata similar to this.
- The provenance data can be verified by looking up the Verification using some simple CLI commands to look up the result in Rekor
For more information and an in-depth architecture overview see the Google blog post.