POST /organization/git-credentials/{profile}
The POST /organization/git-credentials/{profile} endpoint returns GitHub
installation tokens in Git’s credential helper format, using
token permissions granted by a specified organization profile.
Purpose
Section titled “Purpose”This endpoint provides explicit control over which organization profile is used when vending GitHub tokens. Profiles allow configuring different sets of repositories and permissions for different use cases.
This endpoint serves the same underlying function as POST /organization/token/{profile} (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 also
Section titled “See also”- Buildkite integration guide for details on how this endpoint is used in practice.
- Customizing token permissions guide for practical setup and usage instructions.
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 |
Parameters
Section titled “Parameters”Profile parameter
Section titled “Profile parameter”The {profile} path parameter specifies which organization profile to use. Profile names are used directly without prefixes.
Examples:
POST /organization/git-credentials/deployPOST /organization/git-credentials/package-registryPOST /organization/git-credentials/buildkite-plugin
The API does not use prefixes. Prefixes like org: are part of the plugin interface only and are translated by the plugins to the appropriate API paths.
Repository scope
Section titled “Repository scope”For profiles configured with repositories: ["{{caller-scoped-repository}}"]
(see caller-scoped repositories),
the target repository is derived automatically from the path field in the
request body. For a supported destination, a path that does not resolve to a
repository returns 400 Bad Request. See caller-scoped
organization
profiles
for the paths that derive a repository.
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. For a supported destination, caller-scoped profiles require a
path that resolves to a repository. path is optional for other profiles.
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:
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 outside a static
profile’s repository list. This allows Git to fall through to other credential
sources. See Git credential request
handling for the full set of
conditions, and Git credentials
format for how Git treats the
response.
Caller-scoped and wildcard profiles are covered separately. A wildcard profile returns credentials for any repository its installation can reach. A caller-scoped profile returns 400 only when a supported target’s path does not resolve to a repository. When no target is supplied, it returns 200 with no credentials.
Error responses
Section titled “Error responses”| Status code | Condition | Response |
|---|---|---|
| 400 Bad Request | Invalid profile format or parameter, or caller-scoped repository could not be resolved | Empty body, Chinmina-Denied header |
| 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 | JWT valid but claims insufficient, or GitHub rejected a caller-scoped repository | 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, 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.
