diff --git a/pages/agent/v3/signed_pipelines.md b/pages/agent/v3/signed_pipelines.md index 8721f9083a..b11603cdb5 100644 --- a/pages/agent/v3/signed_pipelines.md +++ b/pages/agent/v3/signed_pipelines.md @@ -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. @@ -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 @@ -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 --key-id @@ -55,7 +57,7 @@ Replacing the following: - `` with the signing algorithm you want to use. - `` 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 @@ -111,13 +113,14 @@ verification-jwks-file= ### 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 \ --jwks-file \ @@ -126,12 +129,14 @@ buildkite-agent tool sign \ --pipeline-slug \ --update ``` -making the following replacements: + +Replacing the following: + - `` with a Buildkite GraphQL token that has the `write_pipelines` scope. - `` with the path to the private keyset you generated earlier. -- `` with the key ID from earlier +- `` with the key ID from earlier. - `` with the slug of the organization the pipeline is in. -- `` with the slug of the pipeline you want to sign +- `` 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. @@ -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.