diff --git a/lib/modules/platform/bitbucket/__snapshots__/index.spec.ts.snap b/lib/modules/platform/bitbucket/__snapshots__/index.spec.ts.snap
index 1a100b3d1972da49d1c17d5e5f802925956530f9..d85ff37cef732a00095ad5e713e5b121c5f54b58 100644
--- a/lib/modules/platform/bitbucket/__snapshots__/index.spec.ts.snap
+++ b/lib/modules/platform/bitbucket/__snapshots__/index.spec.ts.snap
@@ -144,13 +144,7 @@ exports[`modules/platform/bitbucket/index getPrList() filters PR list by author
 ]
 `;
 
-exports[`modules/platform/bitbucket/index initPlatform() should init 1`] = `
-{
-  "endpoint": "https://api.bitbucket.org/",
-}
-`;
-
-exports[`modules/platform/bitbucket/index initRepo() works 1`] = `
+exports[`modules/platform/bitbucket/index initRepo() works with username and password 1`] = `
 {
   "defaultBranch": "master",
   "isFork": false,
diff --git a/lib/modules/platform/bitbucket/index.spec.ts b/lib/modules/platform/bitbucket/index.spec.ts
index f4cb3b0685b9897933c45a9c13f8e702ce6cbf6d..16dafb7141e89f0abef13cffa8c7ea7568080a1a 100644
--- a/lib/modules/platform/bitbucket/index.spec.ts
+++ b/lib/modules/platform/bitbucket/index.spec.ts
@@ -3,7 +3,7 @@ import type { logger as _logger } from '../../../logger';
 import { BranchStatus, PrState } from '../../../types';
 import type * as _git from '../../../util/git';
 import { setBaseUrl } from '../../../util/http/bitbucket';
-import type { Platform, RepoParams } from '../types';
+import type { Platform, PlatformResult, RepoParams } from '../types';
 
 const baseUrl = 'https://api.bitbucket.org';
 
@@ -69,7 +69,7 @@ describe('modules/platform/bitbucket/index', () => {
   }
 
   describe('initPlatform()', () => {
-    it('should throw if no username/password', async () => {
+    it('should throw if no token or username/password', async () => {
       expect.assertions(1);
       await expect(bitbucket.initPlatform({})).rejects.toThrow();
     });
@@ -85,14 +85,31 @@ describe('modules/platform/bitbucket/index', () => {
       );
     });
 
-    it('should init', async () => {
+    it('should init with username/password', async () => {
+      const expectedResult: PlatformResult = {
+        endpoint: baseUrl,
+      };
       httpMock.scope(baseUrl).get('/2.0/user').reply(200);
       expect(
         await bitbucket.initPlatform({
+          endpoint: baseUrl,
           username: 'abc',
           password: '123',
         })
-      ).toMatchSnapshot();
+      ).toEqual(expectedResult);
+    });
+
+    it('should init with only token', async () => {
+      const expectedResult: PlatformResult = {
+        endpoint: baseUrl,
+      };
+      httpMock.scope(baseUrl).get('/2.0/user').reply(200);
+      expect(
+        await bitbucket.initPlatform({
+          endpoint: baseUrl,
+          token: 'abc',
+        })
+      ).toEqual(expectedResult);
     });
 
     it('should warn for missing "profile" scope', async () => {
@@ -121,7 +138,7 @@ describe('modules/platform/bitbucket/index', () => {
   });
 
   describe('initRepo()', () => {
-    it('works', async () => {
+    it('works with username and password', async () => {
       httpMock
         .scope(baseUrl)
         .get('/2.0/repositories/some/repo')
@@ -132,6 +149,27 @@ describe('modules/platform/bitbucket/index', () => {
         })
       ).toMatchSnapshot();
     });
+
+    it('works with only token', async () => {
+      hostRules.clear();
+      hostRules.find.mockReturnValue({
+        token: 'abc',
+      });
+      httpMock
+        .scope(baseUrl)
+        .get('/2.0/repositories/some/repo')
+        .reply(200, { owner: {}, mainbranch: { name: 'master' } });
+      expect(
+        await bitbucket.initRepo({
+          repository: 'some/repo',
+        })
+      ).toEqual({
+        defaultBranch: 'master',
+        isFork: false,
+        repoFingerprint:
+          '56653db0e9341ef4957c92bb78ee668b0a3f03c75b77db94d520230557385fca344cc1f593191e3594183b5b050909d29996c040045e8852f21774617b240642',
+      });
+    });
   });
 
   describe('getRepoForceRebase()', () => {
diff --git a/lib/modules/platform/bitbucket/index.ts b/lib/modules/platform/bitbucket/index.ts
index d68db6debe1b612894c7413526b33e684eb580c2..299a39e6d1acaf4ba916675ea61a65f27c5e568b 100644
--- a/lib/modules/platform/bitbucket/index.ts
+++ b/lib/modules/platform/bitbucket/index.ts
@@ -8,6 +8,7 @@ import { BranchStatus, PrState, VulnerabilityAlert } from '../../../types';
 import * as git from '../../../util/git';
 import * as hostRules from '../../../util/host-rules';
 import { BitbucketHttp, setBaseUrl } from '../../../util/http/bitbucket';
+import type { HttpOptions } from '../../../util/http/types';
 import { regEx } from '../../../util/regex';
 import { sanitize } from '../../../util/sanitize';
 import type {
@@ -55,10 +56,11 @@ export async function initPlatform({
   endpoint,
   username,
   password,
+  token,
 }: PlatformParams): Promise<PlatformResult> {
-  if (!(username && password)) {
+  if (!(username && password) && !token) {
     throw new Error(
-      'Init: You must configure a Bitbucket username and password'
+      'Init: You must configure either a Bitbucket token or username and password'
     );
   }
   if (endpoint && endpoint !== BITBUCKET_PROD_ENDPOINT) {
@@ -69,13 +71,18 @@ export async function initPlatform({
   }
   setBaseUrl(defaults.endpoint);
   renovateUserUuid = null;
+  const options: HttpOptions = {
+    useCache: false,
+  };
+  if (token) {
+    options.token = token;
+  } else {
+    options.username = username;
+    options.password = password;
+  }
   try {
     const { uuid } = (
-      await bitbucketHttp.getJson<Account>('/2.0/user', {
-        username,
-        password,
-        useCache: false,
-      })
+      await bitbucketHttp.getJson<Account>('/2.0/user', options)
     ).body;
     renovateUserUuid = uuid;
   } catch (err) {
@@ -193,11 +200,12 @@ export async function initRepo({
   // TODO #7154
   const hostnameWithoutApiPrefix = regEx(/api[.|-](.+)/).exec(hostname!)?.[1];
 
+  const auth = opts.token
+    ? `x-token-auth:${opts.token}`
+    : `${opts.username!}:${opts.password!}`;
   const url = git.getUrl({
     protocol: 'https',
-    // TODO: types (#7154)
-    // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
-    auth: `${opts.username}:${opts.password}`,
+    auth,
     hostname: hostnameWithoutApiPrefix,
     repository,
   });