diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_action.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_action.vue
index 4899efe54acf59f6ea7c73e2bf93c9eb6c5a16e7..5a70c82e6e6993b4eb5a830996a0527df5e87a48 100644
--- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_action.vue
+++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_action.vue
@@ -7,6 +7,7 @@ import {
   REPORT_TYPE_DEPENDENCY_SCANNING,
   REPORT_TYPE_CONTAINER_SCANNING,
 } from '~/vue_shared/security_reports/constants';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
 import { isProject, isGroup } from 'ee/security_orchestration/components/utils';
 import SectionLayout from '../../section_layout.vue';
 import { ACTION_AND_LABEL, RULE_MODE_SCANNERS } from '../../constants';
@@ -19,8 +20,9 @@ import {
   POLICY_ACTION_BUILDER_DAST_PROFILES_ERROR_KEY,
 } from '../constants';
 import { buildScannerAction } from '../lib';
-import { CI_VARIABLE, FILTERS } from './scan_filters/constants';
+import { CI_VARIABLE, FILTERS, TEMPLATE } from './scan_filters/constants';
 import CiVariablesSelectors from './scan_filters/ci_variables_selectors.vue';
+import TemplateSelector from './scan_filters/template_selector.vue';
 import GroupDastProfileSelector from './scan_filters/group_dast_profile_selector.vue';
 import ProjectDastProfileSelector from './scan_filters/project_dast_profile_selector.vue';
 import RunnerTagsFilter from './scan_filters/runner_tags_filter.vue';
