diff --git a/ee/app/assets/javascripts/security_dashboard/components/project/security_training_promo_banner.vue b/ee/app/assets/javascripts/security_dashboard/components/project/security_training_promo_banner.vue
index 1127f623e09b152b8b52030e46d41cfb25eb1bee..9e22deb899efd3a94b821f9e4c0e64ece887481b 100644
--- a/ee/app/assets/javascripts/security_dashboard/components/project/security_training_promo_banner.vue
+++ b/ee/app/assets/javascripts/security_dashboard/components/project/security_training_promo_banner.vue
@@ -1,50 +1,32 @@
 <script>
 import { GlBanner } from '@gitlab/ui';
 import { __ } from '~/locale';
-import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue';
-import Tracking from '~/tracking';
-import {
-  TRACK_PROMOTION_BANNER_CTA_CLICK_ACTION,
-  TRACK_PROMOTION_BANNER_CTA_CLICK_LABEL,
-} from '~/security_configuration/constants';
+import SecurityTrainingPromo from 'ee/vue_shared/security_reports/components/security_training_promo.vue';
 
 export default {
   components: {
     GlBanner,
-    UserCalloutDismisser,
+    SecurityTrainingPromo,
   },
-  mixins: [Tracking.mixin()],
   inject: ['securityConfigurationPath', 'projectFullPath'],
   i18n: {
     title: __('Reduce risk and triage fewer vulnerabilities with security training'),
-    buttonText: __('Enable security training'),
     content: __(
       'Enable security training to help your developers learn how to fix vulnerabilities. Developers can view security training from selected educational providers, relevant to the detected vulnerability.',
     ),
   },
-  computed: {
-    buttonLink() {
-      return `${this.securityConfigurationPath}?tab=vulnerability-management`;
-    },
-  },
-  methods: {
-    trackCTAClick() {
-      this.track(TRACK_PROMOTION_BANNER_CTA_CLICK_ACTION, {
-        label: TRACK_PROMOTION_BANNER_CTA_CLICK_LABEL,
-        property: this.projectFullPath,
-      });
-    },
-  },
 };
 </script>
 
 <template>
-  <user-callout-dismisser feature-name="security_training_feature_promotion">
-    <template #default="{ dismiss, shouldShowCallout }">
+  <security-training-promo
+    :security-configuration-path="securityConfigurationPath"
+    :project-full-path="projectFullPath"
+  >
+    <template #default="{ buttonLink, buttonText, dismiss, trackCTAClick }">
       <gl-banner
-        v-if="shouldShowCallout"
         :title="$options.i18n.title"
-        :button-text="$options.i18n.buttonText"
+        :button-text="buttonText"
         :button-link="buttonLink"
         variant="introduction"
         @primary="trackCTAClick"
