# Access policies for Buildkite secrets

Access policies for Buildkite secrets:

- Control access to [Buildkite secrets](/docs/pipelines/security/secrets/buildkite-secrets) based on build attributes. Policies are written in YAML and configured through the Buildkite interface.

- Restrict access to Buildkite secrets based on build context. You can specify conditions such as the branch, pipeline, or user who triggered the build.

During a build, the policy is evaluated against the build's context. If any of the rules of the policy match, access to the secret is granted. If none of the rules of the policy match, access to the secret is denied.

## Policy schema

Policies are defined as a list of policy rules in YAML. Each _policy rule_ (beginning with a `-`) specifies one or more _claims_, all of which must be met for a build to access the Buildkite secret.

Each claim must specify one or more _conditions_. Conditions can be a single item or a list of strings. When a list of condition strings is provided on a claim, at least one of these string values must match for the claim to be met.

**A single _condition_ on each _claim_ within a _policy rule_:**

```
# All claims must be met. The build must be from the "frontend-pipeline" pipeline and built on the "main" branch.
- pipeline_slug: "frontend-pipeline"     # Claim 1 with a single condition
  build_branch: "main"                   # Claim 2 with a single condition
```

**Multiple _conditions_ on each _claim_ within a _policy rule_:**

This policy will grant access to builds running in the `frontend-pipeline` and the `backend-pipeline` running on either the `main` or `develop` branch.

```
# This rule grants access if:
# - The pipeline is EITHER "frontend-pipeline" OR "backend-pipeline"
#   AND
# - The branch is EITHER "main" OR "develop"
- pipeline_slug:                        # Claim 1 with two conditions
    - "frontend-pipeline"
    - "backend-pipeline"
  build_branch:                         # Claim 1 with two conditions
    - "main"
    - "develop"
```

**Multiple _policy rules_:**

This policy will grant access to builds in the `frontend-pipeline` running on the `main` branch, and will grant access to builds in the `backend-pipeline` running on the `develop` branch. It will not grant access to builds running in the `frontend-pipeline` on the `develop` branch.

```
# This rule grants access if:
# - The pipeline is "frontend-pipeline"
#   AND
# - The branch is "main"
- pipeline_slug: "frontend-pipeline"
  build_branch: "main"

# This rule grants access if:
# - The pipeline is "backend-pipeline"
#   AND
# - The branch is "develop"
- pipeline_slug: "backend-pipeline"
  build_branch: "develop"
```

### First-party claims

First-party claims are ones whose values are generated by Buildkite. This makes these claims more secure than [third-party claims](#policy-schema-third-party-claims).



| `pipeline_id` | The unique identifier of the build pipeline. _Example:_ `pipeline_id: ""f47ac10b-58cc-4372-a567-0e02b2c3d479""` |
| --- | --- |
| `build_source` | The source of the build trigger (e.g., webhook, API). _Example:_ `build_source: "webhook"` |
| `cluster_queue_id` | The unique identifier of the cluster's queue where the job is running. _Example:_ `cluster_queue_id: "01928e5a-1234-5678-9abc-def0123456789"` |



### Third-party claims

Third-party claims are ones whose values are provided by users or third-party tools. While these claims can be useful for controlling access, they are not as secure as [first-party claims](#policy-schema-first-party-claims), which are generated by the Buildkite platform.



| `cluster_queue_key` | The key of the cluster's queue where the job is running. _Example:_ `cluster_queue_key: "default"` |
| --- | --- |
| `pipeline_slug` | The slug of the build pipeline. _Example:_ `pipeline_slug: "my-pipeline"` |
| `build_branch` | The branch being built. _Example:_ `build_branch: "main"` |
| `build_creator` | The email of the user who triggered the build. _Example:_ `build_creator: "user@example.com"` |
| `build_creator_team` | The UUIDs of the teams the build creator belongs to. _Example:_ `build_creator_team: "123e4567-e89b-12d3-a456-426614174000"` |



### Example access policy

The following example access policy contains three rules with different levels of access control. Access to the secret is granted if the build matches all conditions in *any one of these rules*.

```yaml
# This rule grants access if the build matches all five claims and their conditions.
- pipeline_slug: "my-pipeline"
  build_branch: "main"
  build_creator: "user@example.com"
  build_source: "webhook"
  build_creator_team: "123e4567-e89b-12d3-a456-426614174000"

# This rule grants access if:
# - pipeline_slug is "frontend-pipeline" OR "backend-pipeline"
# AND
# - build_branch is either "main" OR "develop"
- pipeline_slug:
    - "frontend-pipeline"
    - "backend-pipeline"
  build_branch:
    - "main"
    - "develop"

# This rule grants access if:
# - pipeline_slug is "public-pipeline"
# AND
# - build_branch is "main" or "release"
# AND
# - build_creator is "admin@example.com" or "deployer@example.com"
- pipeline_slug: "public-pipeline"
  build_branch:
    - "main"
    - "release"
  build_creator:
    - "admin@example.com"
    - "deployer@example.com"

# This rule grants access if:
# - build_branch is "main"
# AND
# - cluster_queue_key is "deploy"
- build_branch: "main"
  cluster_queue_key: "deploy"
```

### Use case examples

Access policies can be tailored to fit a wide range of security and workflow requirements. Here are some practical examples of rules to help you get started.

#### Restrict secret access to the main branch of a pipeline

```yaml
- pipeline_slug: "my-pipeline"
  build_branch: "main"
```

#### Restrict secret access to only Github merge queue builds

```yaml
- pipeline_slug: "my-pipeline"
  build_branch: "gh-readonly-queue/*"
```

#### Only allow a chosen team to deploy from the main branch

```yaml
- build_branch: "main"
  build_creator_team: "e2b7c3f4-1a5d-4e6b-9c8d-2f3a4b5c6d7e"
```

#### Restrict secret access to jobs running on a specific queue of the cluster

```yaml
- cluster_queue_key: "production"
```

#### Restrict secret access to jobs running on specific queues by the queue ID

```yaml
- cluster_queue_id:
    - "01928e5a-1234-5678-9abc-def0123456789"
    - "01928e5a-5678-9abc-1234-def0123456789"
```

## Add an access policy

A Buildkite secret's access policy can only be added (and modified) by [cluster maintainers](/docs/pipelines/security/clusters/manage#manage-maintainers-on-a-cluster), as well as [Buildkite organization administrators](/docs/pipelines/security/permissions#manage-teams-and-permissions-organization-level-permissions).

1. Select **Agents** in the global navigation to access the **Clusters** page.
1. Select the cluster in which to create the new Buildkite secret.
1. Select the secret you want to secure with an access policy.
1. Select the secret's **Access** tab.
1. In the **Agent access** section, select **Restrict access to agents matching a policy**.
1. Add your policy to the **Policy** field in YAML format.
1. Select **Update agent access** to save your changes.
