Token security
Use this page to compare Buildkite token types, manage token access, identify tokens by their prefixes, and understand how leaked tokens are detected. For controls beyond tokens, see the Security overview.
If a token may have been exposed, follow Incident response immediately. Don't wait for a secret scanning notification.
Manage the token lifecycle
Choose the token type your workflow needs, grant only the required access, and plan how to replace or revoke it:
- Create and scope API access tokens: Follow Creating and editing API access tokens, and select only the token scopes the workflow requires.
- Set expiry and rotate credentials: Set a Token Expiry when creating an API access token with the Token credential type, and follow the rotation guidance. For agent tokens, use the API to set an expiration date; tokens created in the Buildkite interface don't expire.
- Manage agent tokens: Create a token in the cluster that needs it, review its scope of access, and revoke it when no longer needed. Revocation prevents new connections but doesn't disconnect existing agents.
- Review and remove API token access: Audit tokens regularly. Organization administrators can remove their organization from a token; token owners can revoke the token entirely.
- Prefer short-lived credentials where supported: Use OAuth Token Exchange for services or job acquisition tokens for ephemeral agents, rather than distributing long-lived tokens to them.
-
Manage OAuth access: Review OAuth for remote MCP and the Buildkite CLI for refresh behavior, Connected Apps revocation, and authorization audit events. Running
bk auth logoutremoves local credentials but doesn't revoke the authorization in Buildkite.
Detect leaked tokens
Buildkite is a member of the GitHub secret scanning program .
If you have enabled GitHub Secret Protection for repositories in your GitHub organization, GitHub will automatically scan these private or public repositories within your GitHub organization for Buildkite tokens and notify you if any are found.
In the case of Buildkite API access tokens (bkua_) leaked on public repositories, GitHub will notify Buildkite directly and any valid tokens will be automatically revoked and their owner's and associated organizations notified.
If you are notified of any other tokens, please contact Buildkite support.
Audit this area
SSO and 2FA enforcement, team membership and the API access audit can't be read through the MCP server today. It also can't look up a token you've found, so use the API tab to identify a leaked one.
The current token API requires no additional token scope. The team query requires GraphQL API access; replace acme-inc with your organization slug. Results only include teams and pipelines visible to the token. Follow GraphQL pagination for both connections when hasNextPage is true. Run these commands locally with jq installed. Never paste tokens into an AI conversation or save them in logs.
API
# Scopes and expiry of the token you're using
curl --fail-with-body -sS \
-H "Authorization: Bearer $BUILDKITE_API_TOKEN" \
https://api.buildkite.com/v2/access-token | jq '{scopes, expires_at}'
# Teams, pipelines, and access levels visible to this token (GraphQL)
curl --fail-with-body -sS \
-H "Authorization: Bearer $BUILDKITE_API_TOKEN" \
-H "Content-Type: application/json" \
https://graphql.buildkite.com/v1 \
--data '{"query":"{ organization(slug: \"acme-inc\") { teams(first: 100) { pageInfo { hasNextPage endCursor } edges { node { name pipelines(first: 100) { pageInfo { hasNextPage endCursor } edges { node { accessLevel pipeline { slug } } } } } } } } }"}' | jq
# Identify an exposed bkua_ token: owner, scopes, and expiry
curl --fail-with-body -sS \
-H "Authorization: Bearer $LEAKED_TOKEN" \
https://api.buildkite.com/v2/access-token | jq '{user, scopes, expires_at}'
# Only after confirming the exposed token: permanently revoke it
curl --fail-with-body -sS -X DELETE \
-H "Authorization: Bearer $LEAKED_TOKEN" \
https://api.buildkite.com/v2/access-token
The final API command revokes the exposed token, not just its access to one organization. Don't run it against a credential you still need. Use a separate token for the team query, rather than an exposed token.
CLI
# Inspect the token configured for the Buildkite CLI
curl --fail-with-body -sS \
-H "Authorization: Bearer $(bk auth token)" \
https://api.buildkite.com/v2/access-token | jq '{scopes, expires_at}'
# Find files containing possible Buildkite tokens in this directory
# Print filenames only, not the token values
grep -rlE --exclude-dir=.git \
'bk(ua|tx|ct|ar|aa|aj|jat|pt|pat|ps)_[A-Za-z0-9]+' .
The Buildkite CLI must be authenticated. bk api uses organization-scoped REST endpoints, so use bk auth token with curl for the root /access-token endpoint. The file search checks the working directory and saved logs, not Git history or remote build logs. Matches are candidates, not proof that a token is valid; review them locally and revoke exposed credentials.
Review SSO enforcement, 2FA enforcement, and the API access audit in the Buildkite interface.
Ask the Buildkite MCP
What scopes does my Buildkite token have, and when does it expire?
Which Buildkite organization am I connected to?
Use only the read-only access_token and user_token_organization tools.
Inspect the MCP connection's token, not a token pasted into this chat.
Report missing expiry information rather than inferring a lifetime.
Do not change anything.
Use read-only MCP access with the user toolset enabled and the read_user and read_organizations scopes. The returned metadata describes the credential used by the MCP server to call the Buildkite API. With OAuth, it doesn't establish the MCP client's session or refresh-token expiry. See OAuth token lifetime and refresh.
Token reference
The following table summarizes how each Buildkite token is used, what it can access, and how long it remains valid. Tokens marked as internal are generated and managed by the Buildkite agent, and you don't create them yourself.
| Token and prefix | How it's used | Scope | Lifetime | ||||
|---|---|---|---|---|---|---|---|
| Token and prefix |
API access token bkua_
|
How it's used | Users and scripts call the REST and GraphQL APIs with a bearer token. | Scope | The selected REST API scopes and optional GraphQL access, for the selected Buildkite organizations. GraphQL access is not further scoped. | Lifetime | The Token Expiry selected at creation, which defaults to seven days. Tokens with the Public Key credential type don't expire. |
| Token and prefix |
OAuth Token Exchange token bktx_
|
How it's used | Services exchange a signed JWT assertion for a token, and call the APIs on behalf of a user. | Scope | The requested scopes, limited to the Token Exchange App's grantable scopes. | Lifetime | Up to the app's Max Token TTL, which defaults to one hour and can be set between 30 seconds and 24 hours. |
| Token and prefix |
Agent token bkct_
|
How it's used | Self-hosted agents register with a cluster using BUILDKITE_AGENT_TOKEN. |
Scope | Any queue in one cluster. | Lifetime | No expiry when created in the Buildkite interface. An optional expiry, at least 10 minutes in the future, can be set when created using the API. |
| Token and prefix |
Unclustered agent token bkar_
|
How it's used | Agents register with unclustered queues. | Scope | Any unclustered queue in the Buildkite organization. | Lifetime | No expiry. Revoke manually. |
| Token and prefix |
Job acquisition token bkjat_
|
How it's used | A stack controller issues the token to an ephemeral agent, which registers and acquires one reserved job. | Scope | One reserved job. | Lifetime | 15 minutes by default, up to one hour, or until the job reservation expires, whichever is first. |
| Token and prefix |
Agent session token (internal) bkaa_
|
How it's used | Issued to an agent when it registers, and used to poll for and start jobs. | Scope | The registered agent's connection. | Lifetime | Until the agent disconnects. |
| Token and prefix |
Agent job token (internal) bkaj_
|
How it's used | Exposed to each job as BUILDKITE_AGENT_ACCESS_TOKEN, and used by agent CLI commands such as annotate, artifact, and meta-data. |
Scope | The job, plus metadata, annotations, and artifacts of other jobs in the same cluster. | Lifetime | Until the job finishes. |
| Token and prefix |
Registry token bkpt_
|
How it's used | Package managers download and install packages from a private registry. | Scope | Read-only access to one registry. | Lifetime | No expiry. Delete manually. |
| Token and prefix | Package Registries temporary token bkpt_
|
How it's used | Included in the publish and install commands shown on a registry's pages. | Scope | Publishing to, or installing from, one registry. | Lifetime | A few minutes. |
| Token and prefix |
Portal long-lived service token bkpat_
|
How it's used | Services call a portal's endpoint with a bearer token. | Scope | The portal's GraphQL operations, run with administrator-level permissions. | Lifetime | No expiry. Replace it from the portal's Security page. |
| Token and prefix |
Ephemeral portal token bkpat_
|
How it's used | Services exchange a portal secret for a token. | Scope | The portal's GraphQL operations, run with administrator-level permissions. | Lifetime | Up to one hour, or shorter if requested. |
| Token and prefix |
User-invoked portal token bkpat_
|
How it's used | A user authorizes a token code to generate the token. | Scope | The portal's GraphQL operations, limited to the user's own permissions. | Lifetime | 12 hours by default, or shorter if requested. |
| Token and prefix |
Portal secret bkps_
|
How it's used | Services use the secret to request ephemeral portal tokens. | Scope | One portal. | Lifetime | No expiry. Each portal can have two secrets, so that you can rotate them. |
| Token and prefix |
OIDC token —
|
How it's used | Jobs present a signed JWT to cloud providers or Buildkite Package Registries, not to the Buildkite REST or GraphQL APIs. No Buildkite token prefix. | Scope | The intended audience, token claims, and receiving system's trust policy. | Lifetime | Five minutes by default for agent-issued tokens, configurable with --lifetime. Buildkite Package Registries accepts tokens valid for no more than five minutes. |
Supported Buildkite tokens
The following Buildkite tokens are supported by the GitHub secret scanning program.
API access tokens
Buildkite API access tokens are also known as Buildkite user access tokens, whose acronym forms the prefix for these types of tokens.
- Prefix:
bkua_ - Example:
bkua_*****************************************************
Applies to API access tokens created after: March, 2023
Agent session tokens
Buildkite agent session tokens are also known as Buildkite agent access tokens, whose acronym forms the prefix for these types of tokens.
- Prefix:
bkaa_ - Example:
bkaa_***************************************************************************
Applies to agent session tokens created after: January, 2025
Agent job tokens
Buildkite agent job tokens form the acronym for the prefix of their values.
- Prefix:
bkaj_ - Example:
bkaj_*********************************************************************************************************************************************************************************************************************************************************************************************************************************************
Unclustered agent tokens
Buildkite unclustered agent tokens are also known as Buildkite agent registration tokens, whose acronym forms the prefix for these types of tokens.
- Prefix:
bkar_ - Example:
bkar_*************************************************************************
Applies to unclustered agent tokens created after: April, 2025
Agent tokens
Buildkite agent tokens are also known as Buildkite cluster tokens, whose acronym forms the prefix for these types of tokens.
- Prefix:
bkct_ - Example:
bkct_*************************************************************************
Applies to agent tokens created after: April, 2025
Registry tokens
Buildkite registry tokens, are a type of Buildkite Package (Registries) token, whose acronym forms the prefix for these tokens.
- Prefix:
bkpt_ - Example:
bkpt_*******************************************************************************************************************************************************************************************************
Package Registries temporary tokens
Buildkite Package Registries temporary tokens, which are presented on a registry's pages for either publishing packages to the registry or installing specific packages from them. See the relevant Package ecosystem pages to learn more about these types of tokens, which are a type of Buildkite Package (Registries) token, whose acronym forms the prefix for these tokens.
- Prefix:
bkpt_ - Example:
bkpt_*******************************************************************************************************************************************************************************************************
Portal tokens
Buildkite portal tokens cover the following types of tokens:
- Long-lived service tokens, generated when a new portal is created, as well as through the portal's Security page.
- Ephemeral portal tokens, which requires a portal secret to be generated.
- Portal tokens that are user-invoked and scoped.
These types of tokens are also known as Buildkite portal access tokens, whose acronym forms the prefix for these types of tokens.
- Prefix:
bkpat_ - Example:
bkpat_******************************************************
Portal secrets
Buildkite portal secrets, whose acronym forms the prefix to their values, are used to generate ephemeral portal tokens, which are a type of portal token.
- Prefix:
bkps_ - Example:
bkps_****************************************************************
Other Buildkite tokens
Buildkite also issues short-lived tokens for specific workflows.
Job acquisition tokens
Buildkite job acquisition tokens allow an ephemeral agent to register and acquire one reserved job without receiving the long-lived agent token held by its stack controller.
- Prefix:
bkjat_ - Example:
bkjat_***************************************************** - Lifetime: 15 minutes by default, up to one hour, or until the job reservation expires, whichever is first.
OAuth Token Exchange tokens
Buildkite OAuth Token Exchange tokens are short-lived API tokens that a service obtains by exchanging a signed JSON Web Token (JWT) assertion, instead of using a long-lived API access token tied to a user.
- Prefix:
bktx_ - Lifetime: Up to the app's Max Token TTL, which defaults to one hour and can be set between 30 seconds and 24 hours.