diff --git a/qa/qa.rb b/qa/qa.rb
index 237086996fdbae5131dbbeeef18f4941c5997a53..e084ef17985df4ef510668e98eb346a9cb314639 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -114,6 +114,7 @@ module Instance
       module Integration
         autoload :Github, 'qa/scenario/test/integration/github'
         autoload :LDAPNoTLS, 'qa/scenario/test/integration/ldap_no_tls'
+        autoload :LDAPNoServer, 'qa/scenario/test/integration/ldap_no_server'
         autoload :LDAPTLS, 'qa/scenario/test/integration/ldap_tls'
         autoload :InstanceSAML, 'qa/scenario/test/integration/instance_saml'
         autoload :OAuth, 'qa/scenario/test/integration/oauth'
@@ -394,6 +395,7 @@ module Service
     autoload :KubernetesCluster, 'qa/service/kubernetes_cluster'
     autoload :Omnibus, 'qa/service/omnibus'
     autoload :Runner, 'qa/service/runner'
+    autoload :LDAP, 'qa/service/ldap'
 
     module ClusterProvider
       autoload :Base, 'qa/service/cluster_provider/base'
diff --git a/qa/qa/fixtures/ldap/admin/1_add_nodes.ldif b/qa/qa/fixtures/ldap/admin/1_add_nodes.ldif
new file mode 100644
index 0000000000000000000000000000000000000000..1476f53a0b952867b408de125b5af3b47c048fe9
--- /dev/null
+++ b/qa/qa/fixtures/ldap/admin/1_add_nodes.ldif
@@ -0,0 +1,7 @@
+dn: ou=Global Groups,dc=example,dc=org
+objectClass: organizationalUnit
+ou: Global Groups
+
+dn: ou=People,ou=Global Groups,dc=example,dc=org
+objectClass: organizationalUnit
+ou: People
diff --git a/qa/qa/fixtures/ldap/admin/2_add_users.ldif b/qa/qa/fixtures/ldap/admin/2_add_users.ldif
new file mode 100644
index 0000000000000000000000000000000000000000..00ba2fe8397993e753fdda5fb87ea11ddcb21eea
--- /dev/null
+++ b/qa/qa/fixtures/ldap/admin/2_add_users.ldif
@@ -0,0 +1,63 @@
+
+# 1. hruser1
+
+dn: uid=hruser1,ou=People,ou=Global Groups,dc=example,dc=org
+cn: HR User 1
+givenName: HR
+sn: User1
+uid: hruser1
+uidNumber: 5000
+gidNumber: 10000
+homeDirectory: /home/hruser1
+mail: hruser1@example.org
+objectClass: top
+objectClass: posixAccount
+objectClass: shadowAccount
+objectClass: inetOrgPerson
+objectClass: organizationalPerson
+objectClass: person
+loginShell: /bin/bash
+# hashed value for 'password'
+userPassword: {SSHA}ICMhr6Jxt5bk2awD7HL7GxRTM3BZ1pFI
+
+# 2. adminuser1
+
+dn: uid=adminuser1,ou=People,ou=Global Groups,dc=example,dc=org
+cn: Admin User 1
+givenName: Admin
+sn: User1
+uid: adminuser1
+uidNumber: 5009
+gidNumber: 10009
+homeDirectory: /home/adminuser1
+mail: adminuser1@example.org
+objectClass: top
+objectClass: posixAccount
+objectClass: shadowAccount
+objectClass: inetOrgPerson
+objectClass: organizationalPerson
+objectClass: person
+loginShell: /bin/bash
+# hashed value for 'password'
+userPassword: {SSHA}ICMhr6Jxt5bk2awD7HL7GxRTM3BZ1pFI
+
+# 2. adminuser2
+
+dn: uid=adminuser2,ou=People,ou=Global Groups,dc=example,dc=org
+cn: Admin User 2
+givenName: Admin
+sn: User1
+uid: adminuser2
+uidNumber: 5010
+gidNumber: 10010
+homeDirectory: /home/adminuser2
+mail: adminuser2@example.org
+objectClass: top
+objectClass: posixAccount
+objectClass: shadowAccount
+objectClass: inetOrgPerson
+objectClass: organizationalPerson
+objectClass: person
+loginShell: /bin/bash
+# hashed value for 'password'
+userPassword: {SSHA}ICMhr6Jxt5bk2awD7HL7GxRTM3BZ1pFI
diff --git a/qa/qa/fixtures/ldap/admin/3_add_groups.ldif b/qa/qa/fixtures/ldap/admin/3_add_groups.ldif
new file mode 100644
index 0000000000000000000000000000000000000000..db8b15bc9ea8e97fc68d42b5ac76acb644d4aa8f
--- /dev/null
+++ b/qa/qa/fixtures/ldap/admin/3_add_groups.ldif
@@ -0,0 +1,16 @@
+# 1. Human Resources
+
+dn: cn=Human Resources,ou=Global Groups,dc=example,dc=org
+objectClass: groupofnames
+cn: Human Resources
+description: Human Resources
+member: uid=hruser1,ou=People,ou=Global Groups,dc=example,dc=org
+
+# 2. Admin
+
+dn: cn=AdminGroup,ou=Global Groups,dc=example,dc=org
+objectClass: groupofnames
+cn: AdminGroup
+description: Human Resources
+member: uid=adminuser1,ou=People,ou=Global Groups,dc=example,dc=org
+member: uid=adminuser2,ou=People,ou=Global Groups,dc=example,dc=org
diff --git a/qa/qa/fixtures/ldap/non_admin/1_add_nodes.ldif b/qa/qa/fixtures/ldap/non_admin/1_add_nodes.ldif
new file mode 100644
index 0000000000000000000000000000000000000000..1476f53a0b952867b408de125b5af3b47c048fe9
--- /dev/null
+++ b/qa/qa/fixtures/ldap/non_admin/1_add_nodes.ldif
@@ -0,0 +1,7 @@
+dn: ou=Global Groups,dc=example,dc=org
+objectClass: organizationalUnit
+ou: Global Groups
+
+dn: ou=People,ou=Global Groups,dc=example,dc=org
+objectClass: organizationalUnit
+ou: People
diff --git a/qa/qa/fixtures/ldap/non_admin/2_add_users.ldif b/qa/qa/fixtures/ldap/non_admin/2_add_users.ldif
new file mode 100644
index 0000000000000000000000000000000000000000..cf8accc97e147a83eacc75766eb87f6deb48fd61
--- /dev/null
+++ b/qa/qa/fixtures/ldap/non_admin/2_add_users.ldif
@@ -0,0 +1,61 @@
+
+# 1. Human Resources
+
+dn: uid=hruser1,ou=People,ou=Global Groups,dc=example,dc=org
+cn: HR User 1
+givenName: HR
+sn: User1
+uid: hruser1
+uidNumber: 5000
+gidNumber: 10000
+homeDirectory: /home/hruser1
+mail: hruser1@example.org
+objectClass: top
+objectClass: posixAccount
+objectClass: shadowAccount
+objectClass: inetOrgPerson
+objectClass: organizationalPerson
+objectClass: person
+loginShell: /bin/bash
+# hashed value for 'password'
+userPassword: {SSHA}ICMhr6Jxt5bk2awD7HL7GxRTM3BZ1pFI
+
+# 2. Admin
+
+dn: uid=adminuser1,ou=People,ou=Global Groups,dc=example,dc=org
+cn: Admin User 1
+givenName: Admin
+sn: User1
+uid: adminuser1
+uidNumber: 5009
+gidNumber: 10009
+homeDirectory: /home/adminuser1
+mail: adminuser1@example.org
+objectClass: top
+objectClass: posixAccount
+objectClass: shadowAccount
+objectClass: inetOrgPerson
+objectClass: organizationalPerson
+objectClass: person
+loginShell: /bin/bash
+# hashed value for 'password'
+userPassword: {SSHA}ICMhr6Jxt5bk2awD7HL7GxRTM3BZ1pFI
+
+dn: uid=adminuser2,ou=People,ou=Global Groups,dc=example,dc=org
+cn: Admin User 2
+givenName: Admin
+sn: User1
+uid: adminuser2
+uidNumber: 5010
+gidNumber: 10010
+homeDirectory: /home/adminuser2
+mail: adminuser2@example.org
+objectClass: top
+objectClass: posixAccount
+objectClass: shadowAccount
+objectClass: inetOrgPerson
+objectClass: organizationalPerson
+objectClass: person
+loginShell: /bin/bash
+# hashed value for 'password'
+userPassword: {SSHA}ICMhr6Jxt5bk2awD7HL7GxRTM3BZ1pFI
diff --git a/qa/qa/fixtures/ldap/non_admin/3_add_groups.ldif b/qa/qa/fixtures/ldap/non_admin/3_add_groups.ldif
new file mode 100644
index 0000000000000000000000000000000000000000..65487a3b2c6cfeab2d206839e543697f010233f1
--- /dev/null
+++ b/qa/qa/fixtures/ldap/non_admin/3_add_groups.ldif
@@ -0,0 +1,16 @@
+# 1. Human Resources
+
+dn: cn=Human Resources,ou=Global Groups,dc=example,dc=org
+objectClass: groupofnames
+cn: Human Resources
+description: Human Resources
+member: uid=hruser1,ou=People,ou=Global Groups,dc=example,dc=org
+member: uid=adminuser1,ou=People,ou=Global Groups,dc=example,dc=org
+
+# 2. Admin
+
+dn: cn=AdminGroup,ou=Global Groups,dc=example,dc=org
+objectClass: groupofnames
+cn: AdminGroup
+description: Human Resources
+member: uid=adminuser2,ou=People,ou=Global Groups,dc=example,dc=org
diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb
index c373ec6d4fdc98bcd3c0d3a6e7a0f7f092720584..6e266e26d789cd6aede94df513530ed27c79c175 100644
--- a/qa/qa/page/main/login.rb
+++ b/qa/qa/page/main/login.rb
@@ -87,7 +87,7 @@ def sign_in_using_ldap_credentials(user:)
             click_element :sign_in_button
           end
 
