diff --git a/app/assets/javascripts/work_items/components/shared/work_item_sidebar_dropdown_widget.vue b/app/assets/javascripts/work_items/components/shared/work_item_sidebar_dropdown_widget.vue
index 55e4de8183b3d0642698948783f3b61c618a3e59..28e70cc5636e20c8241306fd520b9b439a6ebde1 100644
--- a/app/assets/javascripts/work_items/components/shared/work_item_sidebar_dropdown_widget.vue
+++ b/app/assets/javascripts/work_items/components/shared/work_item_sidebar_dropdown_widget.vue
@@ -1,7 +1,16 @@
 <script>
-import { GlButton, GlForm, GlLoadingIcon, GlCollapsibleListbox } from '@gitlab/ui';
+import {
+  GlButton,
+  GlForm,
+  GlLoadingIcon,
+  GlCollapsibleListbox,
+  GlTooltipDirective,
+} from '@gitlab/ui';
 import { isEmpty, debounce } from 'lodash';
 import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
+import { sanitize } from '~/lib/dompurify';
+import { shouldDisableShortcuts } from '~/behaviors/shortcuts/shortcuts_toggle';
+import { keysFor } from '~/behaviors/shortcuts/keybindings';
 
 import { s__, __, sprintf } from '~/locale';
 
@@ -19,6 +28,9 @@ export default {
     GlForm,
     GlCollapsibleListbox,
   },
