---
title: Buildkite integration
description: How to configure Buildkite to use Chinmina
---
There are two broad ways that Chinmina Bridge can be integrated with
Buildkite pipelines:

1. **Git authentication**: This allows Buildkite pipelines to authenticate with
   GitHub using a token that is scoped to the pipeline, and can be used to
   access private repositories.

2. **Token generation**: This allows Buildkite pipelines to generate a GitHub
   token that can be used to access private repositories, such as downloading
   private release assets. Tokens can be exported automatically as environment
   variables or retrieved programmatically via a helper script.

Git authentication integration removes the need to configure SSH deploy keys for
each repository, and token generation is a replacement for long-lived GitHub
Personal Access Tokens (PATs) stored in secrets.

Each use case is integrated using a Buildkite plugin:

* [Chinmina Git Credentials][credentials-plugin]: configures a Git credentials
  helper that uses Chinmina Bridge to authenticate with GitHub.
* [Chinmina Token][chinmina-token]: Retrieves GitHub tokens from Chinmina Bridge,
  either by automatically exporting them as environment variables or by adding a
  `chinmina_token` helper script for dynamic token retrieval.

> \[!CAUTION]
>
> Recommended setup
>
> The plugins *can* be configured in individual pipeline steps, but production
> installations should load the plugins in the Buildkite agent `bootstrap` and
> `environment` hooks.
>
> This configuration ensures that Chinmina is integrated into all pipelines that run on
> the agent, without the need for further configuration. See "[Enabling on the
> agent](#enabling-on-the-agent-for-all-pipelines)" for setup instructions.
>
> This is the only practical way to use Chinmina Bridge for Git authentication in
> particular.

## Configuration

Full documentation for each plugin:

* [Chinmina Git Credentials][credentials-plugin]
* [Chinmina Token][chinmina-token]

Collect the following information from your Chinmina Bridge instance:

1. The URL of the Chinmina Bridge instance, e.g. `https://chinmina-bridge.your-organization.io`.
2. The audience for the OIDC token, e.g. `chinmina:your-github-organization`.

**If the audience doesn't match the value expected by Chinmina Bridge, all requests will fail.**

### Organization-wide defaults

Both plugins support `CHINMINA_DEFAULT_URL` and `CHINMINA_DEFAULT_AUDIENCE` environment variables. Set these at the agent level to provide defaults for all pipelines, eliminating repetitive configuration.

Configuration precedence (highest to lowest):

1. Plugin parameters in pipeline configuration
2. `CHINMINA_DEFAULT_*` environment variables
3. Built-in defaults (audience only)

This allows setting defaults once while permitting per-pipeline overrides when needed.

### Prerequisites

1. If `openssl` is present on the agent, both plugins will use it to encrypt a
   cached OIDC token, speeding up successive token requests in the same job.
2. The `chinmina-token` plugin requires `jq` to be installed on the Buildkite
   agent.

## Using tokens in pipelines

The examples below assume agent-level defaults are configured (see "[Enabling
on the agent](#enabling-on-the-agent-for-all-pipelines)"). The `chinmina-url`
and `audience` parameters can be included to override defaults when needed.

### Environment mode (declarative)

The simplest way to use tokens is via the `environment` parameter, which
automatically exports tokens as environment variables. This is the recommended
approach for most use cases.

```yml
steps:
  - label: "Deploy to production"
    command: |
      # GITHUB_TOKEN is automatically available
      gh release download --repo myorg/myrepo --pattern "*.zip"
    plugins:
      # Using default URL and audience from agent environment
      - chinmina/chinmina-token#v1.4.0:
          environment:
            - GITHUB_TOKEN=pipeline:default
```

> \[!TIP]
>
> Tokens retrieved from Chinmina Bridge are automatically redacted from build logs.

#### Multiple tokens

For workflows requiring multiple tokens (e.g., accessing different profiles or repositories):

```yml
steps:
  - label: "Build with private dependencies"
    command: |
      # Multiple tokens available for different purposes
      npm config set //npm.pkg.github.com/:_authToken "$GITHUB_NPM_TOKEN"
      npm install

      # Deploy using different token with elevated permissions
      gh release create --repo myorg/releases "$VERSION"
    plugins:
      # Using default URL and audience from agent environment
      - chinmina/chinmina-token#v1.4.0:
          environment:
            - GITHUB_TOKEN=pipeline:release # pipeline profile
            - GITHUB_NPM_TOKEN=org:npm-packages # organization profile
```

Profile prefixes (`pipeline:`, `org:`) identify the profile type for the plugin. Pipeline profiles (`pipeline:`) grant permissions to the pipeline's repository, while organization profiles (`org:`) grant access to specific repositories across the organization.

### Library mode (dynamic)

For dynamic token selection or complex scripting scenarios, use the
`chinmina_token` helper script directly. When the plugin is configured without
an `environment` parameter, it adds the `chinmina_token` script to PATH.

```yml
steps:
  - plugins:
      # Using default URL and audience from agent environment
      - chinmina/chinmina-token#v1.4.0: {}
```

Then in your scripts:

```bash
# Dynamically select profile based on environment
if [[ "$ENVIRONMENT" == "production" ]]; then
  export GITHUB_TOKEN=$(chinmina_token "org:prod-profile")
else
  export GITHUB_TOKEN=$(chinmina_token "org:staging-profile")
fi

# Get a token for pipeline repository with elevated permissions
export GITHUB_TOKEN=$(chinmina_token "pipeline:release")

# Or get a token with default pipeline permissions
export GITHUB_TOKEN=$(chinmina_token "pipeline:default")

# Use with gh CLI
gh release download --repo "${repo}" \
  --pattern "release-file-${arch}.zip" \
  --dir "${directory}" \
  "${tag}"
```

#### When to use each approach

| Use Case                                 | Recommended Approach              |
| ---------------------------------------- | --------------------------------- |
| Static token needs known upfront         | `environment` array (declarative) |
| Multiple tokens for different services   | `environment` array               |
| Dynamic profile selection                | `chinmina_token` script           |
| Conditional token logic                  | `chinmina_token` script           |
| Token needed only in specific conditions | `chinmina_token` script           |

## Using Git credentials for authentication

The [Chinmina Git Credentials][credentials-plugin] plugin enables Git operations
to authenticate with GitHub using tokens from Chinmina Bridge.

```yml
steps:
  - command: git clone https://github.com/myorg/private-repo.git
    plugins:
      # Using default URL and audience from agent environment
      - chinmina/chinmina-git-credentials#v1.6.0: {}
```

> \[!TIP]
>
> Each Buildkite pipeline needs to be configured with an **HTTPS Git URL** in the
> Buildkite pipeline settings.
>
> Alternatively, the `BUILDKITE_REPO` value can be overridden in the agent
> `environment` hook to use an HTTPS URL instead of the SSH form.
>
> **If SSH is configured, Git will ignore the credential helper.**

### Using profiles with Git credentials

The Git credentials plugin supports using profiles to access repositories with specific permissions or to access additional repositories beyond the pipeline's own repository:

```yml
steps:
  - command: git clone https://github.com/myorg/shared-repo.git
    plugins:
      # Using default URL and audience from agent environment
      - chinmina/chinmina-git-credentials#v1.6.0:
          profile: org:shared-plugins
```

### Exclusive credential helper mode

By default, the Git credentials plugin adds the Chinmina credential helper alongside any existing system or global Git credential helpers. The `exclusive` flag clears all previously configured credential helpers for GitHub, ensuring only Chinmina is used.

```yml
steps:
  - command: git clone https://github.com/myorg/private-repo.git
    plugins:
      # Using default URL and audience from agent environment
      - chinmina/chinmina-git-credentials#v1.6.0:
          profile: org:shared-plugins
          exclusive: true
```

> \[!CAUTION]
>
> When using `exclusive: true`, ensure the specified profile (or default profile if none specified) has `contents:read` permission. Without this permission, Git operations will fail because no other credential helpers will be available.

Use `exclusive: true` when:

* System-level credential helpers interfere with pipeline-specific authentication
* You need to ensure only Chinmina-vended tokens are used for GitHub operations
* Operating in shared CI environments where credential helper precedence is unclear

### How it works

There are two cooperating parts to the plugin:

1. An `environment` hook to configure a Chinmina Git credentials helper using
   environment variables.
2. A Chinmina Bridge Git credentials helper. This is a simple bash script that
   will be called by Git (as configured in the environment).

When Git clones or fetches a repository, it calls the Credential Helper, which
defers to Chinmina (authenticated with an OIDC token for this pipeline).
Chinmina returns a result in the Git credentials helper format containing the
required username, and the token created for the pipeline.

```d2 sketch=true title="sequence diagram showing Git authentication integration with Chinmina"
shape: sequence_diagram

buildkite-job: Buildkite Job
git: Git
credential-helper: Credential Helper
chinmina: Chinmina Bridge
buildkite-api: Buildkite API

buildkite-job.clone -> git.auth: clone
git.auth -> credential-helper.req: get credentials

credential-helper.req -> buildkite-api.token: request OIDC token
credential-helper.req <- buildkite-api.token: Buildkite OIDC token

credential-helper.req -> chinmina.helper: request GH token\n(using Buildkite OIDC token)
chinmina.helper -> buildkite-api.repo: get pipeline details
chinmina.helper <- buildkite-api.repo: pipeline repository
credential-helper.req <- chinmina.helper: scoped GitHub token

git.auth <- credential-helper.req: \"x-access-token\" /app-token

buildkite-job.clone <- git.auth: complete
```

## Enabling on the agent (for all pipelines)

> \[!TIP]
>
> This is the recommended way to integrate Chinmina with Buildkite, especially for
> Git authentication. Using the plugins on a step-by-step basis is inconvenient
> and inefficient.

This method enables the plugins in the agent `environment` hook, using plugin
versions that have been downloaded in the agent `bootstrap`.

This will enable the functionality to fetch GitHub tokens and authenticate via
Chinmina Bridge on all builds running on the agent.

If more control over activation of this feature is required, add extra
conditions *as code* to the `environment` hook. For example, enable the plugin
based on the presence of an environment variable. This activates the plugin
consistently for every pipeline that defines the environment variable in the
pipeline settings.

1. Alter the agent `bootstrap` hook to clone both plugin sources to the agent so
   they can be activated by any step.

   ```bash
   # Chinmina Token plugin
   plugin_repo="https://github.com/chinmina/chinmina-token-buildkite-plugin.git"
   plugin_version="v1.4.0"
   plugin_dir="/buildkite/plugins/chinmina-token-buildkite-plugin"

   [[ -d "${plugin_dir}" ]] && rm -rf "${plugin_dir}"

   GIT_CONFIG_COUNT=1 \
   GIT_CONFIG_KEY_0=advice.detachedHead \
   GIT_CONFIG_VALUE_0=false \
     git clone --depth 1 --single-branch --no-tags \
       --branch "${plugin_version}" -- \
       "${plugin_repo}" "${plugin_dir}"

   # Chinmina Git Credentials plugin
   plugin_repo="https://github.com/chinmina/chinmina-git-credentials-buildkite-plugin.git"
   plugin_version="v1.6.0"
   plugin_dir="/buildkite/plugins/chinmina-git-credentials-buildkite-plugin"

   [[ -d "${plugin_dir}" ]] && rm -rf "${plugin_dir}"

   GIT_CONFIG_COUNT=1 \
   GIT_CONFIG_KEY_0=advice.detachedHead \
   GIT_CONFIG_VALUE_0=false \
     git clone --depth 1 --single-branch --no-tags \
       --branch "${plugin_version}" -- \
       "${plugin_repo}" "${plugin_dir}"
   ```

2. Set default configuration values and call the plugins' `environment` hooks
   directly from the agent's `environment` hook. These defaults will be used
   by all pipelines unless explicitly overridden.

   ```bash title="Execute plugin environment hooks directly"
   # Set organization-wide defaults (both plugins use these)
   export CHINMINA_DEFAULT_URL="https://chinmina.url-to-instance.io"
   export CHINMINA_DEFAULT_AUDIENCE="chinmina:your-org"

   # Activate Chinmina Token plugin
   source /buildkite/plugins/chinmina-token-buildkite-plugin/hooks/environment

   # Activate Chinmina Git Credentials plugin
   source /buildkite/plugins/chinmina-git-credentials-buildkite-plugin/hooks/environment
   ```

   With this configuration, pipelines no longer need to specify `chinmina-url`
   and `audience` parameters:

   ```yml
   plugins:
     - chinmina/chinmina-token#v1.4.0:
         environment:
           - GITHUB_TOKEN=pipeline:default
   ```

   > \[!NOTE]
   >
   > The bootstrap hook is only run when the agent starts. Cloning the plugins in
   > the bootstrap hook is more efficient than doing so in the environment hook,
   > and also faster.

[chinmina-bridge]: ../introduction/

[chinmina-token]: https://github.com/chinmina/chinmina-token-buildkite-plugin

[credentials-plugin]: https://github.com/chinmina/chinmina-git-credentials-buildkite-plugin

[pipeline-configuration]: https://buildkite.com/docs/pipelines/defining-steps

[library-plugin]: https://buildkite.com/docs/plugins/writing-plugins/library-plugins
