diff --git a/app/models/project.rb b/app/models/project.rb
index d827bfaa806aa83596404798dd742fa9a3c13596..90967a12b963704ec39b7be2b19fe00c3790348a 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1265,7 +1265,18 @@ class Project < ActiveRecord::Base
   end
 
   def remove_private_deploy_keys
-    deploy_keys.where(public: false).delete_all
+    exclude_keys_linked_to_other_projects = <<-SQL
+      NOT EXISTS (
+        SELECT 1
+        FROM deploy_keys_projects dkp2
+        WHERE dkp2.deploy_key_id = deploy_keys_projects.deploy_key_id
+        AND dkp2.project_id != deploy_keys_projects.project_id
+      )
+    SQL
+
+    deploy_keys.where(public: false)
+               .where(exclude_keys_linked_to_other_projects)
+               .delete_all
   end
 
   def remove_pages
diff --git a/changelogs/unreleased/mk-fix-deploy-key-deletion.yml b/changelogs/unreleased/mk-fix-deploy-key-deletion.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9ff2e49b14c769e1524a6cbee3f7ba0b65d18cf0
--- /dev/null
+++ b/changelogs/unreleased/mk-fix-deploy-key-deletion.yml
@@ -0,0 +1,4 @@
+---
+title: Fix deletion of deploy keys linked to other projects
+merge_request: 13162
+author:
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 473b7a88d61e186d7750f858afdfc9687eb47d0e..19808e7d36a53cf203c5ea13bb762319fefff7d0 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -2238,19 +2238,43 @@ describe Project do
   end
 
   describe '#remove_private_deploy_keys' do
-    it 'removes the private deploy keys of a project' do
-      project = create(:empty_project)
+    let!(:project) { create(:empty_project) }
+
+    context 'for a private deploy key' do
+      let!(:key) { create(:deploy_key, public: false) }
+      let!(:deploy_keys_project) { create(:deploy_keys_project, deploy_key: key, project: project) }
+
+      context 'when the key is not linked to another project' do
+        it 'removes the key' do
+          project.remove_private_deploy_keys
+
+          expect(project.deploy_keys).not_to include(key)
+        end
+      end
+
+      context 'when the key is linked to another project' do
+        before do
+          another_project = create(:empty_project)
+          create(:deploy_keys_project, deploy_key: key, project: another_project)
+        end
 
-      private_key = create(:deploy_key, public: false)
-      public_key = create(:deploy_key, public: true)
+        it 'does not remove the key' do
+          project.remove_private_deploy_keys
 
-      create(:deploy_keys_project, deploy_key: private_key, project: project)
-      create(:deploy_keys_project, deploy_key: public_key, project: project)
+          expect(project.deploy_keys).to include(key)
+        end
+      end
+    end
+
+    context 'for a public deploy key' do
+      let!(:key) { create(:deploy_key, public: true) }
+      let!(:deploy_keys_project) { create(:deploy_keys_project, deploy_key: key, project: project) }
 
-      project.remove_private_deploy_keys
+      it 'does not remove the key' do
+        project.remove_private_deploy_keys
 
-      expect(project.deploy_keys.where(public: false).any?).to eq(false)
-      expect(project.deploy_keys.where(public: true).any?).to eq(true)
+        expect(project.deploy_keys).to include(key)
+      end
     end
   end
 end