diff --git a/app/controllers/jira_connect/application_controller.rb b/app/controllers/jira_connect/application_controller.rb
index 9e55aace783263676c9b1088eb2683653c9ab44e..e26d69314cdad629ce6d192eb0a15084f7dd439b 100644
--- a/app/controllers/jira_connect/application_controller.rb
+++ b/app/controllers/jira_connect/application_controller.rb
@@ -3,12 +3,6 @@
 class JiraConnect::ApplicationController < ApplicationController
   include Gitlab::Utils::StrongMemoize
 
-  CORS_ALLOWED_METHODS = {
-    '/-/jira_connect/oauth_application_id' => %i[GET OPTIONS],
-    '/-/jira_connect/subscriptions.json' => %i[GET OPTIONS],
-    '/-/jira_connect/subscriptions/*' => %i[DELETE OPTIONS]
-  }.freeze
-
   skip_before_action :authenticate_user!
   skip_before_action :verify_authenticity_token
   before_action :verify_atlassian_jwt!
@@ -66,25 +60,4 @@ def jwt
   def auth_token
     params[:jwt] || request.headers['Authorization']&.split(' ', 2)&.last
   end
-
-  def cors_allowed_methods
-    CORS_ALLOWED_METHODS[resource]
-  end
-
-  def resource
-    request.path.gsub(%r{/\d+$}, '/*')
-  end
-
-  def set_cors_headers
-    return unless allow_cors_request?
-
-    response.set_header('Access-Control-Allow-Origin', Gitlab::CurrentSettings.jira_connect_proxy_url)
-    response.set_header('Access-Control-Allow-Methods', cors_allowed_methods.join(', '))
-  end
-
-  def allow_cors_request?
-    return false if cors_allowed_methods.nil?
-
-    !Gitlab.com? && Gitlab::CurrentSettings.jira_connect_proxy_url.present?
-  end
 end
diff --git a/app/controllers/jira_connect/cors_preflight_checks_controller.rb b/app/controllers/jira_connect/cors_preflight_checks_controller.rb
deleted file mode 100644
index 3f30c1e04df44829b100b5bf120222b7c8f8f0c9..0000000000000000000000000000000000000000
--- a/app/controllers/jira_connect/cors_preflight_checks_controller.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-module JiraConnect
-  class CorsPreflightChecksController < ApplicationController
-    feature_category :integrations
-
-    skip_before_action :verify_atlassian_jwt!
-    before_action :set_cors_headers
-
-    def index
-      return render_404 unless allow_cors_request?
-
-      render plain: '', content_type: 'text/plain'
-    end
-  end
-end
diff --git a/app/controllers/jira_connect/oauth_application_ids_controller.rb b/app/controllers/jira_connect/oauth_application_ids_controller.rb
index 48827785e56be3d457ed4780056c09bb0a93c392..de520337af3f9c5a691041c5e179b7d40ef63c8e 100644
--- a/app/controllers/jira_connect/oauth_application_ids_controller.rb
+++ b/app/controllers/jira_connect/oauth_application_ids_controller.rb
@@ -5,7 +5,6 @@ class OauthApplicationIdsController < ApplicationController
     feature_category :integrations
 
     skip_before_action :verify_atlassian_jwt!
-    before_action :set_cors_headers
 
     def show
       if show_application_id?
diff --git a/app/controllers/jira_connect/subscriptions_controller.rb b/app/controllers/jira_connect/subscriptions_controller.rb
index da4b25943f730a09ee0f0eccce88835b70e71f93..30cfeb563eb97944264d35ef42b3cf34352182f8 100644
--- a/app/controllers/jira_connect/subscriptions_controller.rb
+++ b/app/controllers/jira_connect/subscriptions_controller.rb
@@ -23,7 +23,6 @@ class JiraConnect::SubscriptionsController < JiraConnect::ApplicationController
     push_frontend_feature_flag(:jira_connect_oauth_self_managed, @user)
   end
 
-  before_action :set_cors_headers
   before_action :allow_rendering_in_iframe, only: :index
   before_action :verify_qsh_claim!, only: :index
   before_action :allow_self_managed_content_security_policy, only: :index
diff --git a/config/application.rb b/config/application.rb
index 249db9c6a67b1014831c00fedba4ebedc2a5ac4c..56eabc59815c9a70b508b7c4d2b020199501a8cf 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -417,6 +417,21 @@ class Application < Rails::Application
           expose: headers_to_expose
       end
 