@@ -53,5 +35,5 @@ export default {
         <p>{{ $options.i18n.content }}</p>
       </gl-banner>
     </template>
-  </user-callout-dismisser>
+  </security-training-promo>
 </template>
diff --git a/ee/spec/frontend/security_dashboard/components/project/security_training_promo_banner_spec.js b/ee/spec/frontend/security_dashboard/components/project/security_training_promo_banner_spec.js
index 93af3cf21f0d2b9bb9c9278e9125a7c9cdbd4f47..a5cd7d33ac0ca65901f5a232b857dfdad51575ce 100644
--- a/ee/spec/frontend/security_dashboard/components/project/security_training_promo_banner_spec.js
+++ b/ee/spec/frontend/security_dashboard/components/project/security_training_promo_banner_spec.js
@@ -1,103 +1,87 @@
 import { shallowMount } from '@vue/test-utils';
 import { GlBanner } from '@gitlab/ui';
-import { makeMockUserCalloutDismisser } from 'helpers/mock_user_callout_dismisser';
-import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
 import SecurityTrainingPromoBanner from 'ee/security_dashboard/components/project/security_training_promo_banner.vue';
-import {
-  TRACK_PROMOTION_BANNER_CTA_CLICK_ACTION,
-  TRACK_PROMOTION_BANNER_CTA_CLICK_LABEL,
-} from '~/security_configuration/constants';
+import { stubComponent } from 'helpers/stub_component';
+import SecurityTrainingPromo from 'ee/vue_shared/security_reports/components/security_training_promo.vue';
+
+const dismissSpy = jest.fn();
+const trackCTAClickSpy = jest.fn();
 
 const SECURITY_CONFIGURATION_PATH = 'foo/bar';
-const VULNERABILITY_MANAGEMENT_TAB_NAME = 'vulnerability-management';
 const PROJECT_FULL_PATH = 'namespace/project';
+const MOCK_SLOT_PROPS = {
+  buttonText: 'Enable security training',
+  buttonLink: 'some/link',
+  trackCTAClick: trackCTAClickSpy,
+  dismiss: dismissSpy,
+};
 
 describe('Security training promo banner component', () => {
   let wrapper;
-  const userCalloutDismissSpy = jest.fn();
 
-  const createWrapper = ({ shouldShowCallout = true } = {}) =>
-    shallowMount(SecurityTrainingPromoBanner, {
+  const createWrapper = () => {
+    wrapper = shallowMount(SecurityTrainingPromoBanner, {
       provide: {
         projectFullPath: PROJECT_FULL_PATH,
         securityConfigurationPath: SECURITY_CONFIGURATION_PATH,
       },
       stubs: {
-        UserCalloutDismisser: makeMockUserCalloutDismisser({
-          dismiss: userCalloutDismissSpy,
-          shouldShowCallout,
+        SecurityTrainingPromo: stubComponent(SecurityTrainingPromo, {
+          render() {
+            return this.$scopedSlots.default(MOCK_SLOT_PROPS);
+          },
         }),
       },
     });
+  };
 
   afterEach(() => {
     wrapper.destroy();
   });
 
+  const findSecurityTrainingPromo = () => wrapper.findComponent(SecurityTrainingPromo);
   const findBanner = () => wrapper.findComponent(GlBanner);
 
-  describe('banner', () => {
-    beforeEach(() => {
-      wrapper = createWrapper();
+  beforeEach(() => {
+    createWrapper();
+  });
+
+  describe('SecurityTrainingPromo', () => {
+    it('renders the component with the correct props', () => {
+      expect(findSecurityTrainingPromo().props()).toMatchObject({
+        securityConfigurationPath: SECURITY_CONFIGURATION_PATH,
+        projectFullPath: PROJECT_FULL_PATH,
+      });
     });
+  });
 
-    it('should be an introduction that announces the security training feature', () => {
-      const { title, buttonText, content } = SecurityTrainingPromoBanner.i18n;
+  describe('GlBanner', () => {
+    it('renders the component with the correct props', () => {
+      const { buttonText, buttonLink } = MOCK_SLOT_PROPS;
+      const { title } = SecurityTrainingPromoBanner.i18n;
 
       expect(findBanner().props()).toMatchObject({
         variant: 'introduction',
-        title,
         buttonText,
+        buttonLink,
+        title,
       });
-      expect(findBanner().text()).toBe(content);
     });
 
-    it(`should link to the security configuration's vulnerability management tab`, () => {
-      expect(findBanner().props('buttonLink')).toBe(
-        `${SECURITY_CONFIGURATION_PATH}?tab=${VULNERABILITY_MANAGEMENT_TAB_NAME}`,
-      );
-    });
-  });
-
-  describe('dismissal', () => {
-    it('should dismiss the callout when the banner is closed', () => {
-      wrapper = createWrapper();
-
-      expect(userCalloutDismissSpy).not.toHaveBeenCalled();
+    it('should trigger the dismiss method when the banner is closed', () => {
+      expect(dismissSpy).not.toHaveBeenCalled();
 
       findBanner().vm.$emit('close');
 
-      expect(userCalloutDismissSpy).toHaveBeenCalled();
-    });
-
-    it('should not show the banner once it has been dismissed', () => {
-      wrapper = createWrapper({ shouldShowCallout: false });
-
-      expect(findBanner().exists()).toBe(false);
+      expect(dismissSpy).toHaveBeenCalled();
     });
-  });
 
-  describe('metrics', () => {
-    let trackingSpy;
-
-    beforeEach(async () => {
-      trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
-      wrapper = createWrapper();
-    });
-
-    afterEach(() => {
-      unmockTracking();
-    });
-
-    it('tracks clicks on the CTA button', () => {
-      expect(trackingSpy).not.toHaveBeenCalled();
+    it('should trigger the trackCTAClick method when the banner is clicked', () => {
+      expect(trackCTAClickSpy).not.toHaveBeenCalled();
 
       findBanner().vm.$emit('primary');
 
-      expect(trackingSpy).toHaveBeenCalledWith(undefined, TRACK_PROMOTION_BANNER_CTA_CLICK_ACTION, {
-        label: TRACK_PROMOTION_BANNER_CTA_CLICK_LABEL,
-        property: PROJECT_FULL_PATH,
-      });
+      expect(trackCTAClickSpy).toHaveBeenCalled();
     });
   });
 });
diff --git a/ee/spec/frontend_integration/security_dashboard/vulnerability_report_init_integration_spec.js b/ee/spec/frontend_integration/security_dashboard/vulnerability_report_init_integration_spec.js
index de5d2cc48b23365135b7cae369ac7aaa34ad88ac..d01f4ffaa22226bb0c8df6e85f9cd69d2afdb194 100644
--- a/ee/spec/frontend_integration/security_dashboard/vulnerability_report_init_integration_spec.js
+++ b/ee/spec/frontend_integration/security_dashboard/vulnerability_report_init_integration_spec.js
@@ -52,6 +52,7 @@ describe('Vulnerability Report', () => {
           pipelineSecurityBuildsFailedCount: 1,
           pipelineSecurityBuildsFailedPath: '/test/faild_pipeline_02',
           projectFullPath: '/test/project',
+          securityConfigurationPath: '/test/configuration',
         },
         type: DASHBOARD_TYPES.PROJECT,
       });