> For the complete documentation index, see [llms.txt](https://docs.nullify.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nullify.ai/connectors/buildkite/configuration.md).

# Configuration

Connecting Buildkite takes about five minutes and three things: a Buildkite API token, your organization slug, and a one-time GitHub permission acknowledgement. This guide walks through all three — plus an optional step for organizations that restrict who can trigger builds.

## Step 1: Create a Buildkite API token

We recommend minting the token from a **dedicated service-account user** rather than a personal account — see the [callout in the overview](/connectors/buildkite.md) for why. Log in to Buildkite **as that user**, then:

1. Go to **Personal Settings → API Access Tokens** (`https://buildkite.com/user/api-access-tokens`).
2. Click **New API Access Token**.
3. Give it a recognizable name, e.g. `nullify-ci-feedback`.
4. Scope it to the **single organization** Nullify should see.
5. Enable **only** these two scopes — nothing else:
   * `read_builds`
   * `read_build_logs`
6. Click **Create Token** and copy the value. Buildkite API tokens are in the form `bkua_…`.

{% hint style="warning" %}
The token is shown **only once**. Copy it before you leave the page — if you lose it, you'll need to create a new one.
{% endhint %}

{% hint style="info" %}
**Least privilege.** Nullify only ever *reads* build status and logs, so it needs nothing beyond `read_builds` and `read_build_logs`. Don't grant write, agent, pipeline-management, or token-management scopes.
{% endhint %}

## Step 2: Connect Buildkite in Nullify

1. In the Nullify dashboard, go to **Configure → Connectors**.
2. Find the **Buildkite** card and click **Connect Buildkite**.
3. Fill in the two fields:
   * **Organization slug** — the identifier from your Buildkite URL, `buildkite.com/<org-slug>`. It's lowercase letters, numbers, and hyphens (e.g. `my-org`).
   * **API token** — paste the `bkua_…` token from Step 1.
4. Click **Save**.

The Buildkite card now shows **Active** with your organization name, and unlocks **Autofix CI Feedback**.

{% hint style="info" %}
**"Active" means saved, not yet proven.** Nullify checks the *format* of the token and slug when you save, but it confirms the credentials actually work the first time it reads a real build. Run the end-to-end check in [Step 6](#step-6-verify) to be sure everything is wired up.
{% endhint %}

## Step 3: Make sure Buildkite reports to GitHub

Nullify learns about your builds through the commit status Buildkite posts to GitHub. If that status isn't being published, Nullify has nothing to react to.

1. In Buildkite, go to **Organization Settings → Repository Providers → GitHub**.
2. Confirm the **Buildkite GitHub App** is installed (not the legacy OAuth integration).
3. In each relevant **pipeline's settings**, confirm **Publish commit statuses** (under GitHub settings) is enabled.

You can sanity-check this independently of Nullify: open any recent pull request that triggered a build and confirm a `buildkite/…` status check appears on it.

## Step 4: Acknowledge the GitHub App permission <a href="#github-app-permissions" id="github-app-permissions"></a>

To receive those commit-status events, Nullify's GitHub App needs two things:

* **Repository permission:** *Commit statuses* → **Read-only**.
* **Event subscription:** the **Status** event.

These are already configured on the Nullify GitHub App. The only action on your side is a one-time acknowledgement: GitHub asks each organization owner to **accept the updated permissions**, shown as an email and a banner on your organization's installed-apps page.

{% hint style="warning" %}
Until your organization owner accepts the updated permission, GitHub won't send build-status events to Nullify — so the autofix loop won't see your Buildkite results, even though the connector shows **Active**.
{% endhint %}

## Step 5: Let Nullify's commits trigger builds <a href="#build-creator-access" id="build-creator-access"></a>

**Skip this step unless your Buildkite organization restricts who can trigger builds.** Some orgs gate builds by the creator's team — for example an agent `environment` hook or a pipeline conditional that checks [`BUILDKITE_BUILD_CREATOR_TEAMS`](https://buildkite.com/docs/pipelines/configure/environment-variables) (or `build.creator.teams`) and fails any build whose creator isn't on an allowed team. If your org runs every push regardless of who created it, jump to [Step 6](#step-6-verify).

When Nullify opens an autofix pull request, the commit is authored by Nullify's GitHub App, using the email `<id>+nullify[bot]@users.noreply.github.com`. Buildkite maps that commit author to a Buildkite user by email and fills `BUILDKITE_BUILD_CREATOR_TEAMS` from that user's teams. So in a gated org, Nullify's Buildkite user must exist in your org and sit on an allowed team — otherwise the build is blocked before it starts, no commit status is posted, and the autofix loop never sees your CI (even though the connector shows **Active**).

1. **Invite the Nullify user.** Invite `integrations-bot@nullify.ai` to your Buildkite organization. It is a Buildkite-managed service account, like Dependabot or Renovate: it auto-accepts the invite, skips billing, and cannot log in.
2. **Add it to an allowed, non-private team.** Put the user on the team(s) your build-creator gate accepts. The team must be **non-private** — `BUILDKITE_BUILD_CREATOR_TEAMS` only lists non-private team slugs, so membership of a private team won't satisfy the check.

{% hint style="info" %}
The gate matches on the commit's **author email**, which Buildkite treats as unverified — Nullify's commits do **not** need to be GPG-signed for this to work. (This is also why the account is associated with the `…+nullify[bot]@users.noreply.github.com` address rather than a regular mailbox.) This Buildkite user is **separate** from the API-token service account in Step 1: the token account authenticates Nullify's log reads; this user lets Nullify's commits run a build.
{% endhint %}

## Step 6: Verify <a href="#step-6-verify" id="step-6-verify"></a>

End-to-end, the simplest way to confirm everything works:

1. Push a commit to an open pull request so Buildkite runs a build.
2. Confirm the `buildkite/…` status appears on the GitHub PR (this proves Steps 3–4).
3. If a build fails on a Nullify autofix PR, watch Nullify pick up the failure and push a follow-up commit — that confirms log fetching and iteration are working.

## Troubleshooting

| Symptom                                                                      | Likely cause and fix                                                                                                                                                           |
| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Autofix PR opened, but Buildkite never runs a build** on Nullify's commits | Your org gates build creators by team, and Nullify's Buildkite user isn't invited, isn't on an allowed team, or is on a **private** team. See [Step 5](#build-creator-access). |
| Connector saved but autofix never reacts to Buildkite failures               | The GitHub permission acknowledgement (Step 4) is still pending, or commit statuses aren't being published (Step 3). Check both.                                               |
| **No `buildkite/…` status on the GitHub PR**                                 | The Buildkite GitHub App isn't installed, or the pipeline doesn't have **Publish commit statuses** enabled. See Step 3.                                                        |
| Builds are detected but **logs aren't fetched**                              | The token is missing the `read_build_logs` scope, or it was created in the wrong organization. Re-check Step 1 and rotate the token if needed.                                 |
| **Status shows Active but nothing happens**                                  | "Active" only means the token and slug were saved. Verify the token is valid and scoped to the right org by running the check in Step 5.                                       |
| Token was created by someone who has since left                              | The token stops working when their account is deactivated. Re-mint it from a dedicated service-account user (see the overview) and update it in Step 2.                        |

## Rotating the token

1. Create a new token in Buildkite (Step 1) — from the same service-account user.
2. In Nullify, go to **Configure → Connectors → Buildkite → Update** and paste the new token.
3. Revoke the old token in Buildkite.

There's no downtime: Nullify uses the new token as soon as you save it.

## Removing the integration

1. Go to **Configure → Connectors → Buildkite**.
2. Click **Delete**.

This removes your stored token and organization slug from Nullify. Your Buildkite pipelines are untouched and keep running exactly as before — disconnecting only stops Nullify from reading build status and logs.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.nullify.ai/connectors/buildkite/configuration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