+  directives: {
+    GlTooltip: GlTooltipDirective,
+  },
   props: {
     canUpdate: {
       type: Boolean,
@@ -108,6 +120,11 @@ export default {
       required: false,
       default: __('Search'),
     },
+    shortcut: {
+      type: Object,
+      required: false,
+      default: () => ({}),
+    },
   },
   data() {
     return {
@@ -131,6 +148,22 @@ export default {
         ? sprintf(__(`No %{label}`), { label: this.dropdownLabel.toLowerCase() })
         : this.toggleDropdownText;
     },
+    disableShortcuts() {
+      return shouldDisableShortcuts() || Object.keys(this.shortcut).length === 0;
+    },
+    shortcutDescription() {
+      return this.disableShortcuts ? null : this.shortcut.description;
+    },
+    shortcutKey() {
+      return this.disableShortcuts ? null : keysFor(this.shortcut)[0];
+    },
+    tooltipText() {
+      const description = this.shortcutDescription;
+      const key = this.shortcutKey;
+      return this.disableShortcuts
+        ? null
+        : sanitize(`${description} <kbd class="flat gl-ml-1" aria-hidden=true>${key}</kbd>`);
+    },
   },
   watch: {
     itemValue: {
@@ -198,6 +231,8 @@ export default {
       <gl-loading-icon v-if="updateInProgress" />
       <gl-button
         v-if="canUpdate && !isEditing"
+        v-gl-tooltip.viewport.html
+        :title="tooltipText"
         data-testid="edit-button"
         category="tertiary"
         size="small"
diff --git a/app/assets/javascripts/work_items/components/work_item_assignees.vue b/app/assets/javascripts/work_items/components/work_item_assignees.vue
index 73f882bc94678244c593298cf582a615ddeeba5d..9a0c646381e7361ec6bf68fd8a1ef81b382ec5f1 100644
--- a/app/assets/javascripts/work_items/components/work_item_assignees.vue
+++ b/app/assets/javascripts/work_items/components/work_item_assignees.vue
@@ -10,6 +10,7 @@ import UncollapsedAssigneeList from '~/sidebar/components/assignees/uncollapsed_
 import WorkItemSidebarDropdownWidget from '~/work_items/components/shared/work_item_sidebar_dropdown_widget.vue';
 import { s__, sprintf, __ } from '~/locale';
 import Tracking from '~/tracking';
+import { ISSUE_MR_CHANGE_ASSIGNEE } from '~/behaviors/shortcuts/keybindings';
 import updateWorkItemMutation from '../graphql/update_work_item.mutation.graphql';
 import updateNewWorkItemMutation from '../graphql/update_new_work_item.mutation.graphql';
 import { i18n, TRACKING_CATEGORY_SHOW } from '../constants';
@@ -79,6 +80,7 @@ export default {
       currentUser: null,
       updateInProgress: false,
       localUsers: [],
+      shortcut: ISSUE_MR_CHANGE_ASSIGNEE,
     };
   },
   apollo: {
@@ -337,6 +339,7 @@ export default {
     :header-text="headerText"
     :update-in-progress="updateInProgress"
     :reset-button-label="__('Clear')"
+    :shortcut="shortcut"
     clear-search-on-item-select
     data-testid="work-item-assignees"
     @dropdownShown="onDropdownShown"
diff --git a/app/assets/javascripts/work_items/components/work_item_detail.vue b/app/assets/javascripts/work_items/components/work_item_detail.vue
index 5267b10620d6a51758d04672c59988e427252602..c60c93dee0a8cba2ba7b0be92efcc45e08655226 100644
--- a/app/assets/javascripts/work_items/components/work_item_detail.vue
+++ b/app/assets/javascripts/work_items/components/work_item_detail.vue
@@ -18,6 +18,9 @@ import { TYPENAME_GROUP } from '~/graphql_shared/constants';
 import { isLoggedIn } from '~/lib/utils/common_utils';
 import { WORKSPACE_PROJECT } from '~/issues/constants';
 import { addShortcutsExtension } from '~/behaviors/shortcuts';
+import { sanitize } from '~/lib/dompurify';
+import { shouldDisableShortcuts } from '~/behaviors/shortcuts/shortcuts_toggle';
+import { keysFor, ISSUABLE_EDIT_DESCRIPTION } from '~/behaviors/shortcuts/keybindings';
 import ShortcutsWorkItems from '~/behaviors/shortcuts/shortcuts_work_items';
 import {
   i18n,
@@ -462,6 +465,16 @@ export default {
     shouldShowEditButton() {
       return !this.editMode && this.canUpdate;
     },
+    editShortcutKey() {
+      return shouldDisableShortcuts() ? null : keysFor(ISSUABLE_EDIT_DESCRIPTION)[0];
+    },
+    editTooltip() {
+      const description = __('Edit title and description');
+      const key = this.editShortcutKey;
+      return shouldDisableShortcuts()
+        ? description
+        : sanitize(`${description} <kbd class="flat gl-ml-1" aria-hidden=true>${key}</kbd>`);
+    },
     modalCloseButtonClass() {
       return {
         'sm:gl-hidden': !this.error,
@@ -933,6 +946,8 @@ export default {
             <div class="gl-ml-auto gl-mt-1 gl-flex gl-gap-3 gl-self-start">
               <gl-button
                 v-if="shouldShowEditButton"
+                v-gl-tooltip.bottom.html
+                :title="editTooltip"
                 category="secondary"
                 data-testid="work-item-edit-form-button"
                 class="shortcut-edit-wi-description"
diff --git a/app/assets/javascripts/work_items/components/work_item_labels.vue b/app/assets/javascripts/work_items/components/work_item_labels.vue
index 9e6d88687bf39f191926372944519dc1a42a3888..295fbf902d56ac9df24f03315bd718b650f84cbb 100644
--- a/app/assets/javascripts/work_items/components/work_item_labels.vue
+++ b/app/assets/javascripts/work_items/components/work_item_labels.vue
@@ -10,6 +10,7 @@ import groupLabelsQuery from '~/sidebar/components/labels/labels_select_widget/g
 import projectLabelsQuery from '~/sidebar/components/labels/labels_select_widget/graphql/project_labels.query.graphql';
 import { isScopedLabel } from '~/lib/utils/common_utils';
 import Tracking from '~/tracking';
+import { ISSUABLE_CHANGE_LABEL } from '~/behaviors/shortcuts/keybindings';
 import workItemByIidQuery from '../graphql/work_item_by_iid.query.graphql';
 import updateWorkItemMutation from '../graphql/update_work_item.mutation.graphql';
 import updateNewWorkItemMutation from '../graphql/update_new_work_item.mutation.graphql';
@@ -72,6 +73,7 @@ export default {
       addLabelIds: [],
       labelsCache: [],
       labelsToShowAtTopOfTheListbox: [],
+      shortcut: ISSUABLE_CHANGE_LABEL,
     };
   },
   computed: {
@@ -334,6 +336,7 @@ export default {
     :toggle-dropdown-text="dropdownText"
     :header-text="__('Select labels')"
     :reset-button-label="__('Clear')"
+    :shortcut="shortcut"
     show-footer
     multi-select
     clear-search-on-item-select
diff --git a/app/assets/javascripts/work_items/components/work_item_milestone.vue b/app/assets/javascripts/work_items/components/work_item_milestone.vue
index 26eb8a9abe1bc38884b4a187a27234f293a419c8..8a7fd3ba8aa319246618d6e2e0c9857d35482ca0 100644
--- a/app/assets/javascripts/work_items/components/work_item_milestone.vue
+++ b/app/assets/javascripts/work_items/components/work_item_milestone.vue
@@ -7,6 +7,7 @@ import { getIdFromGraphQLId } from '~/graphql_shared/utils';
 import { s__, __ } from '~/locale';
 import { MILESTONE_STATE } from '~/sidebar/constants';
 import WorkItemSidebarDropdownWidget from '~/work_items/components/shared/work_item_sidebar_dropdown_widget.vue';
+import { ISSUE_MR_CHANGE_MILESTONE } from '~/behaviors/shortcuts/keybindings';
 import projectMilestonesQuery from '~/sidebar/queries/project_milestones.query.graphql';
 import groupMilestonesQuery from '~/sidebar/queries/group_milestones.query.graphql';
 import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutation.graphql';
@@ -68,6 +69,7 @@ export default {
       updateInProgress: false,
       milestones: [],
       localMilestone: this.workItemMilestone,
+      shortcut: ISSUE_MR_CHANGE_MILESTONE,
     };
   },
   computed: {
@@ -235,6 +237,7 @@ export default {
     :toggle-dropdown-text="dropdownText"
     :header-text="__('Select milestone')"
     :reset-button-label="__('Clear')"
+    :shortcut="shortcut"
     data-testid="work-item-milestone"
     @dropdownShown="onDropdownShown"
     @searchStarted="search"
diff --git a/spec/frontend/work_items/components/shared/work_item_sidebar_dropdown_widget_spec.js b/spec/frontend/work_items/components/shared/work_item_sidebar_dropdown_widget_spec.js
index 7893a75b5b4228ff11f5f5c9348fc0dd1ae38081..485939f4e44eae079709cc1f71bfa0762dcf6a80 100644
--- a/spec/frontend/work_items/components/shared/work_item_sidebar_dropdown_widget_spec.js
+++ b/spec/frontend/work_items/components/shared/work_item_sidebar_dropdown_widget_spec.js
@@ -2,8 +2,13 @@ import { GlForm, GlCollapsibleListbox, GlLoadingIcon } from '@gitlab/ui';
 import { nextTick } from 'vue';
 import { mountExtended } from 'helpers/vue_test_utils_helper';
 import { groupIterationsResponse } from 'jest/work_items/mock_data';
+import { shouldDisableShortcuts } from '~/behaviors/shortcuts/shortcuts_toggle';
+import { keysFor } from '~/behaviors/shortcuts/keybindings';
 import WorkItemSidebarDropdownWidget from '~/work_items/components/shared/work_item_sidebar_dropdown_widget.vue';
 
+jest.mock('~/behaviors/shortcuts/shortcuts_toggle');
+jest.mock('~/behaviors/shortcuts/keybindings');
+
 describe('WorkItemSidebarDropdownWidget component', () => {
   let wrapper;
 
@@ -28,6 +33,7 @@ describe('WorkItemSidebarDropdownWidget component', () => {
     infiniteScrollLoading = false,
     clearSearchOnItemSelect = false,
     listItems = [],
+    shortcut = undefined,
   } = {}) => {
     wrapper = mountExtended(WorkItemSidebarDropdownWidget, {
       propsData: {
@@ -43,6 +49,7 @@ describe('WorkItemSidebarDropdownWidget component', () => {
         infiniteScroll,
         infiniteScrollLoading,
         clearSearchOnItemSelect,
+        shortcut,
       },
       slots,
     });
@@ -257,4 +264,47 @@ describe('WorkItemSidebarDropdownWidget component', () => {
       });
     });
   });
+  describe('shortcut tooltip', () => {
+    const shortcut = {
+      description: 'Edit dropdown',
+    };
+
+    beforeEach(() => {
+      shouldDisableShortcuts.mockReturnValue(false);
+      keysFor.mockReturnValue(['e']);
+    });
+
+    afterEach(() => {
+      jest.clearAllMocks();
+    });
+
+    it('shows tooltip with key when shortcut is provided', () => {
+      createComponent({
+        canUpdate: true,
+        shortcut,
+      });
+      const expectedTooltip = 'Edit dropdown <kbd aria-hidden="true" class="flat gl-ml-1">e</kbd>';
+
+      expect(findEditButton().attributes('title')).toContain(expectedTooltip);
+    });
+
+    it('does not show tooltip when shortcut is not provided', () => {
+      createComponent({
+        canUpdate: true,
+      });
+
+      expect(findEditButton().attributes('title')).toBeUndefined();
+    });
+
+    it('does not show tooltip when shortcuts are disabled', () => {
+      shouldDisableShortcuts.mockReturnValue(true);
+
+      createComponent({
+        canUpdate: true,
+        shortcut,
+      });
+
+      expect(findEditButton().attributes('title')).toBeUndefined();
+    });
+  });
 });
diff --git a/spec/frontend/work_items/components/work_item_assignees_spec.js b/spec/frontend/work_items/components/work_item_assignees_spec.js
index aba02393fd0c6ec755027066de707335fff764d7..b74f6f810db901f329bc1428a4c8aecd6d3380d8 100644
--- a/spec/frontend/work_items/components/work_item_assignees_spec.js
+++ b/spec/frontend/work_items/components/work_item_assignees_spec.js
@@ -26,6 +26,7 @@ import {
   workItemResponseFactory,
 } from 'jest/work_items/mock_data';
 import { i18n, TRACKING_CATEGORY_SHOW, NEW_WORK_ITEM_IID } from '~/work_items/constants';
+import { ISSUE_MR_CHANGE_ASSIGNEE } from '~/behaviors/shortcuts/keybindings';
 
 describe('WorkItemAssignees component', () => {
   Vue.use(VueApollo);
@@ -126,6 +127,12 @@ describe('WorkItemAssignees component', () => {
     expect(findSidebarDropdownWidget().props('dropdownLabel')).toBe('Assignee');
   });
 
+  it('has key shortcut tooltip', () => {
+    createComponent();
+
+    expect(findSidebarDropdownWidget().props('shortcut')).toBe(ISSUE_MR_CHANGE_ASSIGNEE);
+  });
+
   describe('Dropdown search', () => {
     it('shows no items in the dropdown when no results matching', async () => {
       createComponent({ searchQueryHandler: successSearchWithNoMatchingUsers });
diff --git a/spec/frontend/work_items/components/work_item_detail_spec.js b/spec/frontend/work_items/components/work_item_detail_spec.js
index b393932ebfd571e685a2f8ed61a9b7a1491f5760..68801489953ff21c945ae2debd50ded1b405f1ca 100644
--- a/spec/frontend/work_items/components/work_item_detail_spec.js
+++ b/spec/frontend/work_items/components/work_item_detail_spec.js
@@ -1141,6 +1141,7 @@ describe('WorkItemDetail component', () => {
 
       it('shows the edit button', () => {
         expect(findEditButton().exists()).toBe(true);
+        expect(findEditButton().attributes('title')).toContain('Edit title and description');
       });
 
       it('renders the work item title with edit component', () => {
diff --git a/spec/frontend/work_items/components/work_item_labels_spec.js b/spec/frontend/work_items/components/work_item_labels_spec.js
index 4e36531bc061d98f7a3d65e2102ea95caee57894..e389637cd500ea9b2e8fb2a6cff010801ec18c9a 100644
--- a/spec/frontend/work_items/components/work_item_labels_spec.js
+++ b/spec/frontend/work_items/components/work_item_labels_spec.js
@@ -13,6 +13,7 @@ import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutati
 import workItemByIidQuery from '~/work_items/graphql/work_item_by_iid.query.graphql';
 import WorkItemLabels from '~/work_items/components/work_item_labels.vue';
 import WorkItemSidebarDropdownWidget from '~/work_items/components/shared/work_item_sidebar_dropdown_widget.vue';
+import { ISSUABLE_CHANGE_LABEL } from '~/behaviors/shortcuts/keybindings';
 import {
   projectLabelsResponse,
   groupLabelsResponse,
@@ -145,6 +146,7 @@ describe('WorkItemLabels component', () => {
       multiSelect: true,
       showFooter: true,
       itemValue: [],
+      shortcut: ISSUABLE_CHANGE_LABEL,
     });
     expect(findAllLabels()).toHaveLength(0);
   });
diff --git a/spec/frontend/work_items/components/work_item_milestone_spec.js b/spec/frontend/work_items/components/work_item_milestone_spec.js
index 3e361f344d80d42503f32d34f96d7964bcef03a5..00b3fd8ad2c44aba9d6399183517120db00e3c5e 100644
--- a/spec/frontend/work_items/components/work_item_milestone_spec.js
+++ b/spec/frontend/work_items/components/work_item_milestone_spec.js
@@ -10,6 +10,7 @@ import waitForPromises from 'helpers/wait_for_promises';
 import { TRACKING_CATEGORY_SHOW } from '~/work_items/constants';
 import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutation.graphql';
 import projectMilestonesQuery from '~/sidebar/queries/project_milestones.query.graphql';
+import { ISSUE_MR_CHANGE_MILESTONE } from '~/behaviors/shortcuts/keybindings';
 import {
   projectMilestonesResponse,
   projectMilestonesResponseWithNoMilestones,
@@ -68,6 +69,12 @@ describe('WorkItemMilestone component', () => {
     expect(findSidebarDropdownWidget().props('dropdownLabel')).toBe('Milestone');
   });
 
+  it('has key shortcut tooltip', () => {
+    createComponent();
+
+    expect(findSidebarDropdownWidget().props('shortcut')).toBe(ISSUE_MR_CHANGE_MILESTONE);
+  });
+
   describe('Default text with canUpdate false and milestone value', () => {
     describe.each`
       description             | milestone                      | value