diff --git a/ee/app/controllers/ee/sessions_controller.rb b/ee/app/controllers/ee/sessions_controller.rb
index 49f86271a66041695f999d4c6b4f63670bb28709..f33527408e39f037d99c57fded665ab6e182bf40 100644
--- a/ee/app/controllers/ee/sessions_controller.rb
+++ b/ee/app/controllers/ee/sessions_controller.rb
@@ -103,7 +103,9 @@ def check_arkose_captcha
     end
 
     def verify_arkose_token(user)
-      if Arkose::UserVerificationService.new(session_token: params[:arkose_labs_token], user: user).execute
+      result = Arkose::TokenVerificationService.new(session_token: params[:arkose_labs_token], user: user).execute
+
+      if result.success? && result.payload[:low_risk]
         increment_successful_login_captcha_counter
       else
         failed_login_captcha
diff --git a/ee/app/services/arkose/record_user_data_service.rb b/ee/app/services/arkose/record_user_data_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5861927bcbc95e2befe7605e2699ed9ebb15ae83
--- /dev/null
+++ b/ee/app/services/arkose/record_user_data_service.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module Arkose
+  class RecordUserDataService
+    attr_reader :response, :user
+
+    def initialize(response:, user:)
+      @response = response
+      @user = user
+    end
+
+    def execute
+      return ServiceResponse.error(message: 'user is required') unless user.present?
+      return ServiceResponse.error(message: 'Invalid Arkose Labs token') if response.invalid_token?
+
+      add_or_update_arkose_attributes
+
+      ServiceResponse.success
+    end
+
+    private
+
+    def add_or_update_arkose_attributes
+      return if Gitlab::Database.read_only?
+
+      UserCustomAttribute.upsert_custom_attributes(custom_attributes)
+    end
+
+    def custom_attributes
+      custom_attributes = []
+      custom_attributes.push({ key: 'arkose_session', value: response.session_id })
+      custom_attributes.push({ key: 'arkose_risk_band', value: response.risk_band })
+      custom_attributes.push({ key: 'arkose_global_score', value: response.global_score })
+      custom_attributes.push({ key: 'arkose_custom_score', value: response.custom_score })
+
+      custom_attributes.map! { |custom_attribute| custom_attribute.merge({ user_id: user.id }) }
+      custom_attributes
+    end
+  end
+end
diff --git a/ee/app/services/arkose/user_verification_service.rb b/ee/app/services/arkose/token_verification_service.rb
similarity index 53%
rename from ee/app/services/arkose/user_verification_service.rb
rename to ee/app/services/arkose/token_verification_service.rb
index fbb777131c60f946bc6832be975f81f61fa82e3e..2b97df00d03b3b4da76e7a1af19b6d949fbbedd3 100644
--- a/ee/app/services/arkose/user_verification_service.rb
+++ b/ee/app/services/arkose/token_verification_service.rb
@@ -1,78 +1,71 @@
 # frozen_string_literal: true
+
 module Arkose
-  class UserVerificationService
-    attr_reader :url, :session_token, :user, :response
+  class TokenVerificationService
+    attr_reader :session_token, :user
 
     ARKOSE_LABS_DEFAULT_NAMESPACE = 'client'
     ARKOSE_LABS_DEFAULT_SUBDOMAIN = 'verify-api'
 
-    def initialize(session_token:, user:)
+    def initialize(session_token:, user: nil)
       @session_token = session_token
       @user = user
     end
 
     def execute
-      json_response = Gitlab::HTTP.perform_request(Net::HTTP::Post, arkose_verify_url, body: body).parsed_response
-      @response = VerifyResponse.new(json_response)
+      response = Gitlab::HTTP.perform_request(Net::HTTP::Post, arkose_verify_url, body: body).parsed_response
+      response = ::Arkose::VerifyResponse.new(response)
 
-      logger.info(build_message)
+      logger.info(build_message(response))
 
-      return false if response.invalid_token?
+      return ServiceResponse.error(message: response.error) if response.invalid_token?
 
-      add_or_update_arkose_attributes
+      RecordUserDataService.new(response: response, user: user).execute
 
