Incoming webhooks

Incoming webhooks are sent to Buildkite by source control providers (GitHub, GitLab, Bitbucket, etc.) to trigger builds. This page answers the most frequent questions about the security of incoming webhooks in Buildkite.

What kind of information on incoming webhooks is logged by Buildkite?

Buildkite only logs and temporarily stores the incoming webhook information as it was received, the relevant HTTP headers, and the remote IP for diagnostics purposes. This information is soon erased and cannot be used for audit.

How long does Buildkite store the information on incoming webhooks?

Buildkite stores the information on recent incoming webhooks received per pipeline for approximately one week. It is used for troubleshooting purposes only — for example, to diagnose why a given hook didn't trigger a build. This functionality is not exposed in the UI.

What security information is stored in the secret in a Buildkite URL?

Secrets are pipeline-specific. A secret can't prove that it hasn't been acquired by somebody else and added as a webhook inside their own GitHub repository (which is equally true of any other secret). However, all incoming webhooks from GitHub-hosted repositories are IP-filtered to provide an additional layer of security. As a Buildkite user, you can set up a pipeline and request a URL to add it to your GitHub organization as a webhook, proving it comes from your GitHub organization.

IP filtering is available for:

  • GitHub
  • GitHub Enterprise Server
  • Bitbucket Server (not Bitbucket Cloud)
  • GitLab Community
  • GitLab Enterprise

For GitHub's cloud-hosted products, Buildkite manages a set of IP addresses and filters them automatically. For self-hosted solutions like GitHub Enterprise Server, you can provide the IP addresses to filter.

To enable IP filtering for these repository providers:

  1. Navigate to the Repository providers in your organization's settings.
  2. Enter the allowed IP addresses.

How do I access the webhook that triggered a build?

There are two ways to do it:

  • To view the webhook that triggered the build, go to the build page and add "/webhook" at the end of its URL - for example https://buildkite.com/rails/rails/builds/*****/webhook
  • To find the actual payload of a webhook that triggered a build, use the following GraphQL snippet:
query FindWebhookPayload {
  build(uuid: "...") {
    source {
      ...on BuildSourceWebhook {
        headers
        payload
      }
    }
  }
}

Would adding a separate secret per webhook make it more secure?

The webhook URL already contains a secret value, so a second secret field is redundant and doesn't increase security.

Is it possible to ensure that Buildkite is only getting incoming webhooks from my GitHub organization? Can this be specifically set up on Buildkite's side?

The secret verifies that Buildkite receives webhooks from an organization with sufficient Buildkite rights — meaning that it is able to obtain the secret webhook URL, which Buildkite treats as equivalent to coming from your GitHub organization. By definition, anyone with that level of access could change any other security setting in your Buildkite organization.

The webhook secret is generated by Buildkite, per pipeline. The only thing a webhook can do is cause a start of a build of a commit that already exists in the pipeline's configured repository, using the pipeline's configured set of build steps.

Can I (re)issue a webhook secret using the Buildkite UI?

You can ask Buildkite support to create a new webhook secret for you. In case of an emergency, you could modify the existing pipeline to make it unbuildable and replace it with a new one, with a new webhook secret.