@@ -30,6 +32,7 @@ export default {
   CI_VARIABLE,
   FILTERS,
   SCANNERS: RULE_MODE_SCANNERS,
+  TEMPLATE,
   POLICY_ACTION_BUILDER_DAST_PROFILES_ERROR_KEY,
   POLICY_ACTION_BUILDER_TAGS_ERROR_KEY,
   components: {
@@ -41,7 +44,9 @@ export default {
     GroupDastProfileSelector,
     RunnerTagsFilter,
     ScanFilterSelector,
+    TemplateSelector,
   },
+  mixins: [glFeatureFlagsMixin()],
   inject: ['namespacePath', 'namespaceType'],
   props: {
     initAction: {
@@ -92,6 +97,12 @@ export default {
     isProject() {
       return isProject(this.namespaceType);
     },
+    hasTemplateSelector() {
+      return (
+        this.glFeatures.scanExecutionPoliciesWithLatestTemplates ||
+        this.glFeatures.scanExecutionPoliciesWithLatestTemplatesGroup
+      );
+    },
     siteProfile() {
       return this.initAction.site_profile?.trim() ?? '';
     },
@@ -114,16 +125,17 @@ export default {
     isFilterSelected(filter) {
       return this.filters[filter];
     },
-    emitCiVariableFilterChanges() {
+    emitFilterChanges(filter) {
       const updatedAction = { ...this.initAction };
-      delete updatedAction.variables;
+      if (filter === CI_VARIABLE) delete updatedAction.variables;
+      if (filter === TEMPLATE) delete updatedAction.template;
       this.$emit('changed', updatedAction);
     },
-    removeCiFilter() {
+    removeFilter(filter) {
       const newFilters = { ...this.filters };
-      delete newFilters[CI_VARIABLE];
+      delete newFilters[filter];
       this.filters = newFilters;
-      this.emitCiVariableFilterChanges();
+      this.emitFilterChanges(filter);
     },
     removeYamlProperty(property) {
       const updatedAction = { ...this.initAction };
@@ -231,12 +243,19 @@ export default {
           @error="$emit('parsing-error', $options.POLICY_ACTION_BUILDER_TAGS_ERROR_KEY)"
         />
 
+        <template-selector
+          v-if="hasTemplateSelector"
+          :selected="initAction.template"
+          @input="triggerChanged"
+          @remove="removeFilter($options.TEMPLATE)"
+        />
+
         <ci-variables-selectors
           v-if="isCIVariableSelectorSelected"
           class="gl-bg-white"
           :scan-type="initAction.scan"
           :selected="initAction.variables"
-          @remove="removeCiFilter"
+          @remove="removeFilter($options.CI_VARIABLE)"
           @input="triggerChanged"
         />
 
diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/constants.js b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/constants.js
index b8c04fb91ca95487f82645a54681f6cdc79f0338..c70a78da1ae8cd16e03f9014f2b0c57ca7d821d5 100644
--- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/constants.js
+++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/constants.js
@@ -2,6 +2,12 @@ import { s__ } from '~/locale';
 
 export const CI_VARIABLE = 'ci_variable';
 
+export const TEMPLATE = 'template';
+
+export const DEFAULT_TEMPLATE = 'default';
+
+export const LATEST_TEMPLATE = 'latest';
+
 export const FILTERS = [
   {
     text: s__('ScanResultPolicy|Customized CI Variables'),
diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/template_selector.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/template_selector.vue
new file mode 100644
index 0000000000000000000000000000000000000000..8b33bbe51c51b404071476ab9707b589dac27d42
--- /dev/null
+++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/template_selector.vue
@@ -0,0 +1,86 @@
+<script>
+import { GlCollapsibleListbox, GlIcon, GlTooltipDirective as GlTooltip } from '@gitlab/ui';
+import { s__ } from '~/locale';
+import SectionLayout from 'ee/security_orchestration/components/policy_editor/section_layout.vue';
+import { DEFAULT_TEMPLATE, LATEST_TEMPLATE } from './constants';
+
+export default {
+  i18n: {
+    label: s__('SecurityOrchestration|Security job template'),
+    defaultTemplateInformation: s__(
+      'SecurityOrchestration|CI/CD template edition to be enforced. The default template is stable, but may not have all the features of the latest template.',
+    ),
+    latestTemplateInformation: s__(
+      'SecurityOrchestration|CI/CD template edition to be enforced. The latest edition may introduce breaking changes.',
+    ),
+  },
+  components: {
+    GlCollapsibleListbox,
+    GlIcon,
+    SectionLayout,
+  },
+  directives: {
+    GlTooltip,
+  },
+  props: {
+    selected: {
+      type: String,
+      required: false,
+      default: DEFAULT_TEMPLATE,
+    },
+  },
+  computed: {
+    availableOptions() {
+      return [
+        { text: s__('SecurityOrchestration|latest'), value: LATEST_TEMPLATE },
+        { text: s__('SecurityOrchestration|default'), value: DEFAULT_TEMPLATE },
+      ];
+    },
+    tooltipMessage() {
+      return this.selected === LATEST_TEMPLATE
+        ? this.$options.i18n.latestTemplateInformation
+        : this.$options.i18n.defaultTemplateInformation;
+    },
+  },
+  methods: {
+    toggleValue(value) {
+      if (value === LATEST_TEMPLATE) {
+        this.$emit('input', { template: value });
+      } else {
+        this.$emit('remove');
+      }
+    },
+  },
+};
+</script>
+
+<template>
+  <section-layout
+    class="gl-w-full gl-bg-white"
+    content-classes="gl-justify-content-space-between"
+    :show-remove-button="false"
+  >
+    <template #selector>
+      <label class="gl-mb-0 gl-mr-4" for="policy-template" :title="$options.i18n.label">
+        {{ $options.i18n.label }}
+      </label>
+    </template>
+
+    <template #content>
+      <div class="gl-display-flex gl-flex-grow-2 gl-align-items-center">
+        <gl-collapsible-listbox
+          id="policy-template"
+          :items="availableOptions"
+          :selected="selected"
+          @select="toggleValue"
+        />
+        <gl-icon
+          v-gl-tooltip
+          name="question-o"
+          :title="tooltipMessage"
+          class="gl-text-blue-600 gl-ml-3"
+        />
+      </div>
+    </template>
+  </section-layout>
+</template>
diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/lib/from_yaml.js b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/lib/from_yaml.js
index bd95ff700c1a4db775a5acb5f5ffb85054a4bbe6..a6d38b3b976d04c6b2944174fd34e06aa537d540 100644
--- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/lib/from_yaml.js
+++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/lib/from_yaml.js
@@ -1,5 +1,9 @@
 import { safeLoad } from 'js-yaml';
 import { CUSTOM_ACTION_KEY } from 'ee/security_orchestration/components/policy_editor/scan_execution/constants';
+import {
+  DEFAULT_TEMPLATE,
+  LATEST_TEMPLATE,
+} from 'ee/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/constants';
 import { addIdsToPolicy, isValidPolicy, hasInvalidCron } from '../../utils';
 import {
   BRANCH_TYPE_KEY,
@@ -22,6 +26,17 @@ const hasInvalidBranchType = (rules) => {
   );
 };
 
+/**
+ * Check if any action has invalid template type
+ * @param {Array} actions
+ * @returns {Boolean}
+ */
+const hasInvalidTemplate = (actions = []) => {
+  return actions.some(({ template }) => {
+    return (template || template === '') && ![DEFAULT_TEMPLATE, LATEST_TEMPLATE].includes(template);
+  });
+};
+
 /**
  * Checks if rule mode supports the inputted scanner
  * @param {Object} policy
@@ -70,7 +85,15 @@ export const fromYaml = ({ manifest, validateRuleMode = false }) => {
         'branch_exceptions',
         'id',
       ];
-      const actionsKeys = ['scan', 'site_profile', 'scanner_profile', 'variables', 'tags', 'id'];
+      const actionsKeys = [
+        'scan',
+        'site_profile',
+        'scanner_profile',
+        'variables',
+        'tags',
+        'id',
+        'template',
+      ];
 
       if (gon?.features?.compliancePipelineInPolicies) {
         actionsKeys.push('ci_configuration');
@@ -79,6 +102,7 @@ export const fromYaml = ({ manifest, validateRuleMode = false }) => {
       return isValidPolicy({ policy, rulesKeys, actionsKeys }) &&
         !hasInvalidCron(policy) &&
         !hasInvalidBranchType(policy.rules) &&
+        !hasInvalidTemplate(policy.actions) &&
         hasRuleModeSupportedScanners(policy)
         ? policy
         : { error: true };
diff --git a/ee/app/controllers/groups/security/policies_controller.rb b/ee/app/controllers/groups/security/policies_controller.rb
index 6e4dc77ed3b4e206497cce1385f47189c63905ae..8ed86413ef7147096f2ab37c9562d6e58a67b4af 100644
--- a/ee/app/controllers/groups/security/policies_controller.rb
+++ b/ee/app/controllers/groups/security/policies_controller.rb
@@ -13,6 +13,7 @@ class PoliciesController < Groups::ApplicationController
         push_frontend_feature_flag(:compliance_pipeline_in_policies, group)
         push_frontend_feature_flag(:pipeline_execution_policy_type, group)
         push_frontend_feature_flag(:vulnerability_management_policy_type_group, group)
+        push_frontend_feature_flag(:scan_execution_policies_with_latest_templates_group, group)
       end
 
       feature_category :security_policy_management
diff --git a/ee/app/controllers/projects/security/policies_controller.rb b/ee/app/controllers/projects/security/policies_controller.rb
index 442e09207a14c0b3e54d826f97d31c797cbe9137..dc636f4af5914e80f78b0caebf4e77f730e50843 100644
--- a/ee/app/controllers/projects/security/policies_controller.rb
+++ b/ee/app/controllers/projects/security/policies_controller.rb
@@ -15,6 +15,7 @@ class PoliciesController < Projects::ApplicationController
         push_frontend_feature_flag(:pipeline_execution_policy_type, project.group) if project.group
         push_frontend_feature_flag(:approval_policy_disable_bot_comment, project)
         push_frontend_feature_flag(:vulnerability_management_policy_type, project)
+        push_frontend_feature_flag(:scan_execution_policies_with_latest_templates)
       end
 
       feature_category :security_policy_management
diff --git a/ee/config/feature_flags/gitlab_com_derisk/scan_execution_policies_with_latest_templates_group.yml b/ee/config/feature_flags/gitlab_com_derisk/scan_execution_policies_with_latest_templates_group.yml
new file mode 100644
index 0000000000000000000000000000000000000000..df6ae8693df2a340d9a11433cc3d83bd3813a6a4
--- /dev/null
+++ b/ee/config/feature_flags/gitlab_com_derisk/scan_execution_policies_with_latest_templates_group.yml
@@ -0,0 +1,9 @@
+---
+name: scan_execution_policies_with_latest_templates_group
+feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/415427
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/154468
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/468981
+milestone: '17.2'
+group: group::security policies
+type: gitlab_com_derisk
+default_enabled: false
diff --git a/ee/spec/frontend/security_orchestration/components/policy_editor/scan_execution/action/scan_action_spec.js b/ee/spec/frontend/security_orchestration/components/policy_editor/scan_execution/action/scan_action_spec.js
index a7f174e3dc8214a32594b78b6d2f5c1b519fcc76..b6995c051a756718bfb76cfc690093a38ceecd7b 100644
--- a/ee/spec/frontend/security_orchestration/components/policy_editor/scan_execution/action/scan_action_spec.js
+++ b/ee/spec/frontend/security_orchestration/components/policy_editor/scan_execution/action/scan_action_spec.js
@@ -9,6 +9,7 @@ import groupRunnerTags from 'ee/vue_shared/components/runner_tags_dropdown/graph
 import GroupDastProfileSelector from 'ee/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/group_dast_profile_selector.vue';
 import RunnerTagsFilter from 'ee/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/runner_tags_filter.vue';
 import CiVariablesSelectors from 'ee/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/ci_variables_selectors.vue';
+import TemplateSelector from 'ee/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/template_selector.vue';
 import ScanFilterSelector from 'ee/security_orchestration/components/policy_editor/scan_filter_selector.vue';
 import { buildScannerAction } from 'ee/security_orchestration/components/policy_editor/scan_execution/lib';
 import { NAMESPACE_TYPES } from 'ee/security_orchestration/constants';
@@ -26,7 +27,9 @@ import { createMockApolloProvider } from 'ee_jest/security_configuration/dast_pr
 import { RUNNER_TAG_LIST_MOCK } from 'ee_jest/vue_shared/components/runner_tags_dropdown/mocks/mocks';
 import {
   CI_VARIABLE,
+  DEFAULT_TEMPLATE,
   FILTERS,
+  LATEST_TEMPLATE,
 } from 'ee/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/constants';
 
 const actionId = 'action_0';
@@ -88,6 +91,7 @@ describe('PolicyActionBuilder', () => {
 
   const findActionSeperator = () => wrapper.findByTestId('action-and-label');
   const findCiVariablesSelectors = () => wrapper.findComponent(CiVariablesSelectors);
+  const findTemplateFilter = () => wrapper.findComponent(TemplateSelector);
   const findSectionLayout = () => wrapper.findAllComponents(SectionLayout).at(1);
   const findDropdown = () => wrapper.findComponent(GlCollapsibleListbox);
   const findScanFilterSelector = () => wrapper.findComponent(ScanFilterSelector);
@@ -192,10 +196,62 @@ describe('PolicyActionBuilder', () => {
       });
     });
 
+    describe('template filter', () => {
+      describe('without the feature flag', () => {
+        it('does not render', () => {
+          factory();
+          expect(findTemplateFilter().exists()).toBe(false);
+        });
+      });
+
+      describe('with the feature flag', () => {
+        describe.each([
+          'scanExecutionPoliciesWithLatestTemplates',
+          'scanExecutionPoliciesWithLatestTemplatesGroup',
+        ])('%s feature flag', (featureFlag) => {
+          it('renders', () => {
+            factory({
+              provide: { glFeatures: { [featureFlag]: true } },
+            });
+            expect(findTemplateFilter().exists()).toBe(true);
+          });
+
+          it('emits "changed" with the updated value when updated', () => {
+            factory({
+              propsData: {
+                initAction: {
+                  ...DEFAULT_ACTION,
+                  template: LATEST_TEMPLATE,
+                },
+              },
+              provide: { glFeatures: { [featureFlag]: true } },
+            });
+            findTemplateFilter().vm.$emit('input', { template: DEFAULT_TEMPLATE });
+            expect(wrapper.emitted('changed')).toEqual([
+              [{ ...DEFAULT_ACTION, template: DEFAULT_TEMPLATE }],
+            ]);
+          });
+
+          it('emits "changed" with the updated value when removed', () => {
+            factory({
+              propsData: {
+                initAction: {
+                  ...DEFAULT_ACTION,
+                  template: LATEST_TEMPLATE,
+                },
+              },
+              provide: { glFeatures: { [featureFlag]: true } },
+            });
+            findTemplateFilter().vm.$emit('remove');
+            expect(wrapper.emitted('changed')).toEqual([[{ ...DEFAULT_ACTION }]]);
+          });
+        });
+      });
+    });
+
     describe('ci variable filter', () => {
       it('initially hides ci variable filter', () => {
         factory();
-
         expect(findCiVariablesSelectors().exists()).toBe(false);
       });
 
diff --git a/ee/spec/frontend/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/template_selector_spec.js b/ee/spec/frontend/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/template_selector_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..d756a3133cdf1a3decb3257aa57a32e7ff8c1d84
--- /dev/null
+++ b/ee/spec/frontend/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/template_selector_spec.js
@@ -0,0 +1,71 @@
+import { GlCollapsibleListbox, GlIcon } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import SectionLayout from 'ee/security_orchestration/components/policy_editor/section_layout.vue';
+import TemplateSelector from 'ee/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/template_selector.vue';
+import {
+  DEFAULT_TEMPLATE,
+  LATEST_TEMPLATE,
+} from 'ee/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/constants';
+
+describe('TemplateSelector', () => {
+  let wrapper;
+
+  const createComponent = (propsData = {}) => {
+    wrapper = shallowMountExtended(TemplateSelector, {
+      propsData,
+      stubs: {
+        SectionLayout,
+      },
+    });
+  };
+
+  const findDropdown = () => wrapper.findComponent(GlCollapsibleListbox);
+  const findIcon = () => wrapper.findComponent(GlIcon);
+
+  it('renders default value', () => {
+    createComponent();
+    expect(findDropdown().props('selected')).toBe(DEFAULT_TEMPLATE);
+  });
+
+  it('renders help icon for default template', () => {
+    createComponent();
+    expect(findIcon().exists()).toBe(true);
+    expect(findIcon().attributes('title')).toBe(
+      'CI/CD template edition to be enforced. The default template is stable, but may not have all the features of the latest template.',
+    );
+  });
+
+  it('renders help icon for latest template', () => {
+    createComponent({ selected: LATEST_TEMPLATE });
+    expect(findIcon().exists()).toBe(true);
+    expect(findIcon().attributes('title')).toBe(
+      'CI/CD template edition to be enforced. The latest edition may introduce breaking changes.',
+    );
+  });
+
+  it('renders selected value', () => {
+    createComponent({ selected: LATEST_TEMPLATE });
+    expect(findDropdown().props('selected')).toBe(LATEST_TEMPLATE);
+  });
+
+  it('emits "input" event when "latest" is selected', () => {
+    createComponent();
+    expect(wrapper.emitted('input')).toEqual(undefined);
+    expect(wrapper.emitted('remove')).toEqual(undefined);
+    findDropdown().vm.$emit('select', LATEST_TEMPLATE);
+    expect(wrapper.emitted('input')).toEqual([[{ template: LATEST_TEMPLATE }]]);
+    expect(wrapper.emitted('remove')).toEqual(undefined);
+  });
+
+  it('emits "remove" event when "default" is selected', () => {
+    createComponent();
+    expect(wrapper.emitted('input')).toEqual(undefined);
+    expect(wrapper.emitted('remove')).toEqual(undefined);
+    findDropdown().vm.$emit('select', LATEST_TEMPLATE);
+    expect(wrapper.emitted('input')).toHaveLength(1);
+    expect(wrapper.emitted('remove')).toEqual(undefined);
+    findDropdown().vm.$emit('select', DEFAULT_TEMPLATE);
+    expect(wrapper.emitted('input')).toHaveLength(1);
+    expect(wrapper.emitted('remove')).toEqual([[]]);
+  });
+});
diff --git a/ee/spec/frontend/security_orchestration/components/policy_editor/scan_execution/lib/from_yaml_spec.js b/ee/spec/frontend/security_orchestration/components/policy_editor/scan_execution/lib/from_yaml_spec.js
index 3c39aded1449711a310dd57a437b0d89e9d203fd..419c3c3a7b0b0735ea662471e8acf0e7220983ff 100644
--- a/ee/spec/frontend/security_orchestration/components/policy_editor/scan_execution/lib/from_yaml_spec.js
+++ b/ee/spec/frontend/security_orchestration/components/policy_editor/scan_execution/lib/from_yaml_spec.js
@@ -19,6 +19,9 @@ import {
   mockPolicyScopeScanExecutionObject,
   mockCodeBlockFilePathScanExecutionManifest,
   mockCodeBlockFilePathScanExecutionObject,
+  mockTemplateScanExecutionManifest,
+  mockTemplateScanExecutionObject,
+  mockInvalidTemplateScanExecutionManifest,
 } from 'ee_jest/security_orchestration/mocks/mock_scan_execution_policy_data';
 
 jest.mock('lodash/uniqueId', () => jest.fn((prefix) => `${prefix}0`));
@@ -35,6 +38,8 @@ describe('fromYaml', () => {
     ${'returns the policy object for project scope'}                                                     | ${{ manifest: mockPolicyScopeExecutionManifest, validateRuleMode: true }}           | ${mockPolicyScopeScanExecutionObject}       | ${{}}
     ${'returns the policy object for custom code block with file path with enabled ff'}                  | ${{ manifest: mockCodeBlockFilePathScanExecutionManifest, validateRuleMode: true }} | ${mockCodeBlockFilePathScanExecutionObject} | ${{ compliancePipelineInPolicies: true }}
     ${'returns the policy object for custom code block with file path with disabled ff'}                 | ${{ manifest: mockCodeBlockFilePathScanExecutionManifest, validateRuleMode: true }} | ${{ error: true }}                          | ${{ compliancePipelineInPolicies: false }}
+    ${'returns the policy object for valid template value'}                                              | ${{ manifest: mockTemplateScanExecutionManifest, validateRuleMode: true }}          | ${mockTemplateScanExecutionObject}          | ${{ compliancePipelineInPolicies: false }}
+    ${'returns error object for a policy with invalid template value'}                                   | ${{ manifest: mockInvalidTemplateScanExecutionManifest, validateRuleMode: true }}   | ${{ error: true }}                          | ${{}}
   `('$title', ({ input, output, features }) => {
     window.gon = { features };
     expect(fromYaml(input)).toStrictEqual(output);
diff --git a/ee/spec/frontend/security_orchestration/mocks/mock_scan_execution_policy_data.js b/ee/spec/frontend/security_orchestration/mocks/mock_scan_execution_policy_data.js
index 45649fa95571adefd683049811c32baa44cf61cb..d6afc9063e795a3e3d4024d47343b1037f767094 100644
--- a/ee/spec/frontend/security_orchestration/mocks/mock_scan_execution_policy_data.js
+++ b/ee/spec/frontend/security_orchestration/mocks/mock_scan_execution_policy_data.js
@@ -31,6 +31,22 @@ actions:
     scanner_profile: required_scanner_profile
 `;
 
+export const mockDastScanExecutionObject = {
+  type: 'scan_execution_policy',
+  name: 'Scheduled Dast/SAST scan',
+  description: 'This policy enforces pipeline configuration to have a job with DAST scan',
+  enabled: false,
+  rules: [{ type: 'pipeline', branches: ['main'], id: ruleId }],
+  actions: [
+    {
+      scan: 'dast',
+      site_profile: 'required_site_profile',
+      scanner_profile: 'required_scanner_profile',
+      id: actionId,
+    },
+  ],
+};
+
 export const mockBranchExceptionsExecutionManifest = `type: scan_execution_policy
 name: Branch exceptions
 description: This policy enforces pipeline configuration to have branch exceptions
@@ -48,22 +64,6 @@ actions:
     scanner_profile: required_scanner_profile
 `;
 
-export const mockDastScanExecutionObject = {
-  type: 'scan_execution_policy',
-  name: 'Scheduled Dast/SAST scan',
-  description: 'This policy enforces pipeline configuration to have a job with DAST scan',
-  enabled: false,
-  rules: [{ type: 'pipeline', branches: ['main'], id: ruleId }],
-  actions: [
-    {
-      scan: 'dast',
-      site_profile: 'required_site_profile',
-      scanner_profile: 'required_scanner_profile',
-      id: actionId,
-    },
-  ],
-};
-
 export const mockBranchExceptionsScanExecutionObject = {
   type: 'scan_execution_policy',
   name: 'Branch exceptions',
@@ -282,3 +282,16 @@ export const mockCodeBlockFilePathScanExecutionObject = {
     },
   ],
 };
+
+export const mockTemplateScanExecutionManifest = mockDastScanExecutionManifest.concat(
+  `    template: default\n`,
+);
+
+export const mockTemplateScanExecutionObject = {
+  ...mockDastScanExecutionObject,
+  actions: [{ ...mockDastScanExecutionObject.actions[0], template: 'default' }],
+};
+
+export const mockInvalidTemplateScanExecutionManifest = mockDastScanExecutionManifest.concat(
+  `    template: not-valid-value\n`,
+);
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index b0b550eab3166b1ec589b31b905a91bad35ee714..f62d75a9b9d63a865c28fd935fae1521dbf9cd99 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -47709,6 +47709,12 @@ msgstr ""
 msgid "SecurityOrchestration|Branch: %{boldStart}%{branchName}%{boldEnd} was not found in project: %{boldStart}%{projectName}%{boldEnd}. Edit or remove this entry."
 msgstr ""
 
+msgid "SecurityOrchestration|CI/CD template edition to be enforced. The default template is stable, but may not have all the features of the latest template."
+msgstr ""
+
+msgid "SecurityOrchestration|CI/CD template edition to be enforced. The latest edition may introduce breaking changes."
+msgstr ""
+
 msgid "SecurityOrchestration|Cadence is invalid"
 msgstr ""
 
@@ -48089,6 +48095,9 @@ msgstr ""
 msgid "SecurityOrchestration|Security Scan"
 msgstr ""
 
+msgid "SecurityOrchestration|Security job template"
+msgstr ""
+
 msgid "SecurityOrchestration|Security policy overwrites this setting"
 msgstr ""
 
@@ -48374,6 +48383,9 @@ msgstr ""
 msgid "SecurityOrchestration|compliance frameworks"
 msgstr ""
 
+msgid "SecurityOrchestration|default"
+msgstr ""
+
 msgid "SecurityOrchestration|except projects"
 msgstr ""
 
@@ -48389,6 +48401,9 @@ msgstr ""
 msgid "SecurityOrchestration|have no fix available"
 msgstr ""
 
+msgid "SecurityOrchestration|latest"
+msgstr ""
+
 msgid "SecurityOrchestration|more than %{allowed}"
 msgstr ""