---
title: "Automating Cerbos Policy deployments with Buildkite"
description: "This guide will help you set up a CI/CD pipeline in Buildkite to upload your Cerbos policies to a Cerbos Hub store automatically."
author: "Alex Olivier"
date: "2026-07-07T10:32:00.000Z"
canonical: "https://www.cerbos.dev/blog/automating-cerbos-policy-deployments-with-buildkite"
image: "https://stylish-appliance-1c1cc1c30d.media.strapiapp.com/Automating_Cerbos_Policy_deployments_with_Buildkite_6b767d3fb8.png"
tags: ["documentation"]
source: "https://www.cerbos.dev/blog/automating-cerbos-policy-deployments-with-buildkite"
---

# Automating Cerbos Policy deployments with Buildkite

This guide will help you set up a CI/CD pipeline in Buildkite to automatically upload your Cerbos policies to a [Cerbos Hub store](https://docs.cerbos.dev/cerbos-hub/policy-stores.html) whenever you push changes to the `main` branch of your Git repository.

> **Note:** Cerbos Hub can also [connect a repository](https://docs.cerbos.dev/cerbos-hub/policy-stores-git-github.html) to a store directly if you are on GitHub. The pipeline below is what you want on any other CI service, or when you need control over exactly which commits trigger an upload.

## Prerequisites
* A Buildkite account and a configured "Pipeline".
* Your own "agent" running on a machine that has Docker installed.
* The ID of your Cerbos Hub store, which you can find in the store section of the Cerbos Hub.
* Your `CERBOS_HUB_CLIENT_ID` and `CERBOS_HUB_CLIENT_SECRET` values generated in the **Client credentials** section of the Cerbos Hub store. Make sure to select the `Read & Write` option when creating the credentials to allow uploading policies.
* * Nothing needs installing on the runner. The upload runs the [cerbosctl CLI](https://docs.cerbos.dev/cerbos-hub/policy-stores-cli-binary.html) inside a container.

## Step 1: Configure Secrets on Your Agent Machine
Buildkite agents pull secrets from their environment. The simplest way is to define them directly on the agent machine.

1. Log into the server where your Buildkite agent is running.
2. Add your secrets to a system-wide environment file, like `/etc/environment`. Open it with a text editor (e.g., `sudo nano /etc/environment`) and add these lines:

```bash
CERBOS_HUB_CLIENT_ID="your-client-id-here"
CERBOS_HUB_CLIENT_SECRET="your-client-secret-here"
```
3. Save the file and **restart your Buildkite agent service** for the changes to take effect (e.g., `sudo systemctl restart buildkite-agent`).

## Step 2: Create the Pipeline File
1. In your repository, create a directory named `.buildkite`.
2. Inside `.buildkite`, create a file named `pipeline.yml`.
3. Copy and paste the following code into it:
4. Replace `[STORE_ID]` with the ID of your Cerbos Hub store. You can find this in the Cerbos Hub UI under the store settings.

```yaml
# .buildkite/pipeline.yml
steps:
  - command: |
      docker run --rm \
        -e CERBOS_HUB_STORE_ID="[STORE_ID]" \
        -e CERBOS_HUB_CLIENT_ID=$CERBOS_HUB_CLIENT_ID \
        -e CERBOS_HUB_CLIENT_SECRET=$CERBOS_HUB_CLIENT_SECRET \
        -v "$PWD":/app \
        ghcr.io/cerbos/cerbosctl:latest \
        hub store replace-files /app --message="Policy upload from Buildkite"
    
    if: build.branch == 'main'
    label: "Upload Cerbos Policies"
```

## Step 3: Commit and Push
1. Commit the `.buildkite/pipeline.yml` file.
2. Push your changes to the `main` branch.

## Step 4: Verify the Run
1. Go to your pipeline in the Buildkite dashboard.
2. A new build will be triggered. Click on it to watch the "Upload Cerbos Policies" step execute on your agent.

## Next steps

Add your policy tests to the same workflow so a broken policy never reaches the store. Cerbos test suites live alongside your policies and `cerbos compile` [finds them automatically](https://docs.cerbos.dev/cerbos/latest/policies/compile.html#_testing), so a failing test stops the run before the upload step.

If you are still working out what the policies themselves should say, [mapping business requirements](https://www.cerbos.dev/blog/mapping-business-requirements-to-authorization-policy) covers that groundwork, and [GitOps makes the case](https://www.cerbos.dev/blog/why-using-gitops-for-authorization-and-access-control-is-a-good-idea) for keeping policies in version control to begin with.

PS. Here is the same setup for [GitLab Runners](https://www.cerbos.dev/blog/automating-cerbos-policy-deployments-with-gitlab-runners), [CircleCI](https://www.cerbos.dev/blog/automating-cerbos-policy-deployments-with-circleci), [Bitbucket Pipelines](https://www.cerbos.dev/blog/automating-cerbos-policy-deployments-with-bitbucket-pipelines), [GitHub Actions](https://www.cerbos.dev/blog/automating-cerbos-policy-deployments-with-github-actions) and [Azure DevOps](https://www.cerbos.dev/blog/automating-cerbos-policy-deployments-with-azure-devops-pipelines).

## Wrapping up

Go to [Cerbos Hub](https://hub.cerbos.cloud/) to create a policy store and connect this pipeline to it, or [book a free session](https://www.cerbos.dev/workshop) if you'd like to consult with our team.

## FAQ

### How do I automatically upload Cerbos policies to Cerbos Hub from Buildkite?

You upload Cerbos policies from Buildkite by adding a .buildkite/pipeline.yml file with a step that runs the cerbosctl container against your Cerbos Hub store. Unlike hosted CI services, Buildkite runs on your own agents, so the credentials are configured on the agent machine rather than in a web UI.

### Where do Cerbos Hub credentials go when using Buildkite?

Cerbos Hub credentials go on the Buildkite agent machine itself, because Buildkite agents are self-hosted. Set CERBOS_HUB_CLIENT_ID and CERBOS_HUB_CLIENT_SECRET in the agent environment rather than committing them to the pipeline file. This is the main difference between Buildkite and hosted services like CircleCI or GitHub Actions, where secrets live in the provider's settings UI.

### What permissions do Cerbos Hub client credentials need for a Buildkite upload?

Cerbos Hub client credentials used by Buildkite need the Read and Write option selected when they are created in the Client credentials section of your policy store. Read-only credentials will authenticate but the upload step will fail, which is one of the more common causes of a failed policy deployment.

### Should Cerbos policy tests run before uploading to Cerbos Hub from Buildkite?

Yes, add a test step ahead of the upload step in your pipeline. Cerbos test suites live alongside your policies and cerbos compile picks them up automatically, so a failing test can stop the build before a broken policy reaches your decision points.

### Where do I check whether a Cerbos policy upload from Buildkite succeeded?

Open the pipeline in your Buildkite dashboard and select the most recent build. The upload step shows its status and full log output. Failures on self-hosted agents most often trace back to environment variables that were never set on the agent, or an agent without Docker available to run the cerbosctl container.
