diff --git a/app/assets/javascripts/graphql_shared/constants.js b/app/assets/javascripts/graphql_shared/constants.js
index 692de9dcb88b02cb4c01cb82e045cc2d57e2cf2c..378573548f824fce419150a952f3e5e3f07c79b3 100644
--- a/app/assets/javascripts/graphql_shared/constants.js
+++ b/app/assets/javascripts/graphql_shared/constants.js
@@ -15,3 +15,4 @@ export const TYPE_USER = 'User';
 export const TYPE_VULNERABILITY = 'Vulnerability';
 export const TYPE_NOTE = 'Note';
 export const TYPE_DISCUSSION = 'Discussion';
+export const TYPE_PACKAGES_PACKAGE = 'Packages::Package';
diff --git a/ee/app/assets/javascripts/security_configuration/corpus_management/components/corpus_upload.vue b/ee/app/assets/javascripts/security_configuration/corpus_management/components/corpus_upload.vue
index 0e355f9d42e82cf764f83365fc54e0fc7258e234..338d88af8c72b123d20139d348a6432eb3307920 100644
--- a/ee/app/assets/javascripts/security_configuration/corpus_management/components/corpus_upload.vue
+++ b/ee/app/assets/javascripts/security_configuration/corpus_management/components/corpus_upload.vue
@@ -74,7 +74,11 @@ export default {
     addCorpus() {
       this.$apollo.mutate({
         mutation: addCorpusMutation,
-        variables: { name: this.$options.i18n.newCorpus, projectPath: this.projectFullPath },
+        variables: {
+          name: this.$options.i18n.newCorpus,
+          projectPath: this.projectFullPath,
+          packageId: this.states.uploadState.uploadedPackageId,
+        },
       });
     },
     resetCorpus() {
diff --git a/ee/app/assets/javascripts/security_configuration/corpus_management/components/corpus_upload_form.vue b/ee/app/assets/javascripts/security_configuration/corpus_management/components/corpus_upload_form.vue
index 485c74d568706214c3751dd2136a496ba132f63f..354ba04646be5b68bb8ddc01e12409cb50aefc5c 100644
--- a/ee/app/assets/javascripts/security_configuration/corpus_management/components/corpus_upload_form.vue
+++ b/ee/app/assets/javascripts/security_configuration/corpus_management/components/corpus_upload_form.vue
@@ -30,7 +30,7 @@ export default {
     corpusName: s__('CorpusManagement|Corpus name'),
     uploadButtonText: __('Choose File...'),
     uploadMessage: s__(
-      'CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB',
+      'CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 5GB',
     ),
   },
   data() {
@@ -170,7 +170,9 @@ export default {
     <div v-if="isUploading" data-testid="upload-status" class="gl-mt-2">
       <gl-loading-icon inline size="sm" />
       {{ progressText }}
-      <gl-button size="small" @click="cancelUpload"> {{ __('Cancel') }} </gl-button>
+      <gl-button size="small" data-testid="cancel-upload" @click="cancelUpload">
+        {{ __('Cancel') }}
+      </gl-button>
     </div>
   </gl-form>
 </template>
diff --git a/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/mutations/add_corpus.mutation.graphql b/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/mutations/add_corpus.mutation.graphql
index 4e982a106f0d31a46bb7f7eea88b0cacb9866aa3..a42d772e2a219063ff9f662d5428f5ea30f3c6b6 100644
--- a/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/mutations/add_corpus.mutation.graphql
+++ b/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/mutations/add_corpus.mutation.graphql
@@ -1,5 +1,5 @@
-mutation addCorpus($projectPath: ID!, $name: String!) {
-  addCorpus(projectPath: $projectPath, name: $name) @client {
+mutation addCorpus($projectPath: ID!, $name: String!, $packageId: Int!) {
+  addCorpus(projectPath: $projectPath, name: $name, packageId: $packageId) @client {
     errors
   }
 }
diff --git a/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/mutations/corpus_create.mutation.graphql b/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/mutations/corpus_create.mutation.graphql
new file mode 100644
index 0000000000000000000000000000000000000000..68e3a5ae3d56d23635a675a813e5dd563611600e
--- /dev/null
+++ b/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/mutations/corpus_create.mutation.graphql
@@ -0,0 +1,5 @@
+mutation CorpusCreate($input: CorpusCreateInput!) {
+  corpusCreate(input: $input) {
+    errors
+  }
+}
diff --git a/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/mutations/upload_complete.mutation.graphql b/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/mutations/upload_complete.mutation.graphql
new file mode 100644
index 0000000000000000000000000000000000000000..7c464d436c819c0a0c0565f4a3ad4d46fd7f7fe5
--- /dev/null
+++ b/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/mutations/upload_complete.mutation.graphql
@@ -0,0 +1,5 @@
+mutation uploadComplete($projectPath: ID!, $packageId: Int!) {
+  uploadComplete(projectPath: $projectPath, packageId: $packageId) @client {
+    errors
+  }
+}
diff --git a/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/queries/get_corpuses.query.graphql b/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/queries/get_corpuses.query.graphql
index 88a939266d88bc5a44f0249add0e26e72b996141..3d3cccb91265d2f830df34f6cb6b2d3128655e50 100644
--- a/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/queries/get_corpuses.query.graphql
+++ b/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/queries/get_corpuses.query.graphql
@@ -7,5 +7,6 @@ query getCorpuses($projectPath: ID!) {
     isUploading
     progress
     cancelSource
+    uploadedPackageId
   }
 }
diff --git a/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/resolvers/resolvers.js b/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/resolvers/resolvers.js
index 57b6ad7ffdb9ffbb60bffa9f1fc5008a8340ff5e..9041f15acb5c6835f53ff28a941c9b5c80733bf1 100644
--- a/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/resolvers/resolvers.js
+++ b/ee/app/assets/javascripts/security_configuration/corpus_management/graphql/resolvers/resolvers.js
@@ -2,8 +2,12 @@ import produce from 'immer';
 import { corpuses } from 'ee_jest/security_configuration/corpus_management/mock_data';
 import { publishPackage } from '~/api/packages_api';
 import axios from '~/lib/utils/axios_utils';
+import { convertToGraphQLId } from '~/graphql_shared/utils';
+import { TYPE_PACKAGES_PACKAGE } from '~/graphql_shared/constants';
 import getCorpusesQuery from '../queries/get_corpuses.query.graphql';
 import updateProgress from '../mutations/update_progress.mutation.graphql';
+import uploadComplete from '../mutations/upload_complete.mutation.graphql';
+import corpusCreate from '../mutations/corpus_create.mutation.graphql';
 
 export default {
   Query: {
@@ -22,12 +26,13 @@ export default {
         isUploading: false,
         progress: 0,
         cancelSource: null,
+        uploadedPackageId: null,
         __typename: 'UploadState',
       };
     },
   },
   Mutation: {
-    addCorpus: (_, { name, projectPath }, { cache }) => {
+    addCorpus: (_, { name, projectPath, packageId }, { cache, client }) => {
       const sourceData = cache.readQuery({
         query: getCorpusesQuery,
         variables: { projectPath },
@@ -54,6 +59,16 @@ export default {
       });
 
       cache.writeQuery({ query: getCorpusesQuery, data, variables: { projectPath } });
+
+      client.mutate({
+        mutation: corpusCreate,
+        variables: {
+          input: {
+            fullPath: projectPath,
+            packageId: convertToGraphQLId(TYPE_PACKAGES_PACKAGE, packageId),
+          },
+        },
+      });
     },
     deleteCorpus: (_, { name, projectPath }, { cache }) => {
       const sourceData = cache.readQuery({
@@ -91,19 +106,43 @@ export default {
         variables: { projectPath },
       });
 
-      const data = produce(sourceData, (draftState) => {
+      const targetData = produce(sourceData, (draftState) => {
         const { uploadState } = draftState;
         uploadState.isUploading = true;
         uploadState.cancelSource = source;
       });
 
-      cache.writeQuery({ query: getCorpusesQuery, data, variables: { projectPath } });
+      cache.writeQuery({ query: getCorpusesQuery, data: targetData, variables: { projectPath } });
 
       publishPackage(
         { projectPath, name, version: 0, fileName: name, files },
         { status: 'hidden', select: 'package_file' },
         { onUploadProgress, cancelToken: source.token },
-      );
+      )
+        .then(({ data }) => {
+          client.mutate({
+            mutation: uploadComplete,
+            variables: { projectPath, packageId: data.package_id },
+          });
+        })
+        .catch((e) => {
+          /* TODO: Error handling */
+        });
+    },
+    uploadComplete: (_, { projectPath, packageId }, { cache }) => {
+      const sourceData = cache.readQuery({
+        query: getCorpusesQuery,
+        variables: { projectPath },
+      });
+
+      const data = produce(sourceData, (draftState) => {
+        const { uploadState } = draftState;
+        uploadState.isUploading = false;
+        uploadState.cancelSource = null;
+        uploadState.uploadedPackageId = packageId;
+      });
+
+      cache.writeQuery({ query: getCorpusesQuery, data, variables: { projectPath } });
     },
     updateProgress: (_, { projectPath, progress }, { cache }) => {
       const sourceData = cache.readQuery({
@@ -115,11 +154,6 @@ export default {
         const { uploadState } = draftState;
         uploadState.isUploading = true;
         uploadState.progress = progress;
-
-        if (progress >= 100) {
-          uploadState.isUploading = false;
-          uploadState.cancelSource = null;
-        }
       });
 
       cache.writeQuery({ query: getCorpusesQuery, data, variables: { projectPath } });
diff --git a/ee/spec/frontend/security_configuration/corpus_management/components/__snapshots__/corpus_upload_form_spec.js.snap b/ee/spec/frontend/security_configuration/corpus_management/components/__snapshots__/corpus_upload_form_spec.js.snap
index 97aaf3cfc35b12a620fbb43727d4565b2843065d..00ffb8b7d10b04996b5a78ca4214d7596600d2cd 100644
--- a/ee/spec/frontend/security_configuration/corpus_management/components/__snapshots__/corpus_upload_form_spec.js.snap
+++ b/ee/spec/frontend/security_configuration/corpus_management/components/__snapshots__/corpus_upload_form_spec.js.snap
@@ -18,6 +18,7 @@ exports[`Corpus upload modal corpus modal uploading state does show the upload p
     
   <button
     class="btn btn-default btn-sm gl-button"
+    data-testid="cancel-upload"
     type="button"
   >
     <!---->
@@ -27,7 +28,9 @@ exports[`Corpus upload modal corpus modal uploading state does show the upload p
     <span
       class="gl-button-text"
     >
-       Cancel 
+      
+      Cancel
+    
     </span>
   </button>
 </div>
diff --git a/ee/spec/frontend/security_configuration/corpus_management/components/corpus_upload_form_spec.js b/ee/spec/frontend/security_configuration/corpus_management/components/corpus_upload_form_spec.js
index 64fbfb33b0f72b081c6f10a024fd5ca2b641b02a..3ed629f8b7705800d9e97501cd78b084a85c2a89 100644
--- a/ee/spec/frontend/security_configuration/corpus_management/components/corpus_upload_form_spec.js
+++ b/ee/spec/frontend/security_configuration/corpus_management/components/corpus_upload_form_spec.js
@@ -1,13 +1,8 @@
-import { createLocalVue, mount } from '@vue/test-utils';
-import VueApollo from 'vue-apollo';
+import { mount } from '@vue/test-utils';
 import CorpusUploadForm from 'ee/security_configuration/corpus_management/components/corpus_upload_form.vue';
-import createMockApollo from 'helpers/mock_apollo_helper';
 
 const TEST_PROJECT_FULL_PATH = '/namespace/project';
 
-const localVue = createLocalVue();
-localVue.use(VueApollo);
-
 describe('Corpus upload modal', () => {
   let wrapper;
 
@@ -15,12 +10,12 @@ describe('Corpus upload modal', () => {
   const findUploadAttachment = () => wrapper.find('[data-testid="upload-attachment-button"]');
   const findUploadCorpus = () => wrapper.find('[data-testid="upload-corpus"]');
   const findUploadStatus = () => wrapper.find('[data-testid="upload-status"]');
+  const findFileInput = () => wrapper.find({ ref: 'fileUpload' });
+  const findCancelButton = () => wrapper.find('[data-testid="cancel-upload"]');
 
   const createComponent = (propsData, options = {}) => {
     wrapper = mount(CorpusUploadForm, {
-      localVue,
       propsData,
-      apolloProvider: createMockApollo(),
       provide: {
         projectFullPath: TEST_PROJECT_FULL_PATH,
       },
@@ -46,10 +41,6 @@ describe('Corpus upload modal', () => {
 
         const props = {
           states: {
-            mockedPackages: {
-              totalSize: 0,
-              data: [],
-            },
             uploadState: {
               isUploading: false,
               progress: 0,
@@ -75,6 +66,15 @@ describe('Corpus upload modal', () => {
       it('does not show the upload progress', () => {
         expect(findUploadStatus().exists()).toBe(false);
       });
+
+      describe('selecting a file', () => {
+        it('transitions to selected state', async () => {
+          jest.spyOn(wrapper.vm, 'onFileUploadChange').mockImplementation(() => {});
+          await wrapper.vm.$forceUpdate();
+          findFileInput().trigger('change');
+          expect(wrapper.vm.onFileUploadChange).toHaveBeenCalled();
+        });
+      });
     });
 
     describe('file selected state', () => {
@@ -87,16 +87,11 @@ describe('Corpus upload modal', () => {
             attachmentName,
             corpusName,
             files: [attachmentName],
-            uploadTimeout: null,
           };
         };
 
         const props = {
           states: {
-            mockedPackages: {
-              totalSize: 0,
-              data: [],
-            },
             uploadState: {
               isUploading: false,
               progress: 0,
@@ -122,6 +117,15 @@ describe('Corpus upload modal', () => {
       it('does not show the upload progress', () => {
         expect(findUploadStatus().exists()).toBe(false);
       });
+
+      describe('clicking upload file', () => {
+        it('begins the file upload', async () => {
+          jest.spyOn(wrapper.vm, 'beginFileUpload').mockImplementation(() => {});
+          await wrapper.vm.$forceUpdate();
+          findUploadCorpus().trigger('click');
+          expect(wrapper.vm.beginFileUpload).toHaveBeenCalled();
+        });
+      });
     });
 
     describe('uploading state', () => {
@@ -134,16 +138,11 @@ describe('Corpus upload modal', () => {
             attachmentName,
             corpusName,
             files: [attachmentName],
-            uploadTimeout: null,
           };
         };
 
         const props = {
           states: {
-            mockedPackages: {
-              totalSize: 0,
-              data: [],
-            },
             uploadState: {
               isUploading: true,
               progress: 25,
@@ -171,6 +170,13 @@ describe('Corpus upload modal', () => {
         expect(findUploadStatus().exists()).toBe(true);
         expect(findUploadStatus().element).toMatchSnapshot();
       });
+
+      describe('clicking cancel button', () => {
+        it('emits the reset corpus event', () => {
+          findCancelButton().trigger('click');
+          expect(wrapper.emitted().resetCorpus).toBeTruthy();
+        });
+      });
     });
 
     describe('file uploaded state', () => {
@@ -183,16 +189,11 @@ describe('Corpus upload modal', () => {
             attachmentName,
             corpusName,
             files: [attachmentName],
-            uploadTimeout: null,
           };
         };
 
         const props = {
           states: {
-            mockedPackages: {
-              totalSize: 0,
-              data: [],
-            },
             uploadState: {
               isUploading: false,
               progress: 100,
diff --git a/ee/spec/frontend/security_configuration/corpus_management/components/corpus_upload_spec.js b/ee/spec/frontend/security_configuration/corpus_management/components/corpus_upload_spec.js
index 83de230d9696521635495e15538d82b4ed952c12..0710d072f1691fce56ae8d6aa09e10b6a8dd6a2c 100644
--- a/ee/spec/frontend/security_configuration/corpus_management/components/corpus_upload_spec.js
+++ b/ee/spec/frontend/security_configuration/corpus_management/components/corpus_upload_spec.js
@@ -1,12 +1,16 @@
-import { GlButton } from '@gitlab/ui';
+import { GlButton, GlModal } from '@gitlab/ui';
 import { shallowMount } from '@vue/test-utils';
 import CorpusUpload from 'ee/security_configuration/corpus_management/components/corpus_upload.vue';
+import CorpusUploadForm from 'ee/security_configuration/corpus_management/components/corpus_upload_form.vue';
 
 const TEST_PROJECT_FULL_PATH = '/namespace/project';
 
 describe('Corpus Upload', () => {
   let wrapper;
 
+  const findModal = () => wrapper.findComponent(GlModal);
+  const findCorpusUploadForm = () => wrapper.findComponent(CorpusUploadForm);
+
   const createComponentFactory = (mountFn = shallowMount) => (options = {}) => {
     const defaultProps = { totalSize: 4e8 };
     wrapper = mountFn(CorpusUpload, {
@@ -37,5 +41,43 @@ describe('Corpus Upload', () => {
       expect(wrapper.findComponent(GlButton).exists()).toBe(true);
       expect(wrapper.element).toMatchSnapshot();
     });
+
+    describe('addCorpus mutation', () => {
+      it('gets called when the add button is clicked from the modal', async () => {
+        createComponent();
+        jest.spyOn(wrapper.vm, 'addCorpus').mockImplementation(() => {});
+        await wrapper.vm.$forceUpdate();
+        findModal().vm.$emit('primary');
+        expect(wrapper.vm.addCorpus).toHaveBeenCalled();
+      });
+    });
+
+    describe('resetCorpus mutation', () => {
+      it('gets called when the cancel button is clicked from the modal', async () => {
+        createComponent();
+        jest.spyOn(wrapper.vm, 'resetCorpus').mockImplementation(() => {});
+        await wrapper.vm.$forceUpdate();
+        findModal().vm.$emit('canceled');
+        expect(wrapper.vm.resetCorpus).toHaveBeenCalled();
+      });
+
+      it('gets called when the upload form triggers a reset', async () => {
+        createComponent();
+        jest.spyOn(wrapper.vm, 'resetCorpus').mockImplementation(() => {});
+        await wrapper.vm.$forceUpdate();
+        findCorpusUploadForm().vm.$emit('resetCorpus');
+        expect(wrapper.vm.resetCorpus).toHaveBeenCalled();
+      });
+    });
+
+    describe('uploadCorpus mutation', () => {
+      it('gets called when the upload file is clicked from the modal', async () => {
+        createComponent();
+        jest.spyOn(wrapper.vm, 'beginFileUpload').mockImplementation(() => {});
+        await wrapper.vm.$forceUpdate();
+        findCorpusUploadForm().vm.$emit('beginFileUpload');
+        expect(wrapper.vm.beginFileUpload).toHaveBeenCalled();
+      });
+    });
   });
 });
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 173056721f00732181c3605261974ec00f6fbc1e..dd7dccbed0eebbde89d5520a77d289e398fc5460 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -9563,7 +9563,7 @@ msgstr ""
 msgid "CorpusManagement|Latest Job:"
 msgstr ""
 
-msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 10GB"
+msgid "CorpusManagement|New corpus needs to be a upload in *.zip format. Maximum 5GB"
 msgstr ""
 
 msgid "CorpusManagement|New upload"