+      allow do
+        origins { |source, env| source == Gitlab::CurrentSettings.jira_connect_proxy_url }
+        resource '/-/jira_connect/oauth_application_id', headers: :any, credentials: false, methods: %i(get options)
+      end
+
+      allow do
+        origins { |source, env| source == Gitlab::CurrentSettings.jira_connect_proxy_url }
+        resource '/-/jira_connect/subscriptions.json', headers: :any, credentials: false, methods: %i(get options)
+      end
+
+      allow do
+        origins { |source, env| source == Gitlab::CurrentSettings.jira_connect_proxy_url }
+        resource '/-/jira_connect/subscriptions/*', headers: :any, credentials: false, methods: %i(delete options)
+      end
+
       # Cross-origin requests must be enabled for the Authorization code with PKCE OAuth flow when used from a browser.
       %w(/oauth/token /oauth/revoke).each do |oauth_path|
         allow do
diff --git a/config/routes.rb b/config/routes.rb
index e218099ec4a2f0690ab109e7a73d04acd3688cf9..3482b0566ce8863ad0014458e373234e87bf6cef 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -55,10 +55,9 @@
     match '/oauth/token' => 'oauth/tokens#create', via: :options
     match '/oauth/revoke' => 'oauth/tokens#revoke', via: :options
 
-    match '/-/jira_connect/oauth_application_id' => 'jira_connect/cors_preflight_checks#index', via: :options
-    match '/-/jira_connect/subscriptions.json' => 'jira_connect/cors_preflight_checks#index', via: :options
-    match '/-/jira_connect/subscriptions/:id' => 'jira_connect/cors_preflight_checks#index', via: :options
-    match '/-/jira_connect/installations' => 'jira_connect/cors_preflight_checks#index', via: :options
+    match '/-/jira_connect/oauth_application_id' => 'jira_connect/oauth_application_ids#show', via: :options
+    match '/-/jira_connect/subscriptions(.:format)' => 'jira_connect/subscriptions#index', via: :options
+    match '/-/jira_connect/subscriptions/:id' => 'jira_connect/subscriptions#delete', via: :options
 
     # Sign up
     scope path: '/users/sign_up', module: :registrations, as: :users_sign_up do
diff --git a/spec/requests/jira_connect/cors_preflight_checks_controller_spec.rb b/spec/requests/jira_connect/cors_preflight_checks_controller_spec.rb
deleted file mode 100644
index e356aaa3796518fd282ae1ebbc350ed41ade475d..0000000000000000000000000000000000000000
--- a/spec/requests/jira_connect/cors_preflight_checks_controller_spec.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe JiraConnect::CorsPreflightChecksController do
-  shared_examples 'allows cross-origin requests on self managed' do
-    it 'renders not found' do
-      options path
-
-      expect(response).to have_gitlab_http_status(:not_found)
-      expect(response.headers['Access-Control-Allow-Origin']).to be_nil
-    end
-
-    context 'with jira_connect_proxy_url setting' do
-      before do
-        stub_application_setting(jira_connect_proxy_url: 'https://gitlab.com')
-
-        options path, headers: { 'Origin' => 'http://notgitlab.com' }
-      end
-
-      it 'returns 200' do
-        expect(response).to have_gitlab_http_status(:ok)
-      end
-
-      it 'responds with access-control-allow headers', :aggregate_failures do
-        expect(response.headers['Access-Control-Allow-Origin']).to eq 'https://gitlab.com'
-        expect(response.headers['Access-Control-Allow-Methods']).to eq allowed_methods
-        expect(response.headers['Access-Control-Allow-Credentials']).to be_nil
-      end
-
-      context 'when on GitLab.com' do
-        before do
-          allow(Gitlab).to receive(:com?).and_return(true)
-        end
-
-        it 'renders not found' do
-          options path
-
-          expect(response).to have_gitlab_http_status(:not_found)
-          expect(response.headers['Access-Control-Allow-Origin']).to be_nil
-        end
-      end
-    end
-  end
-
-  describe 'OPTIONS /-/jira_connect/oauth_application_id' do
-    let(:allowed_methods) { 'GET, OPTIONS' }
-    let(:path) { '/-/jira_connect/oauth_application_id' }
-
-    it_behaves_like 'allows cross-origin requests on self managed'
-  end
-
-  describe 'OPTIONS /-/jira_connect/subscriptions.json' do
-    let(:allowed_methods) { 'GET, OPTIONS' }
-    let(:path) { '/-/jira_connect/subscriptions.json' }
-
-    it_behaves_like 'allows cross-origin requests on self managed'
-  end
-
-  describe 'OPTIONS /-/jira_connect/subscriptions/:id' do
-    let(:allowed_methods) { 'DELETE, OPTIONS' }
-    let(:path) { '/-/jira_connect/subscriptions/123' }
-
-    it_behaves_like 'allows cross-origin requests on self managed'
-  end
-end
diff --git a/spec/requests/jira_connect/oauth_application_ids_controller_spec.rb b/spec/requests/jira_connect/oauth_application_ids_controller_spec.rb
index 4b3467059ab596445e9a046826f9e0af9416a4c9..ed619bc50a77de88da3c0a084acff26afdfbd941 100644
--- a/spec/requests/jira_connect/oauth_application_ids_controller_spec.rb
+++ b/spec/requests/jira_connect/oauth_application_ids_controller_spec.rb
@@ -4,7 +4,7 @@
 
 RSpec.describe JiraConnect::OauthApplicationIdsController do
   describe 'GET /-/jira_connect/oauth_application_id' do