-          Page::Main::Menu.perform(&:has_personal_area?)
+          Page::Main::Menu.perform(&:signed_in?)
         end
 
         def self.path
diff --git a/qa/qa/page/main/menu.rb b/qa/qa/page/main/menu.rb
index 3391ef454ee3c5cd0cb80f0c2af03fcdfc49df38..bff1b4cc836f96ca869b0b984c84dfbe685612ff 100644
--- a/qa/qa/page/main/menu.rb
+++ b/qa/qa/page/main/menu.rb
@@ -96,6 +96,10 @@ def has_admin_area_link?(wait: Capybara.default_max_wait_time)
           has_element?(:admin_area_link, wait: wait)
         end
 
+        def has_no_admin_area_link?(wait: Capybara.default_max_wait_time)
+          has_no_element?(:admin_area_link, wait: wait)
+        end
+
         def click_stop_impersonation_link
           click_element(:stop_impersonation_link)
         end
diff --git a/qa/qa/scenario/test/integration/ldap_no_server.rb b/qa/qa/scenario/test/integration/ldap_no_server.rb
new file mode 100644
index 0000000000000000000000000000000000000000..be71fc0ef6d5108b9c0eabf3345f3113306f0975
--- /dev/null
+++ b/qa/qa/scenario/test/integration/ldap_no_server.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module QA
+  module Scenario
+    module Test
+      module Integration
+        class LDAPNoServer < Test::Instance::All
+          tags :ldap_no_server
+        end
+      end
+    end
+  end
+end
diff --git a/qa/qa/service/ldap.rb b/qa/qa/service/ldap.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7a02cebeb8f982bd17fc770fd22ff4407061aea9
--- /dev/null
+++ b/qa/qa/service/ldap.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+module QA
+  module Service
+    class LDAP
+      include Service::Shellout
+
+      def initialize(volume)
+        @image = 'osixia/openldap:latest'
+        @name = 'ldap-server'
+        @network = Runtime::Scenario.attributes[:network] || 'test'
+        @volume = volume
+      end
+
+      def network
+        shell "docker network inspect #{@network}"
+      rescue CommandError
+        'bridge'
+      else
+        @network
+      end
+
+      def pull
+        shell "docker pull #{@image}"
+      end
+
+      def host_name
+        "#{@name}.#{network}"
+      end
+
+      def register!
+        shell <<~CMD.tr("\n", ' ')
+          docker run -d --rm
+          --network #{network}
+          --hostname #{host_name}
+          --name #{@name}
+          -p 389:389
+          --volume #{volume_or_fixture(@volume)}:/container/service/slapd/assets/config/bootstrap/ldif/custom
+          #{@image} --copy-service
+        CMD
+      end
+
+      def remove!
+        shell "docker rm -f #{@name}" if running?
+      end
+
+      def running?
+        `docker ps -f name=#{@name}`.include?(@name)
+      end
+
+      def volume_or_fixture(volume_name)
+        if volume_exists?(volume_name)
+          volume_name
+        else
+          File.expand_path("../fixtures/ldap/#{volume_name}", __dir__)
+        end
+      end
+
+      def volume_exists?(volume_name)
+        `docker volume ls -q -f name=#{volume_name}`.include?(volume_name)
+      end
+    end
+  end
+end
diff --git a/qa/qa/specs/features/ee/browser_ui/1_manage/ldap/admin_ldap_sync_spec.rb b/qa/qa/specs/features/ee/browser_ui/1_manage/ldap/admin_ldap_sync_spec.rb
index abe27ab30ae2a1af59c924196baca6896677beaf..3092123ba2914b2eb7d9aa6414244bfdcdf0a936 100644
--- a/qa/qa/specs/features/ee/browser_ui/1_manage/ldap/admin_ldap_sync_spec.rb
+++ b/qa/qa/specs/features/ee/browser_ui/1_manage/ldap/admin_ldap_sync_spec.rb
@@ -1,27 +1,62 @@
 # frozen_string_literal: true
