From f8811575cd9f68a20e40bd33d35e8fcfd26d9470 Mon Sep 17 00:00:00 2001 From: Brendan Kellam Date: Fri, 20 Feb 2026 18:22:43 -0800 Subject: [PATCH 1/3] feat(bitbucket): add gitUser field to support API token auth on Bitbucket Cloud BitBucket Cloud API tokens require different usernames for the REST API (email address) and git clone (Atlassian username). Add an optional `gitUser` field to the BitBucket connection config that, when set, is used for git clone credentials instead of `user`. Fixes #892 Co-Authored-By: Claude Sonnet 4.6 --- docs/docs/connections/bitbucket-cloud.mdx | 106 +++++++++++++++--- .../connections/bitbucket-data-center.mdx | 29 ++++- docs/snippets/schemas/v3/bitbucket.schema.mdx | 6 +- .../snippets/schemas/v3/connection.schema.mdx | 6 +- docs/snippets/schemas/v3/index.schema.mdx | 6 +- packages/backend/src/utils.ts | 2 +- packages/schemas/src/v3/bitbucket.schema.ts | 6 +- packages/schemas/src/v3/bitbucket.type.ts | 6 +- packages/schemas/src/v3/connection.schema.ts | 6 +- packages/schemas/src/v3/connection.type.ts | 6 +- packages/schemas/src/v3/index.schema.ts | 6 +- packages/schemas/src/v3/index.type.ts | 6 +- schemas/v3/bitbucket.json | 6 +- 13 files changed, 168 insertions(+), 29 deletions(-) diff --git a/docs/docs/connections/bitbucket-cloud.mdx b/docs/docs/connections/bitbucket-cloud.mdx index 56b140f83..2dd068768 100644 --- a/docs/docs/connections/bitbucket-cloud.mdx +++ b/docs/docs/connections/bitbucket-cloud.mdx @@ -4,8 +4,6 @@ sidebarTitle: Bitbucket Cloud icon: Bitbucket --- -import BitbucketToken from '/snippets/bitbucket-token.mdx'; -import BitbucketAppPassword from '/snippets/bitbucket-app-password.mdx'; import BitbucketSchema from '/snippets/schemas/v3/bitbucket.schema.mdx' @@ -78,25 +76,107 @@ If you're not familiar with Sourcebot [connections](/docs/connections/overview), ## Authenticating with Bitbucket Cloud -In order to index private repositories, you'll need to provide authentication credentials via a [token](/docs/configuration/config-file#tokens). You can do this using an `App Password` or an `Access Token` +In order to index private repositories, you'll need to provide authentication credentials via a [token](/docs/configuration/config-file#tokens). You can do this using an `API Token`, `Access Token`, or `App Password`. - - Navigate to the [app password creation page](https://bitbucket.org/account/settings/app-passwords/) and create an app password. Ensure that it has the proper permissions for the scope - of info you want to fetch (i.e. workspace, project, and/or repo level) - ![Bitbucket App Password Permissions](/images/bitbucket_app_password_perms.png) - - Next, provide your username + app password pair to Sourcebot: - - + + 1. Navigate to [Personal Settings → API tokens](https://id.atlassian.com/manage-profile/security/api-tokens) and click **Create API token with scopes**. Give the token a name and set an expiry date. + + 2. Select **Bitbucket** as the app. + + 3. Select the following scopes: + - `read:repository:bitbucket` — View your repositories + - `read:workspace:bitbucket` — View your workspaces + + 4. Click **Create token** and copy the token value. + + 5. Add the `user` (your account email), `gitUser` (your Bitbucket username), and `token` to your connection config. [Learn why both are needed](https://support.atlassian.com/bitbucket-cloud/docs/using-api-tokens/) + + ```json + { + "type": "bitbucket", + "deploymentType": "cloud", + "user": "you@example.com", + "gitUser": "myusername", + "token": { + // note: this env var can be named anything. It + // doesn't need to be `BITBUCKET_TOKEN`. + "env": "BITBUCKET_TOKEN" + } + // .. rest of config .. + } + ``` + + 6. Pass this environment variable each time you run Sourcebot: + + ```bash + docker run \ + -e BITBUCKET_TOKEN= \ + /* additional args */ \ + ghcr.io/sourcebot-dev/sourcebot:latest + ``` Create an access token for the desired scope (repo, project, or workspace). Visit the official [Bitbucket Cloud docs](https://support.atlassian.com/bitbucket-cloud/docs/access-tokens/) for more info. - Next, provide the access token to Sourcebot: + 1. Add the `token` property to your connection config: + + ```json + { + "type": "bitbucket", + "deploymentType": "cloud", + "token": { + // note: this env var can be named anything. It + // doesn't need to be `BITBUCKET_TOKEN`. + "env": "BITBUCKET_TOKEN" + } + // .. rest of config .. + } + ``` + + 2. Pass this environment variable each time you run Sourcebot: + + ```bash + docker run \ + -e BITBUCKET_TOKEN= \ + /* additional args */ \ + ghcr.io/sourcebot-dev/sourcebot:latest + ``` + + + + App Passwords are deprecated. Atlassian recommends migrating to API tokens. [Learn more](https://www.atlassian.com/blog/bitbucket/bitbucket-cloud-transitions-to-api-tokens-enhancing-security-with-app-password-deprecation) + + + Navigate to the [app password creation page](https://bitbucket.org/account/settings/app-passwords/) and create an app password. Ensure that it has the proper permissions for the scope + of info you want to fetch (i.e. workspace, project, and/or repo level) + ![Bitbucket App Password Permissions](/images/bitbucket_app_password_perms.png) - + 1. Add the `user` (your Bitbucket username) and `token` properties to your connection config: + + ```json + { + "type": "bitbucket", + "deploymentType": "cloud", + "user": "myusername", + "token": { + // note: this env var can be named anything. It + // doesn't need to be `BITBUCKET_TOKEN`. + "env": "BITBUCKET_TOKEN" + } + // .. rest of config .. + } + ``` + + 2. Pass this environment variable each time you run Sourcebot: + + ```bash + docker run \ + -e BITBUCKET_TOKEN= \ + /* additional args */ \ + ghcr.io/sourcebot-dev/sourcebot:latest + ``` diff --git a/docs/docs/connections/bitbucket-data-center.mdx b/docs/docs/connections/bitbucket-data-center.mdx index f88e98a15..1d6979196 100644 --- a/docs/docs/connections/bitbucket-data-center.mdx +++ b/docs/docs/connections/bitbucket-data-center.mdx @@ -4,8 +4,6 @@ sidebarTitle: Bitbucket Data Center icon: Bitbucket --- -import BitbucketToken from '/snippets/bitbucket-token.mdx'; -import BitbucketAppPassword from '/snippets/bitbucket-app-password.mdx'; import BitbucketSchema from '/snippets/schemas/v3/bitbucket.schema.mdx' @@ -75,9 +73,30 @@ In order to index private repositories, you'll need to provide an access token t Create an access token for the desired scope (repo, project, or workspace). Visit the official [Bitbucket Data Center docs](https://confluence.atlassian.com/bitbucketserver/http-access-tokens-939515499.html) for more info. -Next, provide the access token to Sourcebot: - - +1. Add the `token` property to your connection config: + +```json +{ + "type": "bitbucket", + "deploymentType": "server", + "url": "https://mybitbucketdeployment.com", + "token": { + // note: this env var can be named anything. It + // doesn't need to be `BITBUCKET_TOKEN`. + "env": "BITBUCKET_TOKEN" + } + // .. rest of config .. +} +``` + +2. Pass this environment variable each time you run Sourcebot: + +```bash +docker run \ + -e BITBUCKET_TOKEN= \ + /* additional args */ \ + ghcr.io/sourcebot-dev/sourcebot:latest +``` ## Troubleshooting If you're seeing errors like `TypeError: fetch failed` when fetching repo info, it may be that Sourcebot is refusing to connect to your self-hosted Bitbucket instance due to unrecognized SSL certs. Try setting the `NODE_TLS_REJECT_UNAUTHORIZED=0` environment variable or providing Sourcebot your certs through the `NODE_EXTRA_CA_CERTS` environment variable. diff --git a/docs/snippets/schemas/v3/bitbucket.schema.mdx b/docs/snippets/schemas/v3/bitbucket.schema.mdx index d39ca8bef..66531ef77 100644 --- a/docs/snippets/schemas/v3/bitbucket.schema.mdx +++ b/docs/snippets/schemas/v3/bitbucket.schema.mdx @@ -11,7 +11,11 @@ }, "user": { "type": "string", - "description": "The username to use for authentication. Only needed if token is an app password." + "description": "The username to use for API authentication. For app passwords, this is your Bitbucket username. For API tokens, this is your Bitbucket account email address." + }, + "gitUser": { + "type": "string", + "description": "The username to use for git clone authentication over HTTPS. If not set, falls back to 'user'. For API tokens, this is your Bitbucket username" }, "token": { "description": "An authentication token.", diff --git a/docs/snippets/schemas/v3/connection.schema.mdx b/docs/snippets/schemas/v3/connection.schema.mdx index 7070a1a9e..ef8a33138 100644 --- a/docs/snippets/schemas/v3/connection.schema.mdx +++ b/docs/snippets/schemas/v3/connection.schema.mdx @@ -688,7 +688,11 @@ }, "user": { "type": "string", - "description": "The username to use for authentication. Only needed if token is an app password." + "description": "The username to use for API authentication. For app passwords, this is your Bitbucket username. For API tokens, this is your Bitbucket account email address." + }, + "gitUser": { + "type": "string", + "description": "The username to use for git clone authentication over HTTPS. If not set, falls back to 'user'. For API tokens, this is your Bitbucket username" }, "token": { "description": "An authentication token.", diff --git a/docs/snippets/schemas/v3/index.schema.mdx b/docs/snippets/schemas/v3/index.schema.mdx index 5c575bc3c..38beefc66 100644 --- a/docs/snippets/schemas/v3/index.schema.mdx +++ b/docs/snippets/schemas/v3/index.schema.mdx @@ -1103,7 +1103,11 @@ }, "user": { "type": "string", - "description": "The username to use for authentication. Only needed if token is an app password." + "description": "The username to use for API authentication. For app passwords, this is your Bitbucket username. For API tokens, this is your Bitbucket account email address." + }, + "gitUser": { + "type": "string", + "description": "The username to use for git clone authentication over HTTPS. If not set, falls back to 'user'. For API tokens, this is your Bitbucket username" }, "token": { "anyOf": [ diff --git a/packages/backend/src/utils.ts b/packages/backend/src/utils.ts index b333044c8..f897e6fb7 100644 --- a/packages/backend/src/utils.ts +++ b/packages/backend/src/utils.ts @@ -182,7 +182,7 @@ export const getAuthCredentialsForRepo = async (repo: RepoWithConnections, logge const config = connection.config as unknown as BitbucketConnectionConfig; if (config.token) { const token = await getTokenFromConfig(config.token); - const username = config.user ?? 'x-token-auth'; + const username = config.gitUser ?? config.user ?? 'x-token-auth'; return { hostUrl: config.url, token, diff --git a/packages/schemas/src/v3/bitbucket.schema.ts b/packages/schemas/src/v3/bitbucket.schema.ts index 3e75400ef..ce6c20581 100644 --- a/packages/schemas/src/v3/bitbucket.schema.ts +++ b/packages/schemas/src/v3/bitbucket.schema.ts @@ -10,7 +10,11 @@ const schema = { }, "user": { "type": "string", - "description": "The username to use for authentication. Only needed if token is an app password." + "description": "The username to use for API authentication. For app passwords, this is your Bitbucket username. For API tokens, this is your Bitbucket account email address." + }, + "gitUser": { + "type": "string", + "description": "The username to use for git clone authentication over HTTPS. If not set, falls back to 'user'. For API tokens, this is your Bitbucket username" }, "token": { "description": "An authentication token.", diff --git a/packages/schemas/src/v3/bitbucket.type.ts b/packages/schemas/src/v3/bitbucket.type.ts index d03f89668..a83063049 100644 --- a/packages/schemas/src/v3/bitbucket.type.ts +++ b/packages/schemas/src/v3/bitbucket.type.ts @@ -6,9 +6,13 @@ export interface BitbucketConnectionConfig { */ type: "bitbucket"; /** - * The username to use for authentication. Only needed if token is an app password. + * The username to use for API authentication. For app passwords, this is your Bitbucket username. For API tokens, this is your Bitbucket account email address. */ user?: string; + /** + * The username to use for git clone authentication over HTTPS. If not set, falls back to 'user'. For API tokens, this is your Bitbucket username + */ + gitUser?: string; /** * An authentication token. */ diff --git a/packages/schemas/src/v3/connection.schema.ts b/packages/schemas/src/v3/connection.schema.ts index 51f6bcda7..ae4cffc2a 100644 --- a/packages/schemas/src/v3/connection.schema.ts +++ b/packages/schemas/src/v3/connection.schema.ts @@ -687,7 +687,11 @@ const schema = { }, "user": { "type": "string", - "description": "The username to use for authentication. Only needed if token is an app password." + "description": "The username to use for API authentication. For app passwords, this is your Bitbucket username. For API tokens, this is your Bitbucket account email address." + }, + "gitUser": { + "type": "string", + "description": "The username to use for git clone authentication over HTTPS. If not set, falls back to 'user'. For API tokens, this is your Bitbucket username" }, "token": { "description": "An authentication token.", diff --git a/packages/schemas/src/v3/connection.type.ts b/packages/schemas/src/v3/connection.type.ts index 3bd5feb45..f20e20498 100644 --- a/packages/schemas/src/v3/connection.type.ts +++ b/packages/schemas/src/v3/connection.type.ts @@ -257,9 +257,13 @@ export interface BitbucketConnectionConfig { */ type: "bitbucket"; /** - * The username to use for authentication. Only needed if token is an app password. + * The username to use for API authentication. For app passwords, this is your Bitbucket username. For API tokens, this is your Bitbucket account email address. */ user?: string; + /** + * The username to use for git clone authentication over HTTPS. If not set, falls back to 'user'. For API tokens, this is your Bitbucket username + */ + gitUser?: string; /** * An authentication token. */ diff --git a/packages/schemas/src/v3/index.schema.ts b/packages/schemas/src/v3/index.schema.ts index d3482891a..8f846d8b5 100644 --- a/packages/schemas/src/v3/index.schema.ts +++ b/packages/schemas/src/v3/index.schema.ts @@ -1102,7 +1102,11 @@ const schema = { }, "user": { "type": "string", - "description": "The username to use for authentication. Only needed if token is an app password." + "description": "The username to use for API authentication. For app passwords, this is your Bitbucket username. For API tokens, this is your Bitbucket account email address." + }, + "gitUser": { + "type": "string", + "description": "The username to use for git clone authentication over HTTPS. If not set, falls back to 'user'. For API tokens, this is your Bitbucket username" }, "token": { "anyOf": [ diff --git a/packages/schemas/src/v3/index.type.ts b/packages/schemas/src/v3/index.type.ts index a3342dd18..e08be76f8 100644 --- a/packages/schemas/src/v3/index.type.ts +++ b/packages/schemas/src/v3/index.type.ts @@ -455,9 +455,13 @@ export interface BitbucketConnectionConfig { */ type: "bitbucket"; /** - * The username to use for authentication. Only needed if token is an app password. + * The username to use for API authentication. For app passwords, this is your Bitbucket username. For API tokens, this is your Bitbucket account email address. */ user?: string; + /** + * The username to use for git clone authentication over HTTPS. If not set, falls back to 'user'. For API tokens, this is your Bitbucket username + */ + gitUser?: string; /** * An authentication token. */ diff --git a/schemas/v3/bitbucket.json b/schemas/v3/bitbucket.json index 4bac5e1b2..d6f57b5dc 100644 --- a/schemas/v3/bitbucket.json +++ b/schemas/v3/bitbucket.json @@ -9,7 +9,11 @@ }, "user": { "type": "string", - "description": "The username to use for authentication. Only needed if token is an app password." + "description": "The username to use for API authentication. For app passwords, this is your Bitbucket username. For API tokens, this is your Bitbucket account email address." + }, + "gitUser": { + "type": "string", + "description": "The username to use for git clone authentication over HTTPS. If not set, falls back to 'user'. For API tokens, this is your Bitbucket username" }, "token": { "$ref": "./shared.json#/definitions/Token", From bca6194f718cf658c4845f87108658b7f8b4e871 Mon Sep 17 00:00:00 2001 From: Brendan Kellam Date: Fri, 20 Feb 2026 18:23:07 -0800 Subject: [PATCH 2/3] chore: update CHANGELOG for #918 Co-Authored-By: Claude Sonnet 4.6 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd9d57a50..710171f37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Skip calling `getCommitHashForRefName` for empty repositories to avoid noisy debug log output. [#914](https://github.com/sourcebot-dev/sourcebot/pull/914) +### Added +- Added optional `gitUser` field to the Bitbucket connection config to support Bitbucket Cloud API tokens, which require an email address for the REST API but an Atlassian username for git clone. [#918](https://github.com/sourcebot-dev/sourcebot/pull/918) + ## [4.11.4] - 2026-02-20 ### Fixed From 15dbda38857575346e643146b3a84df048752137 Mon Sep 17 00:00:00 2001 From: Brendan Kellam Date: Fri, 20 Feb 2026 18:24:01 -0800 Subject: [PATCH 3/3] chore: delete unused Bitbucket snippet files Co-Authored-By: Claude Sonnet 4.6 --- docs/snippets/bitbucket-app-password.mdx | 27 ------------------------ docs/snippets/bitbucket-token.mdx | 25 ---------------------- 2 files changed, 52 deletions(-) delete mode 100644 docs/snippets/bitbucket-app-password.mdx delete mode 100644 docs/snippets/bitbucket-token.mdx diff --git a/docs/snippets/bitbucket-app-password.mdx b/docs/snippets/bitbucket-app-password.mdx deleted file mode 100644 index 2d4511c3c..000000000 --- a/docs/snippets/bitbucket-app-password.mdx +++ /dev/null @@ -1,27 +0,0 @@ - - - - 1. Add the `token` and `user` (username associated with the app password you created) properties to your connection config: - ```json - { - "type": "bitbucket", - "deploymentType": "cloud", - "user": "myusername", - "token": { - // note: this env var can be named anything. It - // doesn't need to be `BITBUCKET_TOKEN`. - "env": "BITBUCKET_TOKEN" - } - // .. rest of config .. - } - ``` - - 2. Pass this environment variable each time you run Sourcebot: - ```bash - docker run \ - -e BITBUCKET_TOKEN= \ - /* additional args */ \ - ghcr.io/sourcebot-dev/sourcebot:latest - ``` - - \ No newline at end of file diff --git a/docs/snippets/bitbucket-token.mdx b/docs/snippets/bitbucket-token.mdx deleted file mode 100644 index 26efe2486..000000000 --- a/docs/snippets/bitbucket-token.mdx +++ /dev/null @@ -1,25 +0,0 @@ - - - - 1. Add the `token` property to your connection config: - ```json - { - "type": "bitbucket", - "token": { - // note: this env var can be named anything. It - // doesn't need to be `BITBUCKET_TOKEN`. - "env": "BITBUCKET_TOKEN" - } - // .. rest of config .. - } - ``` - - 2. Pass this environment variable each time you run Sourcebot: - ```bash - docker run \ - -e BITBUCKET_TOKEN= \ - /* additional args */ \ - ghcr.io/sourcebot-dev/sourcebot:latest - ``` - - \ No newline at end of file