diff --git a/lib/modules/platform/azure/index.spec.ts b/lib/modules/platform/azure/index.spec.ts
index c234df87956723760c9fbdd3b7407715556039a9..08774ad666b73fd29c83ce5a2252572c4864f5d3 100644
--- a/lib/modules/platform/azure/index.spec.ts
+++ b/lib/modules/platform/azure/index.spec.ts
@@ -1087,10 +1087,11 @@ describe('modules/platform/azure/index', () => {
 
   describe('massageMarkdown(input)', () => {
     it('returns updated pr body', () => {
-      const input =
-        '\n---\n\n - [ ] <!-- rebase-check --> rebase\nplus also [a link](https://github.com/foo/bar/issues/5)';
-      expect(azure.massageMarkdown(input)).toMatchInlineSnapshot(
-        `"plus also [a link](https://github.com/foo/bar/issues/5)"`
+      const prBody =
+        '\n---\n\n - [ ] <!-- rebase-check --> rebase\n<!--renovate-config-hash:-->' +
+        'plus also [a link](https://github.com/foo/bar/issues/5)';
+      expect(azure.massageMarkdown(prBody)).toBe(
+        'plus also [a link](https://github.com/foo/bar/issues/5)'
       );
     });
   });
diff --git a/lib/modules/platform/azure/index.ts b/lib/modules/platform/azure/index.ts
index 51191062354e8afbd255b716ed4a54ba7b505e41..0730237afb6dc7d96bf14fbe638b76c1d871cd90 100644
--- a/lib/modules/platform/azure/index.ts
+++ b/lib/modules/platform/azure/index.ts
@@ -746,7 +746,7 @@ export function massageMarkdown(input: string): string {
       'rename PR to start with "rebase!"'
     )
     .replace(regEx(`\n---\n\n.*?<!-- rebase-check -->.*?\n`), '')
-    .replace(regEx(/<!--renovate-debug:.*?-->/), '');
+    .replace(regEx(/<!--renovate-(?:debug|config-hash):.*?-->/g), '');
 }
 
 /* istanbul ignore next */
diff --git a/lib/modules/platform/bitbucket/index.spec.ts b/lib/modules/platform/bitbucket/index.spec.ts
index 35aef41c28d062a27d868769791e95efb0b96f64..ceb70ab7a7dfe04bed8af5b088412f3074770f42 100644
--- a/lib/modules/platform/bitbucket/index.spec.ts
+++ b/lib/modules/platform/bitbucket/index.spec.ts
@@ -996,11 +996,10 @@ describe('modules/platform/bitbucket/index', () => {
 
   describe('massageMarkdown()', () => {
     it('returns diff files', () => {
-      expect(
-        bitbucket.massageMarkdown(
-          '<details><summary>foo</summary>bar</details>text<details>'
-        )
-      ).toMatchSnapshot();
+      const prBody =
+        '<details><summary>foo</summary>bar</details>text<details>' +
+        '\n---\n\n - [ ] <!-- rebase-check --> rebase\n<!--renovate-config-hash:-->';
+      expect(bitbucket.massageMarkdown(prBody)).toMatchSnapshot();
     });
   });
 
diff --git a/lib/modules/platform/bitbucket/index.ts b/lib/modules/platform/bitbucket/index.ts
index b839c2ecdf4a9ef6b645ded12a1d091ee864f5d7..6d63ecf1a2775a108559f2813176308a878566d0 100644
--- a/lib/modules/platform/bitbucket/index.ts
+++ b/lib/modules/platform/bitbucket/index.ts
@@ -488,7 +488,7 @@ export function massageMarkdown(input: string): string {
     .replace(regEx(/<\/?details>/g), '')
     .replace(regEx(`\n---\n\n.*?<!-- rebase-check -->.*?\n`), '')
     .replace(regEx(/\]\(\.\.\/pull\//g), '](../../pull-requests/')
-    .replace(regEx(/<!--renovate-debug:.*?-->/), '');
+    .replace(regEx(/<!--renovate-(?:debug|config-hash):.*?-->/g), '');
 }
 
 export async function ensureIssue({
diff --git a/lib/modules/platform/pr-body.spec.ts b/lib/modules/platform/pr-body.spec.ts
index 1439ee61569fb6c86d71f016d137026cc7e7a05c..89967f8a31d96fb3e48f31f362eebdfc28a88838 100644
--- a/lib/modules/platform/pr-body.spec.ts
+++ b/lib/modules/platform/pr-body.spec.ts
@@ -1,3 +1,4 @@
+import hasha from 'hasha';
 import { getPrBodyStruct, hashBody } from './pr-body';
 
 describe('modules/platform/pr-body', () => {
@@ -47,13 +48,50 @@ describe('modules/platform/pr-body', () => {
       );
     });
 
-    it('returns rebaseRequested flag', () => {
-      expect(getPrBodyStruct('- [x] <!-- rebase-check -->')).toEqual({
-        hash: '023952693e1e00a52a71b65d9b4804bca6ca9f215c20f6e029dbf420f322d541',
+    it('hashes an undefined body', () => {
+      // nullish operator branch coverage
+      const hash =
+        'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
+      expect(hashBody(undefined)).toBe(hash);
+    });
+
+    it('returns rebaseRequested=true flag', () => {
+      const input = '- [x] <!-- rebase-check -->';
+      const hash = hashBody(input);
+      expect(getPrBodyStruct(input)).toEqual({
+        hash,
         rebaseRequested: true,
       });
     });
 
+    it('returns rebaseRequested=false flag', () => {
+      const input = '- [ ] <!-- rebase-check -->';
+      const hash = hashBody(input);
+      expect(getPrBodyStruct(input)).toEqual({
+        hash,
+        rebaseRequested: false,
+      });
+    });
+
+    it('returns rebaseRequested=undefined flag', () => {
+      const input = '-  <!-- rebase-check -->';
+      const hash = hashBody(input);
+      expect(getPrBodyStruct(input)).toEqual({
+        hash,
+      });
+    });
+
+    it('returns raw config hash', () => {
+      const config = '{}';
+      const rawConfigHash = hasha(config, { algorithm: 'sha256' });
+      const input = `<!--renovate-config-hash:${rawConfigHash}-->`;
+      const hash = hashBody(input);
+      expect(getPrBodyStruct(input)).toEqual({
+        hash,
+        rawConfigHash,
+      });
+    });
+
     it('strips reviewable section', () => {
       expect(getPrBodyStruct('foo<!-- Reviewable:start -->bar')).toEqual({
         hash: hashBody('foo'),
diff --git a/lib/modules/platform/pr-body.ts b/lib/modules/platform/pr-body.ts
index 5fe70dd8dd3aea927d4fb1910e7912f5dd958d54..88f28826bcd73a17b4e58918971f94cf744ee755 100644
--- a/lib/modules/platform/pr-body.ts
+++ b/lib/modules/platform/pr-body.ts
@@ -1,3 +1,4 @@
+import is from '@sindresorhus/is';
 import hasha from 'hasha';
 import { logger } from '../../logger';
 import { stripEmojis } from '../../util/emoji';
@@ -9,6 +10,12 @@ export const prDebugDataRe = regEx(
   /\n?<!--renovate-debug:(?<payload>.*?)-->\n?/
 );
 
+const renovateConfigHashRe = regEx(
+  /\n?<!--renovate-config-hash:(?<payload>.*?)-->\n?/
+);
+
+const prCheckboxRe = regEx(/- (?<checkbox>\[[\sx]]) <!-- rebase-check -->/);
+
 function noWhitespaceOrHeadings(input: string): string {
   return input.replace(regEx(/\r?\n|\r|\s|#/g), '');
 }
@@ -28,8 +35,12 @@ export function hashBody(body: string | undefined): string {
   return result;
 }
 
-function isRebaseRequested(body: string | undefined): boolean {
-  return !!body?.includes(`- [x] <!-- rebase-check -->`);
+function isRebaseRequested(body: string): boolean | undefined {
+  const match = prCheckboxRe.exec(body);
+  if (!match) {
+    return undefined;
+  }
+  return match.groups?.checkbox === '[x]';
 }
 
 export function getRenovateDebugPayload(body: string): string | undefined {
@@ -37,6 +48,11 @@ export function getRenovateDebugPayload(body: string): string | undefined {
   return match?.groups?.payload;
 }
 
+export function getRenovateConfigHashPayload(body: string): string | undefined {
+  const match = renovateConfigHashRe.exec(body);
+  return match?.groups?.payload;
+}
+
 export function getPrBodyStruct(
   input: string | undefined | null
 ): PrBodyStruct {
@@ -45,10 +61,16 @@ export function getPrBodyStruct(
   const result: PrBodyStruct = { hash };
 
   const rebaseRequested = isRebaseRequested(body);
-  if (rebaseRequested) {
+
+  if (!is.undefined(rebaseRequested)) {
     result.rebaseRequested = rebaseRequested;
   }
 
+  const rawConfigHash = getRenovateConfigHashPayload(body);
+  if (rawConfigHash) {
+    result.rawConfigHash = rawConfigHash;
+  }
+
   const debugPayload = getRenovateDebugPayload(body);
   if (debugPayload) {
     try {
diff --git a/lib/modules/platform/types.ts b/lib/modules/platform/types.ts
index ff2b266f2c814fa3665db3479ea189bbd85c7243..56a625eab08735782527800302c1a04f4c3590be 100644
--- a/lib/modules/platform/types.ts
+++ b/lib/modules/platform/types.ts
@@ -52,6 +52,7 @@ export interface PrDebugData {
 
 export interface PrBodyStruct {
   hash: string;
+  rawConfigHash?: string;
   rebaseRequested?: boolean;
   debugData?: PrDebugData;
 }