Skip to content

fix(git-token-service): restore Bitbucket code-review API access - #6130

Merged
eshurakov merged 2 commits into
mainfrom
eshurakov/bitbucket-api-origin
Sep 14, 2026
Merged

fix(git-token-service): restore Bitbucket code-review API access#6130
eshurakov merged 2 commits into
mainfrom
eshurakov/bitbucket-api-origin

Conversation

@eshurakov

Copy link
Copy Markdown
Contributor

Summary

Restores managed Bitbucket code-review sessions, which were running and reporting Completed while posting no PR comments.

Root cause (verified in production). In contained sessions BITBUCKET_TOKEN is an opaque capability (kbb1.…), and every bb request is intercepted and redeemed by the Worker. The bb CLI calls the Bitbucket Cloud REST API at https://api.bitbucket.org, but validateBitbucketCapabilityUpstream only accepted the git origin https://bitbucket.org. Every API read/write was rejected with upstream_origin_not_allowed, the interceptor returned 502, and the CLI collapsed that into bb: provider_unavailable. Git clone/fetch to bitbucket.org still worked, so the workspace cloned and the review then did nothing.

  • Axiom (cloudflare-logpush, cloud-agent-next): Managed Bitbucket outbound redemption rejected, failureStage=redemption-policy, reason=upstream_origin_not_allowed, hundreds/day over the 30-day window (121 on 2026-09-14). Forwarded = target=bitbucket (git); rejected = target=other (api.bitbucket.org), same container.
  • Session ses_f61349404fffAm3oxDuyaWElZg: bb pr view/diff/comments list all returned provider_unavailable. 4/4 recent Bitbucket sessions sampled failed the same way.

Fix — two commits:

  1. aba2d6117 — classify the redeemed upstream as a git or API surface. The API surface requires origin https://api.bitbucket.org and a path under /2.0/repositories/<workspace>/<repo> matching the capability's canonical repository name (exact segment boundary), and returns Bearer <token>; git keeps Basic x-token-auth:<token>. cloud-agent-next needs no change: forwardRedeemedRequest deletes Authorization and applies result.headers.
  2. 94098700e — the %2f|%5c/traversal guard ran against the whole URL including the query string. bb pr current carries the branch name in q=, so a slash branch arrived as %2F and was rejected as invalid_upstream_url. A query string cannot change how the path resolves against the repository prefix, so the guard now scans only the pre-query portion. Path-level rejections are unchanged.

Verification

Automated, run from the worktree:

  • pnpm --filter cloudflare-git-token-service test — 24 files, 646 passed.
  • New tests fail on the pre-fix implementation (red run: API Bearer success and API repository_mismatch cases failed with upstream_origin_not_allowed; the query-%2F test failed with invalid_upstream_url) and pass with the fix.
  • New coverage: API Bearer + sub-resource; repo/workspace/segment-prefix mismatch → repository_mismatch; http, credentials-in-URL, hash, traversal, %2f, %2e%2einvalid_upstream_url; unapproved origin; git smart-HTTP still Basic; encoded slash allowed in the API query string.
  • typecheck exit 0; lint 0 warnings / 0 errors; oxfmt --list-different clean; git diff --check clean.

No manual/end-to-end run: this is an auth path inside the deployed git-token-service, so there is no manual path short of deploying. It only takes effect once deployed.

Visual Changes

N/A

Reviewer Notes

  • The API surface allows any path under the repository prefix, not only the bb endpoints. It is bounded to that repository and the capability's scope; an endpoint allowlist is a hardening follow-up, not required for the fix.
  • The %2f-in-query path (bb pr current/pr create) is latent today: no skill or prompt currently calls those commands, so it is not part of the reported outage.
  • bb collapsing a 5xx and a network failure into the same provider_unavailable string made this slower to localise; a diagnosability follow-up, deliberately out of scope.

…apability

The bb CLI calls https://api.bitbucket.org while the Bitbucket session
capability validator only allowed the git origin https://bitbucket.org,
so every REST API redemption failed with upstream_origin_not_allowed and
reviews collapsed to provider_unavailable.

Classify the redeemed upstream as a git or API surface, validate the API
path under /2.0/repositories/<workspace>/<repo>, and return Bearer auth
for the API surface while keeping Basic x-token-auth for git.
…oded slashes

The %2f/%5c and traversal guard ran against the whole request URL, including
the query string. bb pr current carries the branch name in the q= filter, so a
branch containing a slash arrived as %2F and the redeem rejected it as
invalid_upstream_url, surfacing as bb: provider_unavailable. A query string
cannot change how the path resolves against the repository prefix, so scan only
the pre-query portion. Path-level rejections are unchanged.
@kilo-code-bot

kilo-code-bot Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Reviewed the Bitbucket capability origin allowlist, git/API surface classification, Bearer redemption, and pre-query path guard changes plus the added tests; the origin checks, repository-prefix matching, and traversal/encoded-slash handling are correct and consistent with the current GitLab capability handling.

Files Reviewed (2 files)
  • services/git-token-service/src/index.ts
  • services/git-token-service/src/index.test.ts

Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants