By Trevor Rosen
This post originally appeared on GitHub.blog and has been revised for OpenSSF.
There’s an increasing need across enterprises and the open source ecosystem to have a verifiable way to link software artifacts back to their source code and build instructions. And with more than 100 million developers building on GitHub, we want to ensure that developers have the tools needed to help protect the integrity of their software supply chain. Today, we’re proud to announce the public beta of Artifact Attestations, a new feature that will pave the way for a cultural shift toward expecting to know where software comes from.
Artifact Attestations allows project maintainers to effortlessly create a tamper-proof, unforgeable paper trail linking their software to the process that created it. Downstream consumers of that metadata can then use it as a foundation for new security and validity checks through policy evaluation via tools such as Rego and Cue. We’re starting with verification support based on GitHub CLI, but we’ll expand to bring these same controls to the Kubernetes ecosystem as well later this year.
Artifact Attestations is powered by Sigstore, an Open Source Security Foundation (OpenSSF) open source project for signing and verifying software artifacts. This means that open source maintainers can reduce their project’s exposure to supply chain attacks and increase the security of the broader software ecosystem—no matter where maintainers host their code or build their artifacts. Let’s jump in.
An effortless user experience
Security features need to be more than just powerful—they have to be simple to adopt and easy to configure in order to be effective. Artifact Attestations couldn’t be easier to set up: all you need to do is add a bit of YAML to your GitHub Actions workflow to create an attestation and install the GitHub CLI tool to verify it.
- Enable your GitHub Actions workflow to write to the attestations store:
- Direct a workflow to create an attestation, making sure to place it after the artifact is generated:
- Once your build is finished and you have the artifact downloaded, use GitHub CLI (version 2.49.0 or greater) to verify it, providing the name of the organization that contains the repository where the action ran:
It’s also easy to download the attestation document itself for storage or offline verification (for example, in an air-gapped environment), quickly look at certificate details, or extract verified attestation contents in a JSON form so you can pipe it to a policy engine like OPA.
You can grab the attestation in JSON format and use the policy to verify that myfile.zip came from an allowed repository in the policy like so:
Can I attest other things in my build, such as an SBOM?
If you have an SBOM that you’ve generated as part of your build, you can use the new attest-sbom action to associate it with a final artifact. You simply provide the path to that artifact, and the action will take care of wrapping it in an in-toto attestation predicate, signing it with our internal Sigstore instance, and sending it to our attestation store. If you don’t already have an SBOM in your build and want a way to get started, the anchore/sbom-action offers support for container images and many language ecosystems.
To associate a build artifact with an attested SBOM, follow these steps:
- First (just like for provenance), you need to grant write permission for the attestation store to your workflow:
- Ensure that you actually have an SBOM that makes sense for your particular needs. Here’s an example of using Anchore’s Syft to scan a build directory:
- Finally, use the attest-sbom action to wrap the generated SBOM file contents in an in-toto SBOM predicate, sign it, associate it with your built artifact, and send it to the attestation store:
How it works
Artifact Attestations helps reduce the complexity of deploying and managing public key infrastructure, instead placing trust in the security of your GitHub account. We accomplish this by signing a document with a temporary key pair. The public key is attached to a certificate associated with a build system’s workload identity, and the private key never leaves process memory and is discarded immediately after signing. This differs from other signing approaches, which rely on human identities or long-lived keys. We believe that certificate revocation lists are too problematic to use effectively and that the future of software provenance and signatures goes through workload identity. Here’s how:
- When an attestation action executes, our Sigstore client requests the GitHub Actions OIDC token associated with that workflow run. It then creates a key pair and sends the public half to Fulcio, a certificate authority (CA), along with the OIDC token. In the case of a public repository, Sigstore Public Good Instance’s Fulcio issues the cert. In the case of a private repository, the cert is issued by GitHub’s internal instance of Fulcio, ensuring that no customer information leaves GitHub.
- Upon receiving the token, Fulcio validates the token’s signature and mints a new short-lived X.509 certificate binding the public key to the workflow’s OIDC identity.
- Fulcio returns the certificate to the client running in GitHub Actions, which calculates a SHA-256 digest of the subject artifact, and writes out an in-toto statement that binds the subject to a predicate containing data from the OIDC token’s claims.
- The client uses the private key to seal the in-toto statement in a DSSE signing envelope. Then, it throws the private key away. The envelope’s signature is sent to the TSA for a timestamp counter-signature, which proves that the signature was produced during the certificate’s 10-minute validity window.
- Everything is wrapped up as a Sigstore bundle and persisted to GitHub’s attestation store. In the case of a private repository, that’s the end of the flow. In the case of a public repository, the attestation is additionally written to the Sigstore Public Good Instance and lands on Rekor, the project’s immutable ledger.
Artifact Attestations has been in an early access preview for the last several months, and we’re thrilled by the early feedback we’ve received.
GitHub is now a root certificate authority
When we started designing the requirements for this feature, we realized quickly that we wanted users to be able to sign an artifact on GitHub Actions and then verify it anywhere, even offline. Public key infrastructure (PKI) is complex and high stakes, and we heard from both customers and open source projects that they wanted a way to sign things without having to build out PKI or manage secrets that can be leaked or lost. To do this, we first needed to establish GitHub as a root CA for signing software so that we could own the entire certificate chain.
In October 2023, we went live with an X.509 certificate authority and RFC 3161 timestamp server, with a trust root managed via a quorum of hardware tokens held by employees across a variety of geographies and roles. The trust root is managed with tooling from the TUF project (where we’re contributors), and the CA and timestamp services are instances of Sigstore applications. Intermediate certificates are housed in Azure KeyVault Managed HSMs, which are used to sign leaf certificates issued by Sigstore Fulcio and Sigstore Timestamp Authority. Signing certificates are valid for 10 minutes from the time of issuance, so there is no need to manage the complexities of certificate revocation lists.
Sigstore, in public and in private
In keeping with our commitment to offering cutting-edge features to both enterprise customers and the open source community, Artifact Attestations supports the same user experience offered in two basic modes depending on repository visibility. For public repositories, attestations generated on GitHub Actions will be written to the Sigstore Public Good Instance for verification in public on an immutable ledger. For private repositories on GitHub Enterprise plans, the attestations are written to an internal, completely private database, and no information is written to public ledgers or logs.
A more secure future
It’s important to note that provenance by itself doesn’t make your artifact or your build process secure. What it does do is create a tamper-proof guarantee that the thing you’re executing is definitely the thing that you built, which can stop many attack vectors. It’s still vital to maintain strong application security processes, such as requiring code review for all patches and applying dependency updates in a timely manner.
In other words: Attestations provide you with a paper trail, which cannot be forged, tying a given artifact to a given GitHub Actions workflow run. We believe that this is a key piece of the modern trust model, and in addition, we want to help effect a cultural shift toward folks knowing where their software components come from.
Artifact Attestations will allow customers unprecedented visibility into the composition and usage of their built software artifact, and this is just the beginning. We’ll be offering the ability to attest other kinds of artifacts associated with the build process, such as vulnerability reports and other pieces of metadata supported by the in-toto project’s defined predicate types. Look for exciting news around Kubernetes support, new guarantees for releases, and more later this year.
About the Author
Trevor Rosen is the founder of the Package Security team at GitHub, focused on improving supply chain security throughout the SDLC. He has extensive experience in practical information security with a particular focus on CI/CD systems. A veteran of the SolarWinds attack and subsequent response, Trevor is a frequent speaker at supply chain security conferences and sits on the Technical Steering Committee for Sigstore.