---
title: "Automating Cerbos Policy deployments with Azure DevOps Pipelines"
description: "This guide shows you how to set up an Azure DevOps Pipeline to upload your Cerbos policies to a Cerbos Hub store automatically."
author: "Alex Olivier"
date: "2026-07-08T10:36:00.000Z"
canonical: "https://www.cerbos.dev/blog/automating-cerbos-policy-deployments-with-azure-devops-pipelines"
image: "https://stylish-appliance-1c1cc1c30d.media.strapiapp.com/Automating_Cerbos_Policy_deployments_with_Azure_Dev_Ops_Pipelines_25c72a2fb6.png"
tags: ["documentation"]
source: "https://www.cerbos.dev/blog/automating-cerbos-policy-deployments-with-azure-devops-pipelines"
---

# Automating Cerbos Policy deployments with Azure DevOps Pipelines

This guide shows you how to set up an Azure DevOps Pipeline 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 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

- An Azure DevOps organization and a Project.
- Your policies is hosted in a repository (either Azure Repos or linked from GitHub, Bitbucket).
- 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: Create the Pipeline YAML File
. In the root directory of your repository, create a new file named `azure-pipelines.yml`.
. Copy and paste the following code into the file. This code defines the trigger, the agent environment, and the steps to run.
. 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
----
# azure-pipelines.yml
trigger:
  branches:
    include:
      - main # This pipeline runs on pushes to the main branch

pool:
  vmImage: 'ubuntu-latest' # Use a Microsoft-hosted Linux agent

jobs:
- job: UploadCerbosPolicies
  displayName: 'Upload Cerbos Policies'
  steps:
    # Step 1: Check out the source code from the repository
    - checkout: self

    # Step 2: Run the docker command to upload policies
    - script: |
        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 "$(System.DefaultWorkingDirectory)":/app \
          ghcr.io/cerbos/cerbosctl:latest \
          hub store replace-files /app --message="Policy upload from Azure DevOps"
      displayName: 'Upload Policies to Cerbos Hub'
      env:
        # Map the secret variables created in the UI to environment variables for this script
        CERBOS_HUB_CLIENT_ID: $(CERBOS_HUB_CLIENT_ID)
        CERBOS_HUB_CLIENT_SECRET: $(CERBOS_HUB_CLIENT_SECRET)
```

**Key Azure DevOps Concepts Used:**

- `trigger`: Defines when the pipeline runs, equivalent to `on:` in GitHub Actions.
- `pool`: Specifies the type of build agent to use, equivalent to `runs-on`.
- `job` and `steps`: Structure the work to be done.
- `checkout: self`: The task to get your source code.
- `script`: A simple task to run a shell script.
- `$(System.DefaultWorkingDirectory)`: The predefined variable for the checkout directory, like `$PWD` or `$CI_PROJECT_DIR`.
- `env:`: The section where you map pipeline variables to environment variables for the script, note the `$(VariableName)` syntax.

## Step 2: Create the Pipeline in Azure DevOps
- Go to your Azure DevOps project. In the left sidebar, click on *Pipelines*.
- Click the *New pipeline* button (or *Create pipeline* if it is your first one).
- *Where is your code?* Select the correct location, for example, *Azure Repos Git*, *GitHub*. You may need to authorize access.
- *Select a repository:* Choose the repository where you just added the `azure-pipelines.yml` file.
- *Configure your pipeline:* Azure DevOps detects your YAML file. Select *Existing Azure Pipelines YAML file*.
- Select the branch, for example, `main` and the path, `/azure-pipelines.yml`, then click *Continue*.

## Step 3: Add Your Secrets
- You now see the YAML file in the pipeline editor view. *Do not run it yet.*
- In the top right corner, click the *Variables* button.
- Click *New variable*
-- Name: `CERBOS_HUB_CLIENT_ID`
-- Value: Paste your client ID.
-  Check the box for *Keep this value secret*.
- Click *OK*.
- Click *New variable* again.
-- Name: `CERBOS_HUB_CLIENT_SECRET`
-- Value: Paste your client secret.
- Check the box for *Keep this value secret*.
- Click *OK*.
- Click the *Save* button at the bottom of the variables pane.

## Step 4: Save and Run the Pipeline
- Now that the secrets are saved, click the *Save and run* button, or just *Run*, in the top right corner.
- Confirm the branch and commit message, and click *Save and run* again.

## Step 5: Verify the Run
- You are taken to the pipeline run summary page.
- Click on the `Upload Cerbos Policies` job to see the live logs.
- If everything is configured correctly, all steps complete with a green checkmark, and your policies are uploaded to Cerbos Hub.

## 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), [Buildkite](https://www.cerbos.dev/blog/automating-cerbos-policy-deployments-with-buildkite) and [GitHub Actions](https://www.cerbos.dev/blog/automating-cerbos-policy-deployments-with-github-actions).

## 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 Azure DevOps?

You upload Cerbos policies from Azure DevOps by adding an azure-pipelines.yml file to your repository, creating a pipeline in Azure DevOps that points at it, and adding your Cerbos Hub credentials as pipeline secrets. The pipeline runs the cerbosctl container on pushes to your main branch and replaces the policy files in your store.

### What credentials does an Azure DevOps pipeline need to push policies to a Cerbos Hub store?

An Azure DevOps pipeline needs your Cerbos Hub store ID plus a client ID and client secret. Create the credentials in the Client credentials section of your store in Cerbos Hub with Read and Write selected, then add them as secret pipeline variables so the values are masked in the run logs.

### Why does setting up Cerbos policy uploads in Azure DevOps take an extra step?

Azure DevOps takes one more step than most CI services because committing the YAML file does not create the pipeline. You add azure-pipelines.yml to the repository, then create the pipeline in Azure DevOps and point it at that file before any run happens. On GitHub Actions or CircleCI the config file alone is enough.

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

Yes, run the tests in an earlier stage of the same pipeline. Cerbos test suites sit alongside your policies and are discovered automatically by cerbos compile, so a failing test stops the run before a broken policy reaches your decision points.

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

Open the Pipelines section in Azure DevOps and select the most recent run. Each job shows a pass or fail state with its log. Failures usually come from client credentials created without Read and Write permission, a store ID that does not match the one in Cerbos Hub, or secret variables that were not made available to the job.
