diff --git a/app/controllers/projects/deploy_keys_controller.rb b/app/controllers/projects/deploy_keys_controller.rb
index 31456fd543da5fa8a61ebf4977e112ba2250b35a..6824a07dc761614cc51d5f1cb00262b7170a81df 100644
--- a/app/controllers/projects/deploy_keys_controller.rb
+++ b/app/controllers/projects/deploy_keys_controller.rb
@@ -24,11 +24,9 @@ def new
   end
 
   def create
-    @key = DeployKeys::CreateService.new(current_user, create_params).execute
+    @key = DeployKeys::CreateService.new(current_user, create_params).execute(project: @project)
 
-    if @key.valid?
-      log_audit_event(@key.title, action: :create)
-    else
+    unless @key.valid?
       flash[:alert] = @key.errors.full_messages.join(', ').html_safe
     end
 
@@ -89,9 +87,4 @@ def update_params
   def authorize_update_deploy_key!
     access_denied! unless can?(current_user, :update_deploy_key, deploy_key)
   end
-
-  def log_audit_event(key_title, options = {})
-    AuditEventService.new(current_user, @project, options)
-      .for_deploy_key(key_title).security_event
-  end
 end
diff --git a/app/services/deploy_keys/create_service.rb b/app/services/deploy_keys/create_service.rb
index a25e73666f847656bc940151256c71af5c6a5491..0142835844a283ca6fd6f702d9627b9db945114f 100644
--- a/app/services/deploy_keys/create_service.rb
+++ b/app/services/deploy_keys/create_service.rb
@@ -2,8 +2,10 @@
 
 module DeployKeys
   class CreateService < Keys::BaseService
-    def execute
+    def execute(project: nil)
       DeployKey.create(params.merge(user: user))
     end
   end
 end
+
+DeployKeys::CreateService.prepend(::EE::DeployKeys::CreateService)
diff --git a/ee/app/services/ee/deploy_keys/create_service.rb b/ee/app/services/ee/deploy_keys/create_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..353791322d5034782d0e5b629c6da1ffe7a20e0e
--- /dev/null
+++ b/ee/app/services/ee/deploy_keys/create_service.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module EE
+  module DeployKeys
+    module CreateService
+      extend ::Gitlab::Utils::Override
+
+      override :execute
+      def execute(project: nil)
+        super.tap do |key|
+          if project && key.persisted?
+            log_audit_event(key.title, project, action: :create)
+          end
+        end
+      end
+
+      private
+
+      def log_audit_event(key_title, project, options = {})
+        ::AuditEventService.new(user, project, options)
+          .for_deploy_key(key_title).security_event
+      end
+    end
+  end
+end
diff --git a/ee/spec/controllers/projects/deploy_keys_controller_spec.rb b/ee/spec/controllers/projects/deploy_keys_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2905e370692a05e9761b8317ddfcb6f56fe0e387
--- /dev/null
+++ b/ee/spec/controllers/projects/deploy_keys_controller_spec.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Projects::DeployKeysController do
+  let(:project) { create(:project, :repository) }
+  let(:user) { create(:user) }
+
+  before do
+    project.add_maintainer(user)
+
+    sign_in(user)
+  end
+
+  describe 'POST create' do
+    let(:deploy_key_attrs) { attributes_for(:deploy_key) }
+    let(:title) { 'my-key' }
+    let(:params) do
+      {
+        namespace_id: project.namespace.path,
+        project_id: project.path,
+        deploy_key: {
+          title: title,
+          key: deploy_key_attrs[:key],
+          deploy_keys_projects_attributes: { '0' => { can_push: '1' } }
+        }
+      }
+    end
+
+    it 'records an audit event' do
+      expect { post :create, params: params }.to change { AuditEvent.count }.by(1)
+
+      expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings'))
+    end
+  end
+
+  describe '/enable/:id' do
+    let(:deploy_key) { create(:deploy_key) }
+    let(:project2) { create(:project) }
+    let!(:deploy_keys_project_internal) do
+      create(:deploy_keys_project, project: project2, deploy_key: deploy_key)
+    end
+
+    context 'with user with permission' do
+      before do
+        project2.add_maintainer(user)
+      end
+
+      it 'records an audit event' do
+        expect do
+          put :enable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project }
+        end.to change { AuditEvent.count }.by(1)
+      end
+
+      it 'returns 404' do
+        put :enable, params: { id: 0, namespace_id: project.namespace, project_id: project }
+
+        expect(response).to have_http_status(404)
+      end
+    end
+  end
+
+  describe '/disable/:id' do
+    let(:deploy_key) { create(:deploy_key) }
+    let!(:deploy_key_project) { create(:deploy_keys_project, project: project, deploy_key: deploy_key) }
+
+    context 'with admin' do
+      before do
+        sign_in(create(:admin))
+      end
+
+      it 'records an audit event' do
+        expect do
+          put :disable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project }
+        end.to change { AuditEvent.count }.by(1)
+      end
+    end
+  end
+end
diff --git a/spec/controllers/projects/deploy_keys_controller_spec.rb b/spec/controllers/projects/deploy_keys_controller_spec.rb
index fd9f8bf9d0c58fba6555b841cf527fefcfd8669e..e54cf3e8181f8fc88fbc1d9eb7dd09c1ce93b337 100644
--- a/spec/controllers/projects/deploy_keys_controller_spec.rb
+++ b/spec/controllers/projects/deploy_keys_controller_spec.rb
@@ -16,7 +16,7 @@
     end
 
     context 'when html requested' do
-      it 'redirects to blob' do
+      it 'redirects to project settings with the correct anchor' do
         get :index, params: params
 
         expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings'))
@@ -60,6 +60,40 @@
     end
   end
 
+  describe 'POST create' do
+    def create_params(title = 'my-key')
+      {
+        namespace_id: project.namespace.path,
+        project_id: project.path,
+        deploy_key: {
+          title: title,
+          key: attributes_for(:deploy_key)[:key],
+          deploy_keys_projects_attributes: { '0' => { can_push: '1' } }
+        }
+      }
+    end
+
+    it 'creates a new deploy key for the project' do
+      expect { post :create, params: create_params }.to change(project.deploy_keys, :count).by(1)
+
+      expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings'))
+    end
+
+    it 'redirects to project settings with the correct anchor' do
+      post :create, params: create_params
+
+      expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings'))
+    end
+
+    context 'when the deploy key is invalid' do
+      it 'shows an alert with the validations errors' do
+        post :create, params: create_params(nil)
+
+        expect(flash[:alert]).to eq("Title can't be blank, Deploy keys projects deploy key title can't be blank")
+      end
+    end
+  end
+
   describe '/enable/:id' do
     let(:deploy_key) { create(:deploy_key) }
     let(:project2) { create(:project) }
@@ -127,7 +161,6 @@
         expect do
           put :enable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project }
         end.to change { DeployKeysProject.count }.by(1)
-           .and change { AuditEvent.count }.by(1) ## EE only
 
         expect(DeployKeysProject.where(project_id: project.id, deploy_key_id: deploy_key.id).count).to eq(1)
         expect(response).to have_http_status(302)
@@ -193,7 +226,6 @@
         expect do
           put :disable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project }
         end.to change { DeployKey.count }.by(-1)
-           .and change { AuditEvent.count }.by(1) ## EE only
 
         expect(response).to have_http_status(302)
         expect(response).to redirect_to(namespace_project_settings_repository_path(anchor: 'js-deploy-keys-settings'))