-      response.allowlisted? || (response.challenge_solved? && response.low_risk?)
+      if response.allowlisted? || response.challenge_solved?
+        ServiceResponse.success(payload: { low_risk: response.allowlisted? || response.low_risk? })
+      else
+        ServiceResponse.error(message: 'Captcha was not solved')
+      end
     rescue StandardError => error
-      payload = { session_token: session_token, log_data: user.id }
+      payload = {
+        # Allow user to proceed when we can't verify the token for some
+        # unexpected reason (e.g. ArkoseLabs is down)
+        low_risk: true,
+        session_token: session_token,
+        log_data: user&.id
+      }.compact
       Gitlab::ExceptionLogFormatter.format!(error, payload)
       Gitlab::ErrorTracking.track_exception(error)
       logger.error("Error verifying user on Arkose: #{payload}")
 
-      true
+      ServiceResponse.success(payload: payload)
     end
 
     private
 
-    def add_or_update_arkose_attributes
-      return if Gitlab::Database.read_only?
-
-      UserCustomAttribute.upsert_custom_attributes(custom_attributes)
-    end
-
-    def custom_attributes
-      custom_attributes = []
-      custom_attributes.push({ key: 'arkose_session', value: response.session_id })
-      custom_attributes.push({ key: 'arkose_risk_band', value: response.risk_band })
-      custom_attributes.push({ key: 'arkose_global_score', value: response.global_score })
-      custom_attributes.push({ key: 'arkose_custom_score', value: response.custom_score })
-
-      custom_attributes.map! { |custom_attribute| custom_attribute.merge({ user_id: user.id }) }
-      custom_attributes
-    end
-
     def body
       {
         private_key: Settings.arkose_private_api_key,
         session_token: session_token,
-        log_data: user.id
-      }
+        log_data: user&.id
+      }.compact
     end
 
     def logger
       Gitlab::AppLogger
     end
 
-    def build_message
+    def build_message(response)
       Gitlab::ApplicationContext.current.symbolize_keys.merge(
         {
           message: 'Arkose verify response',
           response: response.response,
-          username: user.username
-        }.merge(arkose_payload)
-      )
+          username: user&.username
+        }.compact).merge(arkose_payload(response))
     end
 
