Skip to content

Add Bitbucket API token (Bearer) authentication support - #27

Open
aleks-romanov wants to merge 12 commits into
jenkinsci:masterfrom
aleks-romanov:feature/bitbucket-token-auth
Open

Add Bitbucket API token (Bearer) authentication support#27
aleks-romanov wants to merge 12 commits into
jenkinsci:masterfrom
aleks-romanov:feature/bitbucket-token-auth

Conversation

@aleks-romanov

Copy link
Copy Markdown

Why
Bitbucket Cloud is transitioning to API tokens to enhance security. As part of this transition, app passwords were fully deprecated on Jul 28, 2026 - Atlassian changelog, CHANGE-3222

That date has already passed. This plugin currently authenticates exclusively via HTTP Basic Auth (bitbucket/ApiClient.java), sourced from either a Jenkins credentialsId (StandardUsernamePasswordCredentials) or the legacy plaintext username/password trigger fields - so this is no longer a future risk, it's a present break: any install of this plugin pointed at Bitbucket Cloud has already lost the ability to authenticate.

This PR adds support for the two token mechanisms Bitbucket offers as the replacement:

  • Bitbucket Cloud Repository/Project/Workspace Access Tokens - the direct motivation for this change.
  • Bitbucket Server/Data Center Personal Access Tokens - unrelated to the Cloud deprecation, but authenticates identically (Authorization: Bearer <token>), so the same mechanism covers it at near-zero marginal cost.

What this adds

  • A BitbucketAuth interface (BasicAuth / BearerAuth implementations) that ApiClient now delegates auth to, instead of embedding HTTP Basic Auth directly in send(). BasicAuth reproduces the existing behavior exactly; BearerAuth sets an Authorization: Bearer <token> header and touches nothing else.
  • BitbucketRepository resolves the configured Jenkins credential to whichever BitbucketAuth fits: StandardUsernamePasswordCredentialsBasicAuth as before; StringCredentials ("Secret text", from the new plain-credentials dependency) → BearerAuth.
  • The credentialsId dropdown is widened to list both credential kinds - no new UI fields.
  • help-credentialsId.html documents the two credential kinds and a token-scoping caveat.

Backward compatibility
No existing configuration changes behavior - Username/Password credentials, the legacy plaintext trigger fields, the Pipeline step's username/password args, and Server/DC installs are all unchanged. No HTTP client library upgrade.

Testing

  • 31 tests passing (mvn install), including new coverage for BasicAuth/BearerAuth in isolation, credential-type resolution across both Cloud and Server/DC, and the widened dropdown against a real Jenkins credential store.
  • Found and fixed a pre-existing gap along the way: several tests couldn't actually fail on a wrong captured credential value (a JUnit assertion failure and a deliberate "abort" throw were indistinguishable AssertionErrors) - replaced with a sentinel exception + capture-then-assert pattern, verified by deliberately breaking an assertion and confirming a real failure.
  • Smoke-tested the built .hpi against a real Jenkins 2.555.2 + plain-credentials 199.v9f8e1f741799 (Docker) - confirmed clean load and correct dropdown behavior against production classes, not just this plugin's older parent-POM baseline.

Also included: CI + local testing setup
Unrelated to the auth changes above, bundled here because it was built and verified against this same branch's artifact:

  • .github/workflows/ci.yml - this repo currently has no working CI (.travis.yml is dead; the Jenkinsfile only activates once hosted under ci.jenkins.io). Adds a GitHub Actions build that runs on every push/PR, inside the same maven:3.6.3-jdk-8 environment this plugin already requires.
  • docker/Dockerfile - builds a Jenkins instance with the plugin pre-installed, for testing against a specific real Jenkins/plugin version. Generic (EXTRA_PLUGINS build arg), not specific to this PR's plain-credentials dependency. Built and ran it against Jenkins 2.555.2 + plain-credentials 199.v9f8e1f741799 using this branch's actual built .hpi - confirmed clean boot and the plugin loading correctly.
  • README - dead Travis badge replaced with the new CI badge.

Notes for reviewers

  • New dependency: org.jenkins-ci.plugins:plain-credentials:1.4.
  • Deliberately out of scope: Atlassian account-level API tokens (Jira/Confluence-style), and any Java-version/build-baseline migration.
  • Happy to adjust scope, naming, or split this into smaller PRs if that's easier to review.

Note on how this was built
Developed with Claude Code. I reviewed and directed the design and implementation throughout, including the live testing in the Testing section above. Verification was an actual Docker run against the actual built artifact, not a claim taken on faith.

Submitter checklist

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests that demonstrate the feature works or the issue is fixed

.travis.yml is dead (Travis killed free OSS builds years ago, and the
badge even pointed at the wrong org). The Jenkinsfile only builds once
this repo is hosted under jenkinsci and picked up by ci.jenkins.io,
which doesn't help right now. This adds a working CI that runs today.

- .github/workflows/ci.yml: builds and tests inside maven:3.6.3-jdk-8
  on every push to master and every PR (this plugin's old parent POM
  breaks maven-enforcer-plugin under JDK 9+, so this pins the same
  JDK 8 environment already used for local development). Caches the
  local Maven repo and uploads the built .hpi as a workflow artifact.
- docker/Dockerfile: builds a Jenkins instance with the plugin
  pre-installed, for testing against a specific real Jenkins/plugin
  version rather than this plugin's own old baseline. Generic across
  branches - extra plugin dependencies (e.g. this branch's
  plain-credentials) are supplied via an EXTRA_PLUGINS build arg, not
  hardcoded. Standard Jenkins security/setup-wizard flow, nothing
  disabled or pre-configured. Built and ran it end-to-end (Jenkins
  2.555.2, plain-credentials 199.v9f8e1f741799, this branch's actual
  .hpi) to confirm it actually works, not just that it builds.
- README: replaces the dead Travis badge with the new CI badge.
…g/api

The legacy bitbucket.org/api/2.0 alias rejects Bearer-token auth with a
401 even with a valid, correctly-scoped
token. Confirmed against a real Bitbucket Cloud workspace: the same
token succeeds on api.bitbucket.org and fails on bitbucket.org/api on
every request.
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.

1 participant