diff --git a/app/assets/javascripts/security_configuration/components/training_provider_list.vue b/app/assets/javascripts/security_configuration/components/training_provider_list.vue
index dea94503e62c033b1b2d82de118f23685bad7704..539e2bff17c2a423f81f47f2ff3ad87a5d680115 100644
--- a/app/assets/javascripts/security_configuration/components/training_provider_list.vue
+++ b/app/assets/javascripts/security_configuration/components/training_provider_list.vue
@@ -49,7 +49,7 @@ export default {
   data() {
     return {
       errorMessage: '',
-      toggleLoading: false,
+      providerLoadingId: null,
       securityTrainingProviders: [],
       hasTouchedConfiguration: false,
     };
@@ -89,37 +89,29 @@ export default {
         Sentry.captureException(e);
       }
     },
-    toggleProvider(selectedProviderId) {
-      const toggledProviders = this.securityTrainingProviders.map((provider) => ({
-        ...provider,
-        ...(provider.id === selectedProviderId && { isEnabled: !provider.isEnabled }),
-      }));
+    toggleProvider(provider) {
+      const { isEnabled } = provider;
+      const toggledIsEnabled = !isEnabled;
 
-      const enabledProviderIds = toggledProviders
-        .filter(({ isEnabled }) => isEnabled)
-        .map(({ id }) => id);
-
-      const { isEnabled: selectedProviderIsEnabled } = toggledProviders.find(
-        (provider) => provider.id === selectedProviderId,
-      );
-
-      this.trackProviderToggle(selectedProviderId, selectedProviderIsEnabled);
-      this.storeEnabledProviders(enabledProviderIds);
+      this.trackProviderToggle(provider.id, toggledIsEnabled);
+      this.storeProvider({ ...provider, isEnabled: toggledIsEnabled });
     },
-    async storeEnabledProviders(enabledProviderIds) {
-      this.toggleLoading = true;
+    async storeProvider({ id, isEnabled, isPrimary }) {
+      this.providerLoadingId = id;
 
       try {
         const {
           data: {
-            configureSecurityTrainingProviders: { errors = [] },
+            securityTrainingUpdate: { errors = [] },
           },
         } = await this.$apollo.mutate({
           mutation: configureSecurityTrainingProvidersMutation,
           variables: {
             input: {
-              enabledProviders: enabledProviderIds,
-              fullPath: this.projectFullPath,
+              projectPath: this.projectFullPath,
+              providerId: id,
+              isEnabled,
+              isPrimary,
             },
           },
         });
@@ -133,7 +125,7 @@ export default {
       } catch {
         this.errorMessage = this.$options.i18n.configMutationErrorMessage;
       } finally {
-        this.toggleLoading = false;
+        this.providerLoadingId = null;
       }
     },
     trackProviderToggle(providerId, providerIsEnabled) {
@@ -166,25 +158,21 @@ export default {
       </gl-skeleton-loader>
     </div>
     <ul v-else class="gl-list-style-none gl-m-0 gl-p-0">
-      <li
-        v-for="{ id, isEnabled, name, description, url } in securityTrainingProviders"
-        :key="id"
-        class="gl-mb-6"
-      >
+      <li v-for="provider in securityTrainingProviders" :key="provider.id" class="gl-mb-6">
         <gl-card>
           <div class="gl-display-flex">
             <gl-toggle
-              :value="isEnabled"
+              :value="provider.isEnabled"
               :label="__('Training mode')"
               label-position="hidden"
-              :is-loading="toggleLoading"
-              @change="toggleProvider(id)"
+              :is-loading="providerLoadingId === provider.id"
+              @change="toggleProvider(provider)"
             />
             <div class="gl-ml-5">
-              <h3 class="gl-font-lg gl-m-0 gl-mb-2">{{ name }}</h3>
+              <h3 class="gl-font-lg gl-m-0 gl-mb-2">{{ provider.name }}</h3>
               <p>
-                {{ description }}
-                <gl-link :href="url" target="_blank">{{ __('Learn more.') }}</gl-link>
+                {{ provider.description }}
+                <gl-link :href="provider.url" target="_blank">{{ __('Learn more.') }}</gl-link>
               </p>
             </div>
           </div>
diff --git a/app/assets/javascripts/security_configuration/graphql/configure_security_training_providers.mutation.graphql b/app/assets/javascripts/security_configuration/graphql/configure_security_training_providers.mutation.graphql
index 660e0fadafb5ab997e827c3dab84694590cbe5ba..3528bfaf7b8601db469138ff462a47dd7a34ded6 100644
--- a/app/assets/javascripts/security_configuration/graphql/configure_security_training_providers.mutation.graphql
+++ b/app/assets/javascripts/security_configuration/graphql/configure_security_training_providers.mutation.graphql
@@ -1,9 +1,10 @@
-mutation configureSecurityTrainingProviders($input: configureSecurityTrainingProvidersInput!) {
-  configureSecurityTrainingProviders(input: $input) @client {
+mutation updateSecurityTraining($input: SecurityTrainingUpdateInput!) {
+  securityTrainingUpdate(input: $input) {
     errors
-    securityTrainingProviders {
+    training {
       id
       isEnabled
+      isPrimary
     }
   }
 }
diff --git a/app/assets/javascripts/security_configuration/graphql/security_training_providers.query.graphql b/app/assets/javascripts/security_configuration/graphql/security_training_providers.query.graphql
index a8326bb1968d9adeae23520963ae56ad15fe4120..2baeda318f3a9fceb247f600c5af6b8873f88654 100644
--- a/app/assets/javascripts/security_configuration/graphql/security_training_providers.query.graphql
+++ b/app/assets/javascripts/security_configuration/graphql/security_training_providers.query.graphql
@@ -5,6 +5,7 @@ query getSecurityTrainingProviders($fullPath: ID!) {
       name
       id
       description
+      isPrimary
       isEnabled
       url
     }
diff --git a/app/assets/javascripts/security_configuration/index.js b/app/assets/javascripts/security_configuration/index.js
index c8255a010b279443442acfa3db161b4f2a8aea23..8416692dd27a0f19fabe822944706c9a766a9d96 100644
--- a/app/assets/javascripts/security_configuration/index.js
+++ b/app/assets/javascripts/security_configuration/index.js
@@ -5,7 +5,6 @@ import { parseBooleanDataAttributes } from '~/lib/utils/dom_utils';
 import SecurityConfigurationApp from './components/app.vue';
 import { securityFeatures, complianceFeatures } from './components/constants';
 import { augmentFeatures } from './utils';
-import tempResolvers from './resolver';
 
 export const initSecurityConfiguration = (el) => {
   if (!el) {
@@ -15,7 +14,7 @@ export const initSecurityConfiguration = (el) => {
   Vue.use(VueApollo);
 
   const apolloProvider = new VueApollo({
-    defaultClient: createDefaultClient(tempResolvers),
+    defaultClient: createDefaultClient(),
   });
 
   const {
diff --git a/app/assets/javascripts/security_configuration/resolver.js b/app/assets/javascripts/security_configuration/resolver.js
deleted file mode 100644
index 51c02839a47cb0888308fbd9862ef39650912e49..0000000000000000000000000000000000000000
--- a/app/assets/javascripts/security_configuration/resolver.js
+++ /dev/null
@@ -1,60 +0,0 @@
-import produce from 'immer';
-import { __ } from '~/locale';
-import securityTrainingProvidersQuery from './graphql/security_training_providers.query.graphql';
-
-// Note: this is behind a feature flag and only a placeholder
-// until the actual GraphQL fields have been added
-// https://gitlab.com/gitlab-org/gi tlab/-/issues/346480
-export default {
-  Query: {
-    securityTrainingProviders() {
-      return [
-        {
-          __typename: 'SecurityTrainingProvider',
-          id: 101,
-          name: __('Kontra'),
-          description: __('Interactive developer security education.'),
-          url: 'https://application.security/',
-          isEnabled: false,
-        },
-        {
-          __typename: 'SecurityTrainingProvider',
-          id: 102,
-          name: __('SecureCodeWarrior'),
-          description: __('Security training with guide and learning pathways.'),
-          url: 'https://www.securecodewarrior.com/',
-          isEnabled: true,
-        },
-      ];
-    },
-  },
-
-  Mutation: {
-    configureSecurityTrainingProviders: (
-      _,
-      { input: { enabledProviders, primaryProvider, fullPath } },
-      { cache },
-    ) => {
-      const sourceData = cache.readQuery({
-        query: securityTrainingProvidersQuery,
-        variables: {
-          fullPath,
-        },
-      });
-
-      const data = produce(sourceData.project, (draftData) => {
-        /* eslint-disable no-param-reassign */
-        draftData.securityTrainingProviders.forEach((provider) => {
-          provider.isPrimary = provider.id === primaryProvider;
-          provider.isEnabled =
-            provider.id === primaryProvider || enabledProviders.includes(provider.id);
-        });
-      });
-
-      return {
-        __typename: 'configureSecurityTrainingProvidersPayload',
-        securityTrainingProviders: data.securityTrainingProviders,
-      };
-    },
-  },
-};
diff --git a/ee/app/assets/javascripts/security_dashboard/graphql/provider.js b/ee/app/assets/javascripts/security_dashboard/graphql/provider.js
index 055ec1b059b40b679105475adefa34a0100d81a1..9153c5252b359d27bc54a650272d06f95dbf94d2 100644
--- a/ee/app/assets/javascripts/security_dashboard/graphql/provider.js
+++ b/ee/app/assets/javascripts/security_dashboard/graphql/provider.js
@@ -1,13 +1,10 @@
 import Vue from 'vue';
 import VueApollo from 'vue-apollo';
 import createDefaultClient from '~/lib/graphql';
-import tempResolvers from '~/security_configuration/resolver';
 
 Vue.use(VueApollo);
 
-const defaultClient = createDefaultClient({
-  ...tempResolvers,
-});
+const defaultClient = createDefaultClient();
 
 export default new VueApollo({
   defaultClient,
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 8769f0fcede5bea0353b3326aa7b91a5a7acc8e8..6eddbc54e6ebf3f3d300ea78b5a666520fd0429f 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -19717,9 +19717,6 @@ msgstr ""
 msgid "Integrations|can't exceed %{recipients_limit}"
 msgstr ""
 
-msgid "Interactive developer security education."
-msgstr ""
-
 msgid "Interactive mode"
 msgstr ""
 
@@ -21058,9 +21055,6 @@ msgstr ""
 msgid "Ki"
 msgstr ""
 
-msgid "Kontra"
-msgstr ""
-
 msgid "Kroki"
 msgstr ""
 
@@ -32018,9 +32012,6 @@ msgstr ""
 msgid "Secure token that identifies an external storage request."
 msgstr ""
 
-msgid "SecureCodeWarrior"
-msgstr ""
-
 msgid "Security"
 msgstr ""
 
@@ -32045,9 +32036,6 @@ msgstr ""
 msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
 msgstr ""
 
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
 msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
 msgstr ""
 
diff --git a/spec/frontend/security_configuration/components/training_provider_list_spec.js b/spec/frontend/security_configuration/components/training_provider_list_spec.js
index ea5df9ca550655af9ab6b9bf833a92dac6ed43fc..18c9ada6bde9c189265f9e8333416f69a901629a 100644
--- a/spec/frontend/security_configuration/components/training_provider_list_spec.js
+++ b/spec/frontend/security_configuration/components/training_provider_list_spec.js
@@ -19,6 +19,8 @@ import {
   dismissUserCalloutErrorResponse,
   securityTrainingProviders,
   securityTrainingProvidersResponse,
+  updateSecurityTrainingProvidersResponse,
+  updateSecurityTrainingProvidersErrorResponse,
   testProjectPath,
   textProviderIds,
 } from '../mock_data';
@@ -29,18 +31,22 @@ describe('TrainingProviderList component', () => {
   let wrapper;
   let apolloProvider;
 
-  const createApolloProvider = ({ resolvers, handlers = [] } = {}) => {
+  const createApolloProvider = ({ handlers = [] } = {}) => {
     const defaultHandlers = [
       [
         securityTrainingProvidersQuery,
         jest.fn().mockResolvedValue(securityTrainingProvidersResponse),
       ],
+      [
+        configureSecurityTrainingProvidersMutation,
+        jest.fn().mockResolvedValue(updateSecurityTrainingProvidersResponse),
+      ],
     ];
 
     // make sure we don't have any duplicate handlers to avoid 'Request handler already defined for query` errors
     const mergedHandlers = [...new Map([...defaultHandlers, ...handlers])];
 
-    apolloProvider = createMockApollo(mergedHandlers, resolvers);
+    apolloProvider = createMockApollo(mergedHandlers);
   };
 
   const createComponent = () => {
@@ -62,7 +68,7 @@ describe('TrainingProviderList component', () => {
   const findLoader = () => wrapper.findComponent(GlSkeletonLoader);
   const findErrorAlert = () => wrapper.findComponent(GlAlert);
 
-  const toggleFirstProvider = () => findFirstToggle().vm.$emit('change');
+  const toggleFirstProvider = () => findFirstToggle().vm.$emit('change', textProviderIds[0]);
 
   afterEach(() => {
     wrapper.destroy();
@@ -146,9 +152,9 @@ describe('TrainingProviderList component', () => {
       beforeEach(async () => {
         jest.spyOn(apolloProvider.defaultClient, 'mutate');
 
-        await waitForMutationToBeLoaded();
+        await waitForQueryToBeLoaded();
 
-        toggleFirstProvider();
+        await toggleFirstProvider();
       });
 
       it.each`
@@ -166,7 +172,14 @@ describe('TrainingProviderList component', () => {
         expect(apolloProvider.defaultClient.mutate).toHaveBeenCalledWith(
           expect.objectContaining({
             mutation: configureSecurityTrainingProvidersMutation,
-            variables: { input: { enabledProviders: textProviderIds, fullPath: testProjectPath } },
+            variables: {
+              input: {
+                providerId: textProviderIds[0],
+                isEnabled: true,
+                isPrimary: false,
+                projectPath: testProjectPath,
+              },
+            },
           }),
         );
       });
@@ -264,14 +277,12 @@ describe('TrainingProviderList component', () => {
     describe('when storing training provider configurations', () => {
       beforeEach(async () => {
         createApolloProvider({
-          resolvers: {
-            Mutation: {
-              configureSecurityTrainingProviders: () => ({
-                errors: ['something went wrong!'],
-                securityTrainingProviders: [],
-              }),
-            },
-          },
+          handlers: [
+            [
+              configureSecurityTrainingProvidersMutation,
+              jest.fn().mockReturnValue(updateSecurityTrainingProvidersErrorResponse),
+            ],
+          ],
         });
         createComponent();
 
diff --git a/spec/frontend/security_configuration/mock_data.js b/spec/frontend/security_configuration/mock_data.js
index e47a255fbac3beb8b09918c14cdc1c12b58ca1ad..b042e8704679560694f6543eb144818554281cc6 100644
--- a/spec/frontend/security_configuration/mock_data.js
+++ b/spec/frontend/security_configuration/mock_data.js
@@ -9,6 +9,7 @@ export const securityTrainingProviders = [
     description: 'Interactive developer security education',
     url: 'https://www.example.org/security/training',
     isEnabled: false,
+    isPrimary: false,
   },
   {
     id: textProviderIds[1],
@@ -16,6 +17,7 @@ export const securityTrainingProviders = [
     description: 'Security training with guide and learning pathways.',
     url: 'https://www.vendornametwo.com/',
     isEnabled: true,
+    isPrimary: false,
   },
 ];
 
@@ -51,3 +53,26 @@ export const dismissUserCalloutErrorResponse = {
     },
   },
 };
+
+export const updateSecurityTrainingProvidersResponse = {
+  data: {
+    securityTrainingUpdate: {
+      errors: [],
+      training: {
+        id: 101,
+        name: 'Acme',
+        isEnabled: true,
+        isPrimary: false,
+      },
+    },
+  },
+};
+
+export const updateSecurityTrainingProvidersErrorResponse = {
+  data: {
+    securityTrainingUpdate: {
+      errors: ['something went wrong!'],
+      training: null,
+    },
+  },
+};