-    let(:cors_request_headers) { { 'Origin' => 'http://notgitlab.com' } }
+    let(:cors_request_headers) { { 'Origin' => 'https://gitlab.com' } }
 
     before do
       stub_application_setting(jira_connect_application_key: '123456')
@@ -50,4 +50,21 @@
       end
     end
   end
+
+  describe 'OPTIONS /-/jira_connect/oauth_application_id' do
+    let(:cors_request_headers) { { 'Origin' => 'https://gitlab.com', 'access-control-request-method' => 'GET' } }
+
+    before do
+      stub_application_setting(jira_connect_application_key: '123456')
+      stub_application_setting(jira_connect_proxy_url: 'https://gitlab.com')
+    end
+
+    it 'allows cross-origin requests', :aggregate_failures do
+      options '/-/jira_connect/oauth_application_id', headers: cors_request_headers
+
+      expect(response.headers['Access-Control-Allow-Origin']).to eq 'https://gitlab.com'
+      expect(response.headers['Access-Control-Allow-Methods']).to eq 'GET, OPTIONS'
+      expect(response.headers['Access-Control-Allow-Credentials']).to be_nil
+    end
+  end
 end
diff --git a/spec/requests/jira_connect/subscriptions_controller_spec.rb b/spec/requests/jira_connect/subscriptions_controller_spec.rb
index ba195471a12c7526316bf1e4cdae847e3b3f19df..73a825d471ae9bce9dfe82f0a733c80e328e4fa1 100644
--- a/spec/requests/jira_connect/subscriptions_controller_spec.rb
+++ b/spec/requests/jira_connect/subscriptions_controller_spec.rb
@@ -10,7 +10,7 @@
     end
 
     let(:jwt) { Atlassian::Jwt.encode({ iss: installation.client_key, qsh: qsh }, installation.shared_secret) }
-    let(:cors_request_headers) { { 'Origin' => 'http://notgitlab.com' } }
+    let(:cors_request_headers) { { 'Origin' => 'https://gitlab.com' } }
     let(:path) { '/-/jira_connect/subscriptions' }
     let(:params) { { jwt: jwt } }
 
@@ -49,6 +49,38 @@
     end
   end
 
+  describe 'OPTIONS /-/jira_connect/subscriptions' do
+    let(:cors_request_headers) { { 'Origin' => 'https://gitlab.com', 'access-control-request-method' => 'GET' } }
+
+    before do
+      stub_application_setting(jira_connect_proxy_url: 'https://gitlab.com')
+    end
+
+    it 'allows cross-origin requests', :aggregate_failures do
+      options '/-/jira_connect/subscriptions.json', headers: cors_request_headers
+
+      expect(response.headers['Access-Control-Allow-Origin']).to eq 'https://gitlab.com'
+      expect(response.headers['Access-Control-Allow-Methods']).to eq 'GET, OPTIONS'
+      expect(response.headers['Access-Control-Allow-Credentials']).to be_nil
+    end
+  end
+
+  describe 'OPTIONS /-/jira_connect/subscriptions/:id' do
+    let(:cors_request_headers) { { 'Origin' => 'https://gitlab.com', 'access-control-request-method' => 'DELETE' } }
+
+    before do
+      stub_application_setting(jira_connect_proxy_url: 'https://gitlab.com')
+    end
+
+    it 'allows cross-origin requests', :aggregate_failures do
+      options '/-/jira_connect/subscriptions/1', headers: cors_request_headers
+
+      expect(response.headers['Access-Control-Allow-Origin']).to eq 'https://gitlab.com'
+      expect(response.headers['Access-Control-Allow-Methods']).to eq 'DELETE, OPTIONS'
+      expect(response.headers['Access-Control-Allow-Credentials']).to be_nil
+    end
+  end
+
   describe 'DELETE /-/jira_connect/subscriptions/:id' do
     let_it_be(:installation) { create(:jira_connect_installation, instance_url: 'http://self-managed-gitlab.com') }
     let_it_be(:subscription) { create(:jira_connect_subscription, installation: installation) }
@@ -58,7 +90,7 @@
     end
 
     let(:jwt) { Atlassian::Jwt.encode({ iss: installation.client_key, qsh: qsh }, installation.shared_secret) }
-    let(:cors_request_headers) { { 'Origin' => 'http://notgitlab.com' } }
+    let(:cors_request_headers) { { 'Origin' => 'https://gitlab.com' } }
     let(:params) { { jwt: jwt, format: :json } }
 
     before do