Introduction
Connect Buildkite to GitHub with secure, short-lived tokens.
Chinmina Bridge is a simple web service that acts as an intermediary between a Buildkite installation and a related GitHub App. Buildkite agents can request ephemeral GitHub access tokens from Chinmina Bridge, removing the need to store Deploy Keys or Personal Access Tokens long term.

Benefits
Section titled “Benefits”There are substantial security and flexibility benefits when Chinmina Bridge is integrated with your Buildkite stack, as outlined below. While initial deployment is not trivial, it provides a level of auditability and manageability that isn’t present in the standard Buildkite/GitHub integration that makes Chinmina ideal for scaling Buildkite deployments from a handful to hundreds of repositories.
Security
Section titled “Security”-
Access tokens for the repository have a lifetime of one hour and only provide read access to the pipeline repository. There is no token to store and refresh: it’s entirely automatic.
-
Issuing deploy keys per repository is no longer required. Deploy keys are long-lived credentials that require elevated repository permissions, and keys issued to individuals have a higher potential to be accidentally leaked.
-
The GitHub app private key is the only key that is stored: no other token storage is required in secrets or S3, and nothing to manage per-repository in GitHub.
-
With KMS, the highly sensitive private key cannot be extracted. When configured as described in our guide, the Chinmina service uses KMS to sign the GitHub JWT, and never has access to the raw key material.
-
Audit-friendly logs are written for each token request, whether successful or unsuccessful. These can be readily connected to your SIEM system, adding transparency and traceability to the system.
Flexibility
Section titled “Flexibility”Once configured, Buildkite pipelines get automatic read access to their source repository. This reduces complexity in the provisioning process.
Drawbacks
Section titled “Drawbacks”-
Chinmina is not available as a cloud offering: it needs to be self-hosted and reachable by the Buildkite agent infrastructure. It is a single point of failure in the system also, and critical to keep up. Given that it is a simple, containerized HTTP service with Open Telemetry support and easy scaling, this is thankfully relatively straightforward.
-
The private key for the GitHub application is quite powerful, and needs to be carefully protected. It has the superset of permissions that it can delegate. Storing the key in AWS KMS and using careful resource and IAM policies on access is therefore strongly recommended.
-
Adequate controls are required on Buildkite pipeline creation. At present, the bridge will allow access by the pipeline to the configured repository. Controls are required to ensure that repository access is appropriately limited.1
How it works
Section titled “How it works”Chinmina Bridge accepts HTTP connections from Buildkite agents. GitHub tokens are requested from one of the available endpoints using Buildkite OIDC token for authorization.
GitHub tokens vended by Chinmina have a maximum lifetime of an hour. Chinmina will cache tokens internally for up to 15 minutes, so the token received by an agent will have an effective lifetime of between 45 and 60 minutes.
Pipeline-based
Section titled “Pipeline-based”This is the simplest way of working with Chinmina, where a token is retrieved for the repository linked to the pipeline that is running the current build. This is a direct replacement for the deploy key or PAT that would be required instead.
Requests to /token and /git-credentials are authorized with the Buildkite
OIDC token, whose claims identify the executing pipeline. From
the pipeline, the associated GitHub repository is looked up, and a token with
contents:read permission is returned for that repository.
Organization profiles
Section titled “Organization profiles”If the /organization/* routes are used, Chinmina will use the organization
profile to determine the repositories and permissions for the
GitHub token. Profiles can optionally restrict access
to specific pipelines via claim matching.
Endpoints
Section titled “Endpoints”Five endpoints are exposed:
/token, which returns a token and its expiry/organization/token/{profile}, which returns a token and its expiry for a given organization profile/git-credentials, which returns the token and repository metadata in the Git Credentials format./organization/git-credentials/{profile}, which returns the token and repository metadata in the Git Credentials format for a given organization profile./healthcheck, which returns 200. It is used for healthcheck requests from load balancers and the like.
Footnotes
Section titled “Footnotes”-
Changing this behaviour is on the road map. In upcoming releases, you will be able to require some central configuration will be required in order to enable repository access. ↩