Skip to content

Commit

Permalink
Apply suggestions from code review
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Belton <[email protected]>
  • Loading branch information
moskyb and mbelton-buildkite authored Nov 24, 2023
1 parent 2cc4fe6 commit 928451c
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions pages/agent/v3/signed_pipelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
Signed pipelines are a security feature where pipelines are cryptographically signed when uploaded to Buildkite. Agents then verify the signature before running the job. If an agent detects a signature mismatch, it'll refuse to run the job.

Maintaining a strong security boundary is important to Buildkite and informs how we design features. It's also a key reason people choose Buildkite over other CI/CD tools. Signing pipelines improves your security posture by ensuring agents don't run jobs where a malicious actor has modified the instructions. This moves you towards zero-trust CI/CD by further isolating you from Buildkite itself being compromised.

The signature guarantees the origin of jobs by asserting:

- The jobs were uploaded from a trusted source.
Expand Down Expand Up @@ -34,7 +36,7 @@ The following fields are included in the signature for each step:
- **Environment variables defined in the pipeline YAML.** Environment variables set by the agent, hooks, or the user's shell are _not_ signed, and can override the environment a step's command is started with.
- **Plugins and plugin configuration.**
- **Matrix configuration.** The matrix configuration is signed as a whole rather than each individual matrix job. This means the signature is the same for each job in the matrix. When signatures are verified for matrix jobs, the agent double-checks that the job it received is a valid construction of the matrix and that the signature matches the matrix configuration.
- **The repo the commands are running in.** This prevents you from copying a signed step from one repo to another.
- **The repository the commands are running in.** This prevents you from copying a signed step from one repository to another.

## Enabling signed pipelines on your agents

Expand All @@ -44,7 +46,7 @@ You'll need to configure your agents and update pipeline definitions to enable s

Behind the scenes, signed pipelines use [JSON Web Signing (JWS)](https://datatracker.ietf.org/doc/html/rfc7797) to generate signatures. You'll need to generate a [JSON Web Key Set (JWKS)](https://datatracker.ietf.org/doc/html/rfc7517) to sign and verify your pipelines with, then configure your agents to use those keys.

Luckily, the agent has you covered! A JWKS generation tool is built into the agent, which you can use to generate a key pair for you. To use it, you'll need to [install the agent on your machine](/docs/agent/v3/installation), and then run:
Luckily, the agent has you covered! A JWKS generation tool is built into the agent, which you can use to generate a key pair. To use it, you'll need to [install the agent on your machine](/docs/agent/v3/installation), and then run:

```bash
buildkite-agent tool keygen --alg <algorithm> --key-id <key-id>
Expand All @@ -55,7 +57,7 @@ Replacing the following:
- `<algorithm>` with the signing algorithm you want to use.
- `<key-id>` with the key ID you want to use.

For example, to generate an EdDSA key pair with a key ID of `my-key-id`, you'd run:
For example, to generate an [EdDSA](https://en.wikipedia.org/wiki/EdDSA) key pair with a key ID of `my-key-id`, you'd run:

```bash
buildkite-agent tool keygen --alg EdDSA --key-id my-key-id
Expand Down Expand Up @@ -111,13 +113,14 @@ verification-jwks-file=<path to verification keys>

### 3. Sign all steps

So far, you've configured agents to sign and verify any steps they upload and run. But there's another source of steps: the Buildkite dashboard. Rather than defining steps in your repository, you can also define steps in a pipeline's settings. The most common use for this is to have a single step that uploads a pipeline definition from [a YAML file in the repository](/docs/pipelines/defining-steps#step-defaults-pipeline-dot-yml-file). These steps should also be signed.
So far, you've configured agents to sign and verify any steps they upload and run. However, you also define steps in a pipeline's settings through the Buildkite dashboard. For example, teams commonly use a single step in the Buildkite dashboard to upload a pipeline definition from [a YAML file in the repository](/docs/pipelines/defining-steps#step-defaults-pipeline-dot-yml-file). These steps should also be signed.

> 🚧 Non-YAML steps
> You must use YAML to sign steps configured in the Buildkite dashboard. If you don't use YAML, you'll need to [migrate to YAML steps](/docs/tutorials/pipeline_upgrade) before continuing.
To sign steps configured in the Buildkite dashboard, you need to add static signatures to the YAML. To do this, run:
```Bash

```sh
buildkite-agent tool sign \
--graphql-token <token> \
--jwks-file <path to signing jwks> \
Expand All @@ -126,12 +129,14 @@ buildkite-agent tool sign \
--pipeline-slug <pipeline slug> \
--update
```
making the following replacements:

Replacing the following:

- `<token>` with a Buildkite GraphQL token that has the `write_pipelines` scope.
- `<path to signing jwks>` with the path to the private keyset you generated earlier.
- `<signing key id>` with the key ID from earlier
- `<signing key id>` with the key ID from earlier.
- `<org slug>` with the slug of the organization the pipeline is in.
- `<pipeline slug>` with the slug of the pipeline you want to sign
- `<pipeline slug>` with the slug of the pipeline you want to sign.

This will download the pipeline definition using the Buildkite GraphQL API, sign all steps, and upload the signed pipeline definition back to Buildkite.

Expand All @@ -141,7 +146,8 @@ Because signed pipelines use JWKS as their key format, rotating keys is easy.

To rotate your keys:

1. Generate a new key pair.
1. [Generate a new key pair](#enabling-signed-pipelines-on-your-agents-1-generate-a-key-pair).
1. Add the new keys to your existing key sets. Be careful not to mix public and private keys.
1. Update the `signing-key-id` on your signing agents to use the new key ID.

Once the updated key sets are in place, you can update the `signing-key-id` on your signing agents to use the new key ID. Verifying agents will automatically use the public key with the matching key ID, if it's present.
The verifying agents will automatically use the public key with the matching key ID, if it's present.

0 comments on commit 928451c

Please sign in to comment.