-
 module QA
-  context 'Manage', :orchestrated, :ldap_no_tls, :ldap_tls do
+  context 'Manage', :orchestrated, :ldap_no_server do
     describe 'LDAP admin sync' do
-      it 'Syncs admin users' do
-        Runtime::Browser.visit(:gitlab, Page::Main::Login)
+      before do
+        run_ldap_service_with_user_as('admin')
 
-        Page::Main::Login.perform do |login_page|
-          user = Struct.new(:ldap_username, :ldap_password).new('adminuser1', 'password')
+        Runtime::Browser.visit(:gitlab, Page::Main::Login)
 
-          login_page.sign_in_using_ldap_credentials(user: user)
-        end
+        login_with_ldap_admin_user
+      end
 
+      it 'sets and removes user\'s admin status' do
         Page::Main::Menu.perform do |menu|
-          expect(menu).to have_personal_area
-
-          # The ldap_sync_worker_cron job is set to run every minute
           admin_synchronised = menu.wait(max: 80, interval: 1, reload: true) do
             menu.has_admin_area_link?
           end
 
           expect(admin_synchronised).to be_truthy
         end
+
+        remove_ldap_service_with_user_as('admin')
+
+        run_ldap_service_with_user_as('non_admin')
+
+        login_with_ldap_admin_user
+
+        Page::Main::Menu.perform do |menu|
+          admin_removed = menu.wait(max: 80, interval: 1, reload: true) do
+            menu.has_no_admin_area_link?
+          end
+
+          expect(admin_removed).to be_truthy
+        end
+      end
+
+      after do
+        remove_ldap_service_with_user_as('non_admin')
+      end
+
+      def run_ldap_service_with_user_as(user_status)
+        Service::LDAP.new(user_status).tap do |runner|
+          runner.pull
+          runner.register!
+        end
+      end
+
+      def remove_ldap_service_with_user_as(user_status)
+        Service::LDAP.new(user_status).remove!
+      end
+
+      def login_with_ldap_admin_user
+        Page::Main::Login.perform do |login_page|
+          user = Struct.new(:ldap_username, :ldap_password).new('adminuser1', 'password')
+
+          QA::Support::Retrier.retry_until(exit_on_failure: true, sleep_interval: 3, max_attempts: 5) do
+            login_page.sign_in_using_ldap_credentials(user)
+          end
+        end
       end
     end
   end
diff --git a/qa/spec/scenario/test/integration/ldap_spec.rb b/qa/spec/scenario/test/integration/ldap_spec.rb
index b6d798bf504d7cb3d5b83bcfc691ad41ff8d5f26..86747cd8eb71c02f764d75ed2f24b3d6c149ac15 100644
--- a/qa/spec/scenario/test/integration/ldap_spec.rb
+++ b/qa/spec/scenario/test/integration/ldap_spec.rb
@@ -8,6 +8,14 @@
   end
 end
 
+describe QA::Scenario::Test::Integration::LDAPNoServer do
+  context '#perform' do
+    it_behaves_like 'a QA scenario class' do
+      let(:tags) { [:ldap_no_server] }
+    end
+  end
+end
+
 describe QA::Scenario::Test::Integration::LDAPTLS do
   context '#perform' do
     it_behaves_like 'a QA scenario class' do