-    def arkose_payload
+    def arkose_payload(response)
       {
         'arkose.session_id': response.session_id,
         'arkose.global_score': response.global_score,
diff --git a/ee/lib/arkose/verify_response.rb b/ee/lib/arkose/verify_response.rb
index 60e7fc05d9ac67a78f6ebfdffe7a081d3a50ae75..f5c4748b157249db1785c00e1c67ba10808a7837 100644
--- a/ee/lib/arkose/verify_response.rb
+++ b/ee/lib/arkose/verify_response.rb
@@ -4,9 +4,15 @@ module Arkose
   class VerifyResponse
     attr_reader :response
 
+    InvalidResponseFormatError = Class.new(StandardError)
+
     ALLOWLIST_TELLTALE = 'gitlab1-whitelist-qa-team'
 
     def initialize(response)
+      unless response.is_a? Hash
+        raise InvalidResponseFormatError, "Arkose Labs Verify API returned a #{response.class} instead of of an object"
+      end
+
       @response = response
     end
 
diff --git a/ee/spec/controllers/ee/sessions_controller_spec.rb b/ee/spec/controllers/ee/sessions_controller_spec.rb
index 24c08377a8e4808f887a27273a187f7c8d7b38ff..abf0c7826b40de3688043411bd2407cbd2971175 100644
--- a/ee/spec/controllers/ee/sessions_controller_spec.rb
+++ b/ee/spec/controllers/ee/sessions_controller_spec.rb
@@ -175,20 +175,38 @@ def authenticate_2fa(otp_user_id: user.id, **user_params)
       end
 
       context 'when the user was verified by Arkose' do
-        it 'successfully logs in a user when reCAPTCHA is solved' do
-          allow_next_instance_of(Arkose::UserVerificationService) do |instance|
-            allow(instance).to receive(:execute).and_return(true)
+        before do
+          allow_next_instance_of(Arkose::TokenVerificationService) do |instance|
+            response = ServiceResponse.success(payload: { low_risk: low_risk })
+            allow(instance).to receive(:execute).and_return(response)
           end
+
           post(:create, params: params, session: {})
+        end
 
-          expect(subject.current_user).to eq user
+        context 'when user is low risk' do
+          let(:low_risk) { true }
+
+          it 'successfully logs in the user' do
+            expect(subject.current_user).to eq user
+          end
+        end
+
+        context 'when user is NOT low risk' do
+          let(:low_risk) { false }
+
+          it 'prevents the user from logging in' do
+            expect(response).to render_template(:new)
+            expect(flash[:alert]).to include 'Login failed. Please retry from your primary device and network'
+            expect(subject.current_user).to be_nil
+          end
         end
       end
 
       context 'when the user was not verified by Arkose' do
         before do
-          allow_next_instance_of(Arkose::UserVerificationService) do |instance|
-            allow(instance).to receive(:execute).and_return(false)
+          allow_next_instance_of(Arkose::TokenVerificationService) do |instance|
+            allow(instance).to receive(:execute).and_return(ServiceResponse.error(message: 'Captcha was not solved'))
           end
         end
 
diff --git a/ee/spec/lib/arkose/verify_response_spec.rb b/ee/spec/lib/arkose/verify_response_spec.rb
index 42814c422f22a331a9072c076b73c207b22d94c8..1aa1cdb315190d4a17359e32bf8fc030457b9848 100644
--- a/ee/spec/lib/arkose/verify_response_spec.rb
+++ b/ee/spec/lib/arkose/verify_response_spec.rb
@@ -27,6 +27,23 @@ def parse_json(file_path)
     parse_json('ee/spec/fixtures/arkose/allowlisted_response.json')
   end
 
+  describe '.new' do
+    context 'when response is not a Hash' do
+      it 'raises an InvalidResponseFormatError error' do
+        expect { described_class.new('a_string') }.to raise_error(
+          described_class::InvalidResponseFormatError,
+          "Arkose Labs Verify API returned a String instead of of an object"
+        )
+      end
+    end
+
+    context 'when response is a Hash' do
+      it 'does not raise an InvalidResponseFormatError error' do
+        expect { described_class.new({}) }.not_to raise_error
+      end
+    end
+  end
+
   describe '#invalid_token?' do
     subject { described_class.new(json_response).invalid_token? }
 
diff --git a/ee/spec/services/arkose/record_user_data_service_spec.rb b/ee/spec/services/arkose/record_user_data_service_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3153fc695173999f7dfad931b6b224cb5a0d2713
--- /dev/null
+++ b/ee/spec/services/arkose/record_user_data_service_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Arkose::RecordUserDataService do
+  let(:user) { create(:user) }
+
+  let(:arkose_verify_response) do
+    Gitlab::Json.parse(File.read(Rails.root.join('ee/spec/fixtures/arkose/successfully_solved_ec_response.json')))
+  end
+
+  let(:response) { Arkose::VerifyResponse.new(arkose_verify_response) }
+  let(:service) { described_class.new(response: response, user: user) }
+
+  describe '#execute' do
+    it 'adds new custom attributes to the user' do
+      expect { service.execute }.to change { user.custom_attributes.count }.from(0).to(4)
+    end
+
+    it 'adds arkose data to custom attributes' do
+      service.execute
+
+      expect(user.custom_attributes.find_by(key: 'arkose_session').value).to eq('22612c147bb418c8.2570749403')
+      expect(user.custom_attributes.find_by(key: 'arkose_risk_band').value).to eq('Low')
+      expect(user.custom_attributes.find_by(key: 'arkose_global_score').value).to eq('0')
+      expect(user.custom_attributes.find_by(key: 'arkose_custom_score').value).to eq('0')
+    end
+
+    it 'returns a success response' do
+      expect(service.execute).to be_success
+    end
+
+    context 'when response is from failed verification' do
+      let(:arkose_verify_response) do
+        Gitlab::Json.parse(File.read(Rails.root.join('ee/spec/fixtures/arkose/invalid_token.json')))
+      end
+
+      it 'does not add any custom attributes' do
+        expect { service.execute }.not_to change { user.custom_attributes.count }
+      end
+
+      it 'returns an error response' do
+        expect(service.execute).to be_error
+      end
+    end
+
+    context 'when user is nil' do
+      let(:user) { nil }
+
+      it 'returns an error response' do
+        expect(service.execute).to be_error
+      end
+    end
+  end
+end
diff --git a/ee/spec/services/arkose/token_verification_service_spec.rb b/ee/spec/services/arkose/token_verification_service_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e650249060291ec633475a6ed522711afdefad9d
--- /dev/null
+++ b/ee/spec/services/arkose/token_verification_service_spec.rb
@@ -0,0 +1,287 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Arkose::TokenVerificationService do
+  let(:user) { create(:user) }
+  let(:session_token) { '22612c147bb418c8.2570749403' }
+  let(:service) { described_class.new(session_token: session_token, user: user) }
+  let(:verify_api_url) { "https://verify-api.arkoselabs.com/api/v4/verify/" }
+  let(:arkose_labs_private_api_key) { 'foo' }
+
+  subject { service.execute }
+
+  before do
+    stub_request(:post, verify_api_url)
+      .with(
+        body: /.*/,
+        headers: {
+          'Accept' => '*/*'
+        }
+      ).to_return(
+        status: 200,
+        body: arkose_ec_response.to_json,
+        headers: { 'Content-Type' => 'application/json' }
+      )
+  end
+
+  describe '#execute' do
+    shared_examples_for 'interacting with Arkose verify API' do |url|
+      let(:verify_api_url) { url }
+
+      context 'when the user did not solve the challenge' do
+        let(:arkose_ec_response) do
+          Gitlab::Json.parse(File.read(Rails.root.join('ee/spec/fixtures/arkose/failed_ec_response.json')))
+        end
+
+        it 'returns an error response' do
+          expect(subject).to be_error
+        end
+
+        it 'returns an error message' do
+          expect(subject.message).to eq 'Captcha was not solved'
+        end
+      end
+
+      context 'when feature arkose_labs_prevent_login is enabled' do
+        context 'when the user solved the challenge' do
+          context 'when the risk score is low' do
+            let(:arkose_ec_response) do
+              Gitlab::Json.parse(
+                File.read(Rails.root.join('ee/spec/fixtures/arkose/successfully_solved_ec_response.json'))
+              )
+            end
+
+            it 'makes a request to the Verify API' do
+              subject
+
+              expect(WebMock).to have_requested(:post, verify_api_url)
+            end
+
+            it 'returns a success response' do
+              expect(subject).to be_success
+            end
+
+            it 'returns { low_risk: true } payload' do
+              expect(subject.payload[:low_risk]).to eq true
+            end
+
+            it 'logs Arkose verify response' do
+              allow(Gitlab::AppLogger).to receive(:info)
+              allow(Gitlab::ApplicationContext).to receive(:current).and_return(
+                { 'correlation_id': 'be025cf83013ac4f52ffd2bf712b11a2' }
+              )
+
+              subject
+
+              expect(Gitlab::AppLogger).to have_received(:info).with(
+                correlation_id: 'be025cf83013ac4f52ffd2bf712b11a2',
+                message: 'Arkose verify response',
+                response: arkose_ec_response,
+                username: user.username,
+                'arkose.session_id': '22612c147bb418c8.2570749403',
+                'arkose.global_score': '0',
+                'arkose.global_telltale_list': [],
+                'arkose.custom_score': '0',
+                'arkose.custom_telltale_list': [],
+                'arkose.risk_band': 'Low',
+                'arkose.risk_category': 'NO-THREAT'
+              )
+            end
+
+            it "records user's Arkose data" do
+              mock_response = Arkose::VerifyResponse.new(arkose_ec_response)
+              expect(Arkose::VerifyResponse).to receive(:new).with(arkose_ec_response).and_return(mock_response)
+
+              expect_next_instance_of(Arkose::RecordUserDataService, response: mock_response, user: user) do |service|
+                expect(service).to receive(:execute)
+              end
+
+              subject
+            end
+
+            context 'when the session is allowlisted' do
+              let(:arkose_ec_response) do
+                json = Gitlab::Json.parse(
+                  File.read(Rails.root.join('ee/spec/fixtures/arkose/successfully_solved_ec_response_high_risk.json'))
+                )
+                json['session_details']['telltale_list'].push(Arkose::VerifyResponse::ALLOWLIST_TELLTALE)
+                json
+              end
+
+              it 'returns a success response' do
+                expect(subject).to be_success
+              end
+
+              it 'returns { low_risk: true } payload' do
+                expect(subject.payload[:low_risk]).to eq true
+              end
+            end
+
+            context 'when the risk score is high' do
+              let(:arkose_ec_response) do
+                Gitlab::Json.parse(
+                  File.read(Rails.root.join('ee/spec/fixtures/arkose/successfully_solved_ec_response_high_risk.json'))
+                )
+              end
+
+              it 'returns a success response' do
+                expect(subject).to be_success
+              end
+
+              it 'returns { low_risk: false } payload' do
+                expect(subject.payload[:low_risk]).to eq false
+              end
+            end
+          end
+        end
+
+        context 'when the response does not include the risk session' do
+          context 'when the user solved the challenge' do
+            let(:arkose_ec_response) do
+              Gitlab::Json.parse(
+                File.read(
+                  Rails.root.join('ee/spec/fixtures/arkose/successfully_solved_ec_response_without_session_risk.json')
+                )
+              )
+            end
+
+            it 'returns a success response' do
+              expect(subject).to be_success
+            end
+
+            it 'returns { low_risk: true } payload' do
+              expect(subject.payload[:low_risk]).to eq true
+            end
+          end
+
+          context 'when the user did not solve the challenge' do
+            let(:arkose_ec_response) do
+              Gitlab::Json.parse(
+                File.read(Rails.root.join('ee/spec/fixtures/arkose/failed_ec_response_without_risk_session.json'))
+              )
+            end
+
+            it 'returns an error response' do
+              expect(subject).to be_error
+            end
+
+            it 'returns an error message' do
+              expect(subject.message).to eq 'Captcha was not solved'
+            end
+          end
+        end
+      end
+
+      context 'when response from Arkose is not what we expect' do
+        # For example: https://gitlab.com/gitlab-org/modelops/anti-abuse/team-tasks/-/issues/54
+
+        let(:arkose_ec_response) { 'unexpected_from_arkose' }
+
+        it 'returns a success response' do
+          expect(subject).to be_success
+        end
+
+        it 'returns { low_risk: true } payload' do
+          expect(subject.payload[:low_risk]).to eq true
+        end
+
+        it 'logs the error' do
+          expect(Gitlab::AppLogger).to receive(:error).with(a_string_matching(/Error verifying user on Arkose: /))
+
+          subject
+        end
+      end
+
+      context 'when an error occurs during the Arkose request' do
+        let(:arkose_ec_response) { {} }
+
+        before do
+          allow(Gitlab::HTTP).to receive(:perform_request).and_raise(Errno::ECONNREFUSED.new('bad connection'))
+        end
+
+        it 'returns a success response' do
+          expect(subject).to be_success
+        end
+
+        it 'returns { low_risk: true } payload' do
+          expect(subject.payload[:low_risk]).to eq true
+        end
+
+        it 'logs the error' do
+          expect(Gitlab::AppLogger).to receive(:error).with(a_string_matching(/Error verifying user on Arkose: /))
+
+          subject
+        end
+      end
+
+      context 'when user is nil' do
+        let(:user) { nil }
+        let(:arkose_ec_response) do
+          Gitlab::Json.parse(File.read(Rails.root.join('ee/spec/fixtures/arkose/successfully_solved_ec_response.json')))
+        end
+
+        it 'logs Arkose verify response without username' do
+          allow(Gitlab::AppLogger).to receive(:info)
+          allow(Gitlab::ApplicationContext).to receive(:current).and_return(
+            { 'correlation_id': 'be025cf83013ac4f52ffd2bf712b11a2' }
+          )
+
+          subject
+
+          expect(Gitlab::AppLogger).to have_received(:info).with(
+            correlation_id: 'be025cf83013ac4f52ffd2bf712b11a2',
+            message: 'Arkose verify response',
+            response: arkose_ec_response,
+            'arkose.session_id': '22612c147bb418c8.2570749403',
+            'arkose.global_score': '0',
+            'arkose.global_telltale_list': [],
+            'arkose.custom_score': '0',
+            'arkose.custom_telltale_list': [],
+            'arkose.risk_band': 'Low',
+            'arkose.risk_category': 'NO-THREAT'
+          )
+        end
+      end
+    end
+
+    context 'when Arkose is configured using application settings' do
+      before do
+        stub_application_setting(arkose_labs_private_api_key: arkose_labs_private_api_key)
+        stub_application_setting(arkose_labs_namespace: "gitlab")
+      end
+
+      it_behaves_like 'interacting with Arkose verify API', "https://gitlab-verify.arkoselabs.com/api/v4/verify/"
+    end
+
+    context 'when Arkose application settings are not present, fallback to environment variables' do
+      before do
+        stub_env('ARKOSE_LABS_PRIVATE_KEY': arkose_labs_private_api_key)
+      end
+
+      it_behaves_like 'interacting with Arkose verify API', "https://verify-api.arkoselabs.com/api/v4/verify/"
+    end
+
+    context 'when feature arkose_labs_prevent_login is disabled' do
+      before do
+        stub_feature_flags(arkose_labs_prevent_login: false)
+      end
+
+      context 'when the risk score is high' do
+        let(:arkose_ec_response) do
+          Gitlab::Json.parse(
+            File.read(Rails.root.join('ee/spec/fixtures/arkose/successfully_solved_ec_response_high_risk.json'))
+          )
+        end
+
+        it 'returns a success response' do
+          expect(subject).to be_success
+        end
+
+        it 'returns { low_risk: true } payload' do
+          expect(subject.payload[:low_risk]).to eq true
+        end
+      end
+    end
+  end
+end
diff --git a/ee/spec/services/arkose/user_verification_service_spec.rb b/ee/spec/services/arkose/user_verification_service_spec.rb
deleted file mode 100644
index fbd4d9475e0ca4ce7cc040932cdbe7bceef3e008..0000000000000000000000000000000000000000
--- a/ee/spec/services/arkose/user_verification_service_spec.rb
+++ /dev/null
@@ -1,166 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Arkose::UserVerificationService do
-  let(:session_token) { '22612c147bb418c8.2570749403' }
-  let_it_be_with_reload(:user) { create(:user, id: '1999') }
-
-  let(:service) { Arkose::UserVerificationService.new(session_token: session_token, user: user) }
-  let(:verify_api_url) { "https://verify-api.arkoselabs.com/api/v4/verify/" }
-  let(:response_status_code) { 200 }
-  let(:arkose_labs_private_api_key) { 'foo' }
-
-  subject { service.execute }
-
-  before do
-    stub_request(:post, verify_api_url)
-      .with(
-        body: /.*/,
-        headers: {
-          'Accept' => '*/*'
-        }
-      ).to_return(status: response_status_code, body: arkose_ec_response.to_json, headers: {
-        'Content-Type' => 'application/json'
-      })
-  end
-
-  describe '#execute' do
-    shared_examples_for 'interacting with Arkose verify API' do |url|
-      let(:verify_api_url) { url }
-
-      context 'when the user did not solve the challenge' do
-        let(:arkose_ec_response) { Gitlab::Json.parse(File.read(Rails.root.join('ee/spec/fixtures/arkose/failed_ec_response.json'))) }
-
-        it 'returns false' do
-          expect(subject).to be_falsey
-        end
-      end
-
-      context 'when feature arkose_labs_prevent_login is enabled' do
-        context 'when the user solved the challenge' do
-          context 'when the risk score is not high' do
-            let(:arkose_ec_response) { Gitlab::Json.parse(File.read(Rails.root.join('ee/spec/fixtures/arkose/successfully_solved_ec_response.json'))) }
-
-            it 'makes a request to the Verify API' do
-              subject
-
-              expect(WebMock).to have_requested(:post, verify_api_url)
-            end
-
-            it 'returns true' do
-              expect(subject).to be_truthy
-            end
-
-            it 'adds arkose data to custom attributes' do
-              subject
-              expect(user.custom_attributes.count).to eq(4)
-
-              expect(user.custom_attributes.find_by(key: 'arkose_session').value).to eq('22612c147bb418c8.2570749403')
-              expect(user.custom_attributes.find_by(key: 'arkose_risk_band').value).to eq('Low')
-              expect(user.custom_attributes.find_by(key: 'arkose_global_score').value).to eq('0')
-              expect(user.custom_attributes.find_by(key: 'arkose_custom_score').value).to eq('0')
-            end
-
-            it 'logs Arkose verify response' do
-              allow(Gitlab::AppLogger).to receive(:info)
-              allow(Gitlab::ApplicationContext).to receive(:current).and_return({ 'correlation_id': 'be025cf83013ac4f52ffd2bf712b11a2' })
-
-              subject
-
-              expect(Gitlab::AppLogger).to have_received(:info).with(correlation_id: 'be025cf83013ac4f52ffd2bf712b11a2',
-                                                                     message: 'Arkose verify response',
-                                                                     response: arkose_ec_response,
-                                                                     username: user.username,
-                                                                     'arkose.session_id': '22612c147bb418c8.2570749403',
-                                                                     'arkose.global_score': '0',
-                                                                     'arkose.global_telltale_list': [],
-                                                                     'arkose.custom_score': '0',
-                                                                     'arkose.custom_telltale_list': [],
-                                                                     'arkose.risk_band': 'Low',
-                                                                     'arkose.risk_category': 'NO-THREAT')
-            end
-
-            context 'when the risk score is high' do
-              let(:arkose_ec_response) { Gitlab::Json.parse(File.read(Rails.root.join('ee/spec/fixtures/arkose/successfully_solved_ec_response_high_risk.json'))) }
-
-              it 'returns false' do
-                expect(subject).to be_falsey
-              end
-
-              context 'when the session is allowlisted' do
-                let(:arkose_ec_response) do
-                  json = Gitlab::Json.parse(File.read(Rails.root.join('ee/spec/fixtures/arkose/successfully_solved_ec_response.json')))
-                  json['session_details']['telltale_list'].push(Arkose::VerifyResponse::ALLOWLIST_TELLTALE)
-                  json
-                end
-
-                it 'returns true' do
-                  expect(subject).to be_truthy
-                end
-              end
-            end
-          end
-        end
-
-        context 'when the response does not include the risk session' do
-          context 'when the user solved the challenge' do
-            let(:arkose_ec_response) { Gitlab::Json.parse(File.read(Rails.root.join('ee/spec/fixtures/arkose/successfully_solved_ec_response_without_session_risk.json'))) }
-
-            it 'returns true' do
-              expect(subject).to be_truthy
-            end
-          end
-
-          context 'when the user did not solve the challenge' do
-            let(:arkose_ec_response) { Gitlab::Json.parse(File.read(Rails.root.join('ee/spec/fixtures/arkose/failed_ec_response_without_risk_session.json'))) }
-
-            it 'returns false' do
-              expect(subject).to be_falsey
-            end
-          end
-        end
-      end
-
-      context 'when an error occurs during the Arkose request' do
-        let(:arkose_ec_response) { {} }
-        let(:response_status_code) { 500 }
-
-        it 'returns true' do
-          expect(subject).to be_truthy
-        end
-      end
-    end
-
-    context 'when Arkose is configured using application settings' do
-      before do
-        stub_application_setting(arkose_labs_private_api_key: arkose_labs_private_api_key)
-        stub_application_setting(arkose_labs_namespace: "gitlab")
-      end
-
-      it_behaves_like 'interacting with Arkose verify API', "https://gitlab-verify.arkoselabs.com/api/v4/verify/"
-    end
-
-    context 'when Arkose application settings are not present, fallback to environment variables' do
-      before do
-        stub_env('ARKOSE_LABS_PRIVATE_KEY': arkose_labs_private_api_key)
-      end
-
-      it_behaves_like 'interacting with Arkose verify API', "https://verify-api.arkoselabs.com/api/v4/verify/"
-    end
-
-    context 'when feature arkose_labs_prevent_login is disabled' do
-      before do
-        stub_feature_flags(arkose_labs_prevent_login: false)
-      end
-
-      context 'when the risk score is high' do
-        let(:arkose_ec_response) { Gitlab::Json.parse(File.read(Rails.root.join('ee/spec/fixtures/arkose/successfully_solved_ec_response_high_risk.json'))) }
-
-        it 'returns true' do
-          expect(subject).to be_truthy
-        end
-      end
-    end
-  end
-end