Skip to content

Commit

Permalink
Merge pull request #55 from buildkite/isaacsu/pkg-7545-docs-for-initi…
Browse files Browse the repository at this point in the history
…al-provenance

[PKG-7545] First cut docs for Packages SLSA Provenance
  • Loading branch information
gilesgas authored Oct 14, 2024
2 parents 790d352 + cd815ef commit 1284eab
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 4 deletions.
2 changes: 2 additions & 0 deletions data/nav.yml
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,8 @@
path: "package-registries/security/oidc"
- name: "Permissions"
path: "package-registries/security/permissions"
- name: "SLSA provenance"
path: "package-registries/security/slsa-provenance"
- name: "Package ecosystems"
children:
- name: "Overview"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 5 additions & 3 deletions pages/package_registries/security/oidc.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@ The basic format for a Buildkite registry's OIDC policy, to handle OIDC tokens i
where:
- `iss` (the issuer) must be `https://agent.buildkite.com`, representing the Buildkite Agent.
- `organization-slug` can be obtained from the end of your Buildkite URL, after accessing **Packages** or **Pipelines** in the global navigation of your organization in Buildkite.
- `pipeline-slug` can be obtained from the end of your Buildkite URL, after accessing **Pipelines** in the global navigation of your organization in Buildkite.
- `main` or whichever branch of the repository you want to restrict package publication/uploads from pipeline builds.
- the `claims:` field contains:

* `organization-slug`, which can be obtained from the end of your Buildkite URL, after accessing **Packages** or **Pipelines** in the global navigation of your organization in Buildkite.
* `pipeline-slug`, which can be obtained from the end of your Buildkite URL, after accessing **Pipelines** in the global navigation of your organization in Buildkite.
* `main` or whichever branch of the repository you want to restrict package publication/uploads from pipeline builds.

