Bitbucket Source
What it ingests
Repository activity from Bitbucket Cloud — pull requests, issues, commits, and review verdicts (approvals and change requests) — across a whole workspace or an explicit list of repositories.
It is the Bitbucket-side peer of the GitHub source and feeds the same graph entity types (Repository, PullRequest, Issue, Commit), so an org split across both forges gets one graph rather than two.
Bitbucket Cloud only
This source does not support Bitbucket Data Center / Server. That product speaks /rest/api/1.0, which is a different API rather than a different base URL for this one — different pagination, different response envelopes, different user and link shapes, and no workspace concept (it has projects instead). There is no base_url setting that would reach it.
Credential
The Bitbucket source references a bitbucket_access_token credential by id. Store only the secret — never a username:secret pair, even though Bitbucket's own curl examples show them joined by a colon. The username, when one is needed at all, goes in the source's username config field.
Three kinds of secret work, and which one you have decides whether you set username:
| Secret | Set username? | How it is sent |
|---|---|---|
| Access token (workspace, project, or repository) | No — leave it empty | Authorization: Bearer <token> |
| App password | Yes — the Bitbucket username | HTTP Basic |
| Atlassian API token | Yes — the account email | HTTP Basic |
An access token is the recommended choice: it is scoped to exactly the workspace, project, or repository you point it at, and it needs no user account behind it. Atlassian has put app passwords on a deprecation path, so prefer an access token for a new install.
curl -sS -X POST https://your-corveil-host/api/credentials \
-H "Authorization: Bearer <admin>" -H "Content-Type: application/json" \
-d '{"type":"bitbucket_access_token","name":"acme-bitbucket-ro","secret":"ATCTT..."}'Copy the returned credential id.
Required scopes
Grant read access to repositories, pull requests, and issues:
- Access token —
repository,pullrequest, andissue. - App password — Repositories: Read, Pull requests: Read, and Issues: Read.
A missing scope surfaces as a 403 that names what to grant, rather than a bare status code.
Config fields
| Key | Required | Notes |
|---|---|---|
workspace | one of workspace / repos | Workspace slug, e.g. acme. Use the slug from the workspace URL, not its display name. |
repos | one of workspace / repos | Comma-separated workspace/repo-slug list, e.g. acme/api, acme/web. |
username | no | The account username or email, for an app password or Atlassian API token. Leave empty for an access token — see the table above. |
Provide either a workspace or an explicit repo list. Setting workspace polls every repository in it; setting repos polls exactly those.
Provider-side setup
- Create the credential in Bitbucket:
- Access token — Workspace settings → Access tokens (or a project's or repository's own settings, for a narrower scope).
- App password — Personal settings → App passwords.
- Grant the scopes listed above.
- Copy the secret. Bitbucket shows it exactly once.
Wire-up
POST /api/sensors
{
"sensor_type": "bitbucket",
"name": "Acme Bitbucket",
"config": { "workspace": "acme" },
"credentials": { "token": "<bitbucket_access_token credential id>" }
}To scope to specific repos instead:
{
"sensor_type": "bitbucket",
"name": "Acme API + Web",
"config": { "repos": "acme/api, acme/web" },
"credentials": { "token": "<bitbucket_access_token credential id>" }
}With an app password, add the username:
{
"sensor_type": "bitbucket",
"name": "Acme Bitbucket",
"config": { "workspace": "acme", "username": "jane@acme.com" },
"credentials": { "token": "<bitbucket_access_token credential id>" }
}Verify
Use Test connection on the source. It probes the workspace's repository listing — the same call the poller makes — so a pass means the credential can read what the source is configured to ingest. A bad or under-scoped credential comes back as a named auth failure quoting Bitbucket's own message, not a generic error.
After the first poll, the source's event count climbs and sensor_events carry source = "bitbucket".
What to expect
- Backfill then poll. A new source first backfills the configured history window, then polls for what changed since a timestamp watermark. The watermark only advances when every repository succeeded, so a transient failure re-fetches its window rather than skipping it.
- Lifecycle transitions are separate events. A pull request that opens and later merges produces two events, not one — which is what lets the graph record who merged it.
- Repos with no issue tracker are fine. The tracker is opt-in per repository on Bitbucket Cloud; a repo without one contributes pull requests and commits as normal.
- No author emails on pull requests or issues. Bitbucket Cloud stopped exposing user email addresses on its API in 2018, so those actors resolve by display name. Commits are the exception — their git identity includes an address, so commit authors resolve by email like any other source.
- Review activity is polled, not backfilled. Approvals and change requests cost one request per pull request, so they are collected on the ongoing poll (capped per repository per tick) and skipped during the initial backfill. The pull-request lifecycle events covering the same people and PRs are backfilled as normal.