POST /git-credentials/{profile}
The POST /git-credentials/{profile} (and legacy POST /git-credentials)
endpoints vend short-lived GitHub installation tokens validated against
Buildkite OIDC tokens.
The profile parameter selects the pipeline profile that will be used when creating the token using permissions defined by the specified pipeline profile.
The reserved profile name default is always available. The default profile can
be requested via POST /git-credentials/default or POST /git-credentials.
Permissions for the default profile can be
changed but match rules cannot be added.
Purpose
Section titled “Purpose”This endpoint serves the same underlying function as /token (vending GitHub
installation tokens), however its request and response format follows Git’s
credential helper protocol. This allows Chinmina Bridge to
act as a Git credential helper, enabling transparent authentication for Git
operations without requiring separate credential extraction and configuration
steps.
See the Buildkite integration guide for details on how this endpoint is used in practice.
Request format
Section titled “Request format”Headers
Section titled “Headers”| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer token containing Buildkite OIDC JWT |
Content-Type | Recommended | Should be text/plain |
Profile parameter
Section titled “Profile parameter”The optional {profile} path parameter specifies which pipeline profile to use:
/git-credentials(no parameter): Uses pipeline default permissions/git-credentials/default: Same as/git-credentials(explicitly requests default permissions)/git-credentials/{profile-name}: Uses the named pipeline profile
Profile names are used directly in the path. The API does not use prefixes
(prefixes like pipeline: are part of the plugin interface only).
Examples:
POST /git-credentials→ default pipeline permissionsPOST /git-credentials/pr-commenter→ “pr-commenter” pipeline profilePOST /git-credentials/release→ “release” pipeline profile
If the profile does not exist or the pipeline doesn’t match the profile’s access rules, the request returns an error.
Request body
Section titled “Request body”The request body follows Git’s credential helper input format:
protocol=httpshost=github.compath=owner/repositoryWhen any of protocol, host, or path is non-empty, both protocol and
host must be non-empty. An entirely empty target returns 200 without
credentials. path is optional.
Git credential request handling describes how the request target is validated, and which targets return no credentials without consulting the profile.
Response format
Section titled “Response format”Success response (200 OK)
Section titled “Success response (200 OK)”When a token is successfully vended, the response contains Git credential helper output:
protocol=httpshost=github.compath=owner/repositoryusername=x-access-tokenpassword=ghs_...password_expiry_utc=1705320600The response body is plain text with newline-separated key-value pairs. Git
parses this and uses the credentials for the requested operation. The
protocol, host, and path lines echo the request.
With DEV_DISCLOSE_APP_IDENTIFIERS
set, the response also carries chinmina_app_name, chinmina_app_id, and
chinmina_installation_id. See development
properties. This
setting is for development only.
Empty response (200 OK)
Section titled “Empty response (200 OK)”The endpoint returns a successful but empty response when it has no credentials
for the requested context: the request supplies no target, names a destination
other than https and github.com, or requests a repository other than the
pipeline’s. See Git credential request
handling for the full set of
conditions, and Git credentials
format for how Git treats the
response.
Error responses
Section titled “Error responses”| Status code | Condition | Response |
|---|---|---|
| 400 Bad Request | Target partially specified: protocol or host missing or empty | Bad Request in plain text |
| 401 Unauthorized | Missing or invalid JWT | JSON error |
| 403 Forbidden | Pipeline doesn’t match profile’s access rules | Empty body, Chinmina-Denied header |
| 404 Not Found | Profile does not exist, or is unavailable because it failed validation (for example, it names a GitHub App that is not configured or is disabled) | Empty body, Chinmina-Denied header |
| 413 Content Too Large | Request body exceeds the 20 KB limit | Empty body, Chinmina-Denied header |
| 500 Internal Server Error | Token vending failure, Buildkite or GitHub API error, or the profile names a GitHub App that could not be resolved | Empty body, Chinmina-Denied header |
Errors raised by the endpoint carry no response body. The caller-facing reason
is returned in the Chinmina-Denied header, and the full cause is recorded in
the audit log. A profile that failed validation reports
profile unavailable: validation failed. The server never returns client
content as part of an error message.
Two cases differ. A JWT validation failure is answered by the authentication
middleware with a JSON body and a WWW-Authenticate header. An incomplete
request target is answered with a plain text status line and no
Chinmina-Denied header.