However, more [complex OIDC policies](#define-an-oidc-policy-for-a-registry-complex-oidc-policy-example) can be created.

Expand Down
124 changes: 124 additions & 0 deletions pages/package_registries/security/slsa_provenance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# Generate and store SLSA provenance

## Introduction

Supply-chain levels for software artifacts ([SLSA](https://slsa.dev/spec/) and pronounced like "salsa") is an industry-consensus specification for describing and gradually improving artifact supply chain security.

When using Buildkite [Pipelines](/docs/pipelines) with [Package Registries](/docs/package-registries), you can publish software packages and artifacts to registries with [SLSA provenance](https://slsa.dev/provenance) in only four steps.

This guide uses the following Buildkite examples to demonstrate this process:

- Buildkite organization: `nova-corp`
- Pipeline: `ruby-logger-gem`, which builds a RubyGem package
- Registry: `ruby-gems` to store the RubyGem

Although this guide uses RubyGems as examples, this process will work for [all supported package ecosystems](/docs/packages/ecosystems) (with the exception of OCI-based packages like [Container (Docker)](/docs/packages/container) and [Helm OCI](/docs/packages/helm-oci)).

## Step 1: Configure steps to generate SLSA provenance

The [Generate Provenance Attestation Buildkite Plugin](https://github.com/buildkite-plugins/generate-provenance-attestation-buildkite-plugin) generates a SLSA provenance attestation for artifacts that have been uploaded to artifact storage in a pipeline step.

First, configure a step step that builds a RubyGem gem and uploads it to artifact storage.

```yaml
steps:
- label: "Build Gem"
command: "gem build logger.gemspec"
artifact_paths: "logger-*.gem"
```
A SLSA provenance attestation can be generated by adding this plugin to your pipeline step that builds the package or artifact:
```yaml
steps:
- label: "Build Gem"
command: "gem build logger.gemspec"
artifact_paths: "logger-*.gem"
plugins:
- generate-provenance-attestation#v1.1.0:
artifacts: "logger-*.gem"
attestation_name: "gem-attestation.json"
```
In the example above, a SLSA provenance attestation will be generated for artifacts matching `logger-*.gem` and be uploaded it to artifact storage as `gem-attestation.json`.

<%= image "artifacts-attestation.png", alt: "Screenshot of artifacts showing the attestation generated by the Generate Provenance Attestation Buildkite Plugin.", class: "no-decoration" %>

Once this step is complete, `gem-attestation.json` will be available to subsequent steps in the pipeline.

See [an example of a SLSA provenance statement](https://github.com/buildkite-plugins/generate-provenance-attestation-buildkite-plugin/blob/d9f2ff4d6b745f17cc55b6b91778a0e1a7d45824/examples/statement.json) that this plugin generates. This SLSA provenance statement is then serialized and uploaded as [a dead simple signing envelope (DSSE)](https://github.com/buildkite-plugins/generate-provenance-attestation-buildkite-plugin/blob/d9f2ff4d6b745f17cc55b6b91778a0e1a7d45824/examples/envelope.json). This `envelope.json` DSSE file shows an example of the `gem-attestation.json` file format. Learn more about DSSE in [DSSE Envelope](https://github.com/secure-systems-lab/dsse/blob/master/envelope.md).

## Step 2: Configure steps to publish a package with SLSA provenance

The [Publish to Packages](https://github.com/buildkite-plugins/publish-to-packages-buildkite-plugin/) plugin allows you to quickly and easily publish a package to Package Registries. When the `attestations: ` attribute is set, the package will be published from artifact storage with the specified attestations.
```yaml
steps:
- label: "Publish Gem"
plugins:
- publish-to-packages#v2.2.0:
artifacts: "logger-*.gem"
registry: "nova-corp/ruby-gems"
attestations:
- "gem-attestation.json"
```
In the example above, artifacts matching `logger-*.gem` will be published to `nova-corp/ruby-gems` Package Registry. Additionally, they will be published with the `gem-attestation.json` attestation.

## Step 3: Define an OIDC policy for the registry

The Publish to Packages plugin authenticates with Package Registries using an [Agent OIDC token](/docs/agent/v3/cli-oidc). Therefore, an [OIDC policy](/docs/packages/security/oidc#define-an-oidc-policy-for-a-registry) must be configured on the [Ruby registry](/docs/package-registries/ruby).

```yaml
- iss: "https://agent.buildkite.com"
claims:
organization_slug: "nova-corp"
pipeline_slug: "ruby-logger-gem"
```

{: codeblock-file="OIDC policy for nova-corp/ruby-gems registry"}

In the example above, the policy allows the Buildkite pipeline with slug `ruby-logger-gem`, configured in the Nova Corp Buildkite organization (with slug `nova-corp`) to publish packages to the Ruby registry named **ruby-gems**.

<%= image "oidc-policy.png", alt: "Screenshot of Artifacts showing the attestation generated by the Generate Provenance Attestation plugin.", class: "no-decoration" %>

## Step 4: Complete the pipeline

All the steps above come together in a simple pipeline that builds and publishes a Ruby Gem with SLSA Provenance. A [step dependency](/docs/pipelines/dependencies#defining-explicit-dependencies) ensures that the **Publish Gem** step does not start until the **Build Gem** step has finished successfully.

```yaml
steps:
- label: "Build Gem"
key: "build-gem"
command: "gem build logger.gemspec"
artifact_paths: "logger-*.gem"
plugins:
- generate-provenance-attestation#v1.1.0:
artifacts: "logger-*.gem"
attestation_name: "gem-attestation.json"
- label: "Publish Gem"
depends_on: "build-gem"
plugins:
- publish-to-packages#v2.2.0:
artifacts: "logger-*.gem"
registry: "nova-corp/ruby-gems"
attestations:
- "gem-attestation.json"
```

{: codeblock-file="pipeline.yml"}

This generates a build that looks something like this:

<%= image "full-pipeline-build.png", alt: "Screenshot of Artifacts showing the attestation generated by the Generate Provenance Attestation plugin.", class: "no-decoration" %>

The SLSA provenance will then be visible under the **Attestations** tab of a package details page.

<%= image "provenance-in-packages.png", alt: "Screenshot of Artifacts showing the attestation generated by the Generate Provenance Attestation plugin.", class: "no-decoration" %>

## Summary

- SLSA Provenance can be generated and stored in Buildkite with the help of [Generate Provenance Attestation](https://github.com/buildkite-plugins/generate-provenance-attestation-buildkite-plugin) and [Publish to Packages](https://github.com/buildkite-plugins/publish-to-packages-buildkite-plugin/) plugins.

- Artifacts that are built and published in this way satisfy [SLSA Build Level 1](https://slsa.dev/spec/v1.0/levels#build-l1) requirements.
1 change: 1 addition & 0 deletions vale/styles/Buildkite/h1-h6_sentence_case.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ exceptions:
- SAML
- SCIM
- Slack
- SLSA
- S3
- SSH
- SSO
Expand Down

0 comments on commit 1284eab

Please sign in to comment.