diff --git a/ee/app/assets/javascripts/roles_and_permissions/components/app.vue b/ee/app/assets/javascripts/roles_and_permissions/components/app.vue
index bdb9ff41ef89e98ca0b6472b7cef517c5e764924..c1ec477445fb6244bb897acccc8f15a222054c64 100644
--- a/ee/app/assets/javascripts/roles_and_permissions/components/app.vue
+++ b/ee/app/assets/javascripts/roles_and_permissions/components/app.vue
@@ -43,7 +43,8 @@ export default {
     },
     newRolePath: {
       type: String,
-      required: true,
+      required: false,
+      default: '',
     },
   },
   data() {
@@ -127,7 +128,9 @@ export default {
         </gl-sprintf>
       </span>
 
-      <gl-button :href="newRolePath" variant="confirm">{{ $options.i18n.newRoleText }}</gl-button>
+      <gl-button v-if="newRolePath" :href="newRolePath" variant="confirm">
+        {{ $options.i18n.newRoleText }}
+      </gl-button>
     </div>
 
     <roles-table :roles="roles" :busy="isLoading" @delete-role="roleToDelete = $event" />
diff --git a/ee/app/controllers/admin/application_settings/roles_and_permissions_controller.rb b/ee/app/controllers/admin/application_settings/roles_and_permissions_controller.rb
index 93c482bcec6a4fec13227648fe6db7bc5a455545..034ac11c95a9288b4178cdc77f111091f02b5c4e 100644
--- a/ee/app/controllers/admin/application_settings/roles_and_permissions_controller.rb
+++ b/ee/app/controllers/admin/application_settings/roles_and_permissions_controller.rb
@@ -8,12 +8,17 @@ class RolesAndPermissionsController < Admin::ApplicationController
 
       feature_category :user_management
 
-      before_action :ensure_custom_roles_available!
+      before_action :authorize_admin_member_roles!, except: [:index, :show]
+      before_action :authorize_view_member_roles!, only: [:index, :show]
 
       private
 
-      def ensure_custom_roles_available!
-        render_404 if gitlab_com_subscription? || !License.feature_available?(:custom_roles)
+      def authorize_admin_member_roles!
+        render_404 if gitlab_com_subscription? || !can?(current_user, :admin_member_role)
+      end
+
+      def authorize_view_member_roles!
+        render_404 if gitlab_com_subscription? || !can?(current_user, :view_member_roles)
       end
     end
   end
diff --git a/ee/app/controllers/groups/settings/roles_and_permissions_controller.rb b/ee/app/controllers/groups/settings/roles_and_permissions_controller.rb
index 609d84729922d7c09cc29fcbd294ea43c199377f..4db8416ca3360cc15d2d2a315e79f811bb9dcb93 100644
--- a/ee/app/controllers/groups/settings/roles_and_permissions_controller.rb
+++ b/ee/app/controllers/groups/settings/roles_and_permissions_controller.rb
@@ -8,9 +8,10 @@ class RolesAndPermissionsController < Groups::ApplicationController
 
       feature_category :user_management
 
-      before_action :authorize_admin_member_roles!
+      before_action :authorize_admin_member_roles!, except: [:index, :show]
+      before_action :authorize_view_member_roles!, only: [:index, :show]
       before_action :ensure_root_group!
-      before_action :ensure_custom_roles_available!
+      before_action :ensure_gitlab_com_subscription!
 
       private
 
@@ -18,12 +19,16 @@ def authorize_admin_member_roles!
         render_404 unless can?(current_user, :admin_member_role, group)
       end
 
+      def authorize_view_member_roles!
+        render_404 unless can?(current_user, :view_member_roles, group)
+      end
+
       def ensure_root_group!
         render_404 unless group.root?
       end
 
-      def ensure_custom_roles_available!
-        render_404 unless group.licensed_feature_available?(:custom_roles) && gitlab_com_subscription?
+      def ensure_gitlab_com_subscription!
+        render_404 unless gitlab_com_subscription?
       end
     end
   end
diff --git a/ee/app/helpers/member_roles_helper.rb b/ee/app/helpers/member_roles_helper.rb
index 1e3caf2e67fd29ddc338c1a4b8e61964b4bb25a7..77208927656bec302cf4bf41f749e700d9cbd021 100644
--- a/ee/app/helpers/member_roles_helper.rb
+++ b/ee/app/helpers/member_roles_helper.rb
@@ -42,9 +42,9 @@ def member_role_details_path(role)
   def new_role_path(source)
     root_group = source&.root_ancestor
 
-    if root_group&.custom_roles_enabled? && can?(current_user, :admin_group_member, root_group)
+    if gitlab_com_subscription? && can?(current_user, :admin_member_role, root_group)
       new_group_settings_roles_and_permission_path(root_group)
-    elsif current_user&.can_admin_all_resources? && License.feature_available?(:custom_roles)
+    elsif !gitlab_com_subscription? && can?(current_user, :admin_member_role)
       new_admin_application_settings_roles_and_permission_path
     end
   end
diff --git a/ee/app/models/gitlab_subscriptions/features.rb b/ee/app/models/gitlab_subscriptions/features.rb
index 0834cf946f78a7dc54e838680e1de41c238e319b..7ed1386a45d866148c745474bf5c0cc4a664c410 100644
--- a/ee/app/models/gitlab_subscriptions/features.rb
+++ b/ee/app/models/gitlab_subscriptions/features.rb
@@ -175,6 +175,7 @@ class Features
       group_saved_replies
       requested_changes_block_merge_request
       project_saved_replies
+      default_roles_assignees
     ].freeze
 
     ULTIMATE_FEATURES = %i[
diff --git a/ee/app/policies/ee/global_policy.rb b/ee/app/policies/ee/global_policy.rb
index e733562f176125ae3fcd19b2d605a5e52bfed3a4..3db73e179443a05369e958baa45de03afe175465 100644
--- a/ee/app/policies/ee/global_policy.rb
+++ b/ee/app/policies/ee/global_policy.rb
@@ -124,6 +124,10 @@ module GlobalPolicy
         ::License.feature_available?(:custom_roles)
       end
 
+      condition(:default_roles_assignees_allowed) do
+        ::License.feature_available?(:default_roles_assignees)
+      end
+
       condition(:user_allowed_to_manage_ai_settings) do
         next false if ::Gitlab::Saas.feature_available?(:gitlab_com_subscriptions)
 
@@ -170,6 +174,11 @@ module GlobalPolicy
 
       rule { admin & custom_roles_allowed }.policy do
         enable :admin_member_role
+        enable :view_member_roles
+      end
+
+      rule { admin & default_roles_assignees_allowed }.policy do
+        enable :view_member_roles
       end
 
       rule { ~anonymous & custom_roles_allowed }.policy do
diff --git a/ee/app/policies/ee/group_policy.rb b/ee/app/policies/ee/group_policy.rb
index 347584c98eb43f629f95da273476e1f342a8c91f..edbad712bf554f1e4ef7069aa29a9f3864d3e5b1 100644
--- a/ee/app/policies/ee/group_policy.rb
+++ b/ee/app/policies/ee/group_policy.rb
@@ -261,6 +261,10 @@ module GroupPolicy
         ::Gitlab::ClickHouse.configured?
       end
 
+      condition(:default_roles_assignees_allowed, scope: :subject) do
+        @subject.root_ancestor.licensed_feature_available?(:default_roles_assignees)
+      end
+
       rule { user_banned_from_namespace }.prevent_all
 
       rule { public_group | logged_in_viewable }.policy do
@@ -562,8 +566,13 @@ module GroupPolicy
         enable :read_member_role
       end
 
+      rule { default_roles_assignees_allowed & owner }.policy do
+        enable :view_member_roles
+      end
+
       rule { custom_roles_allowed & owner }.policy do
         enable :admin_member_role
+        enable :view_member_roles
       end
 
       rule { custom_role_enables_admin_cicd_variables }.policy do
diff --git a/ee/lib/ee/sidebars/admin/menus/admin_settings_menu.rb b/ee/lib/ee/sidebars/admin/menus/admin_settings_menu.rb
index fd926bf996ca11fa31dfff49e5df885b65d34392..75a8a60319fff890f99ff5388dbd8afa45abf91d 100644
--- a/ee/lib/ee/sidebars/admin/menus/admin_settings_menu.rb
+++ b/ee/lib/ee/sidebars/admin/menus/admin_settings_menu.rb
@@ -24,7 +24,7 @@ def configure_menu_items
           private
 
           def roles_and_permissions_menu_item
-            return ::Sidebars::NilMenuItem.new(item_id: :roles_and_permissions) unless custom_roles_enabled?
+            return ::Sidebars::NilMenuItem.new(item_id: :roles_and_permissions) unless roles_and_permissions_available?
 
             ::Sidebars::MenuItem.new(
               title: _('Roles and permissions'),
@@ -34,8 +34,8 @@ def roles_and_permissions_menu_item
             )
           end
 
-          def custom_roles_enabled?
-            ::License.feature_available?(:custom_roles) && !gitlab_com_subscription?
+          def roles_and_permissions_available?
+            can?(current_user, :view_member_roles) && !gitlab_com_subscription?
           end
 
           def advanced_search_menu_item
diff --git a/ee/lib/ee/sidebars/groups/menus/settings_menu.rb b/ee/lib/ee/sidebars/groups/menus/settings_menu.rb
index 2fe326ca6507aaf2b854b35a93fb53ce7ed14b62..7bef06fa1e23c14fb9057d45149acab08033427a 100644
--- a/ee/lib/ee/sidebars/groups/menus/settings_menu.rb
+++ b/ee/lib/ee/sidebars/groups/menus/settings_menu.rb
@@ -56,7 +56,9 @@ def roles_and_permissions_menu_item
           end
 
           def custom_roles_enabled?
-            context.group.root? && context.group.licensed_feature_available?(:custom_roles) && gitlab_com_subscription?
+            context.group.root? &&
+              can?(context.current_user, :view_member_roles, context.group) &&
+              gitlab_com_subscription?
           end
 
           def ldap_sync_menu_item
diff --git a/ee/spec/frontend/roles_and_permissions/components/app_spec.js b/ee/spec/frontend/roles_and_permissions/components/app_spec.js
index eef6dbb99c8ec9a7653b9f1e9a61d8fd60204643..da5cdffaf36ab02086b57428336de4e3166c0a5a 100644
--- a/ee/spec/frontend/roles_and_permissions/components/app_spec.js
+++ b/ee/spec/frontend/roles_and_permissions/components/app_spec.js
@@ -32,13 +32,14 @@ describe('Roles app', () => {
     groupRolesQueryHandler = groupRolesSuccessQueryHandler,
     instanceRolesQueryHandler = instanceRolesSuccessQueryHandler,
     groupFullPath = 'test-group',
+    newRolePath = 'new/role/path',
   } = {}) => {
     wrapper = shallowMountExtended(RolesApp, {
       apolloProvider: createMockApollo([
         [groupMemberRolesQuery, groupRolesQueryHandler],
         [instanceMemberRolesQuery, instanceRolesQueryHandler],
       ]),
-      propsData: { groupFullPath, newRolePath: 'new/role/path' },
+      propsData: { groupFullPath, newRolePath },
       stubs: { GlSprintf },
       mocks: { $toast: { show: mockToastShow } },
     });
@@ -182,4 +183,16 @@ describe('Roles app', () => {
       });
     });
   });
+
+  describe('when newRolePath is not set', () => {
+    beforeEach(() => {
+      createComponent({ newRolePath: null });
+    });
+
+    it('does not show the New role button', () => {
+      const button = wrapper.findComponent(GlButton);
+
+      expect(button.exists()).toBe(false);
+    });
+  });
 });
diff --git a/ee/spec/helpers/member_roles_helper_spec.rb b/ee/spec/helpers/member_roles_helper_spec.rb
index f46ee3b13e485f897bcdc9a3da7a012c5fc492cf..fe001a3aecab5b4ad1aaa4ecd36c1e5c2e0489e7 100644
--- a/ee/spec/helpers/member_roles_helper_spec.rb
+++ b/ee/spec/helpers/member_roles_helper_spec.rb
@@ -18,31 +18,18 @@
     context 'when on self-managed' do
       subject(:data) { helper.member_roles_data }
 
-      context 'for admin user', :enable_admin_mode do
-        let_it_be(:user) { build_stubbed(:admin) }
-
-        context 'when custom roles are available' do
-          it 'matches the expected data' do
-            expect(data[:new_role_path]).to eq new_admin_application_settings_roles_and_permission_path
-            expect(data[:group_full_path]).to be_nil
-          end
-        end
-
-        context 'when custom roles are not available' do
-          before do
-            stub_licensed_features(custom_roles: false)
-          end
+      it 'matches the expected data' do
+        expect(data[:new_role_path]).to be_nil
+        expect(data[:group_full_path]).to be_nil
+      end
 
-          it 'matches the expected data' do
-            expect(data[:new_role_path]).to be_nil
-            expect(data[:group_full_path]).to be_nil
-          end
+      context 'with admin member role rights' do
+        before do
+          allow(helper).to receive(:can?).with(user, :admin_member_role).and_return(true)
         end
-      end
 
-      context 'for non-admin user' do
         it 'matches the expected data' do
-          expect(data[:new_role_path]).to be_nil
+          expect(data[:new_role_path]).to eq new_admin_application_settings_roles_and_permission_path
           expect(data[:group_full_path]).to be_nil
         end
       end
@@ -52,37 +39,21 @@
       context 'when on group page' do
         subject(:data) { helper.member_roles_data(source) }
 
-        shared_examples 'custom roles are not available' do
-          it 'matches the expected data' do
-            expect(data[:new_role_path]).to be_nil
-            expect(data[:group_full_path]).to eq source.full_path
-          end
+        it 'matches the expected data' do
+          expect(data[:new_role_path]).to be_nil
+          expect(data[:group_full_path]).to eq source.full_path
         end
 
-        context 'as group owner' do
+        context 'with admin member role rights' do
           before do
-            allow(helper).to receive(:can?).with(user, :admin_group_member, root_group).and_return(true)
+            allow(helper).to receive(:can?).with(user, :admin_member_role, root_group).and_return(true)
           end
 
-          context 'when custom roles are available' do
-            it 'matches the expected data' do
-              expect(data[:new_role_path]).to eq new_group_settings_roles_and_permission_path(source)
-              expect(data[:group_full_path]).to eq source.full_path
-            end
-          end
-
-          context 'when custom roles are not available' do
-            before do
-              stub_licensed_features(custom_roles: false)
-            end
-
-            it_behaves_like 'custom roles are not available'
+          it 'matches the expected data' do
+            expect(data[:new_role_path]).to eq new_group_settings_roles_and_permission_path(source)
+            expect(data[:group_full_path]).to eq source.full_path
           end
         end
-
-        context 'as group non-owner' do
-          it_behaves_like 'custom roles are not available'
-        end
       end
     end
   end
diff --git a/ee/spec/lib/ee/sidebars/admin/menus/admin_settings_menu_spec.rb b/ee/spec/lib/ee/sidebars/admin/menus/admin_settings_menu_spec.rb
index 2465fc06cdf689e55e02cb4ac29f75a12458d88d..cae58ae416478f115bc03ef0636df81ffb1202dd 100644
--- a/ee/spec/lib/ee/sidebars/admin/menus/admin_settings_menu_spec.rb
+++ b/ee/spec/lib/ee/sidebars/admin/menus/admin_settings_menu_spec.rb
@@ -33,29 +33,19 @@
     describe 'Roles and permissions menu', feature_category: :user_management do
       let(:item_id) { :roles_and_permissions }
 
-      context 'when custom_roles feature is licensed' do
+      it { is_expected.not_to be_present }
+
+      context 'when user can view member roles' do
         before do
-          stub_licensed_features(custom_roles: true)
+          allow(Ability).to receive(:allowed?).with(user, :view_member_roles).and_return(true)
         end
 
         it { is_expected.to be_present }
 
-        context 'when in SaaS mode' do
-          before do
-            stub_saas_features(gitlab_com_subscriptions: true)
-          end
-
+        context 'when in SaaS mode', :saas do
           it { is_expected.not_to be_present }
         end
       end
-
-      context 'when custom_roles feature is not licensed' do
-        before do
-          stub_licensed_features(custom_roles: false)
-        end
-
-        it { is_expected.not_to be_present }
-      end
     end
   end
 end
diff --git a/ee/spec/lib/ee/sidebars/groups/menus/settings_menu_spec.rb b/ee/spec/lib/ee/sidebars/groups/menus/settings_menu_spec.rb
index 522c6cbb9fbf7aa966118d8f4240b0bca8b3245b..cee23a007832222d79adeaeb6accccff1cabea8d 100644
--- a/ee/spec/lib/ee/sidebars/groups/menus/settings_menu_spec.rb
+++ b/ee/spec/lib/ee/sidebars/groups/menus/settings_menu_spec.rb
@@ -28,45 +28,51 @@
       subject { menu.renderable_items.find { |e| e.item_id == item_id } }
 
       describe 'Roles and permissions menu', feature_category: :user_management do
+        using RSpec::Parameterized::TableSyntax
+
         let(:item_id) { :roles_and_permissions }
 
-        context 'when custom_roles feature is licensed' do
-          before do
-            stub_licensed_features(custom_roles: true)
-            stub_saas_features(gitlab_com_subscriptions: true)
-          end
+        where(license: [:custom_roles, :default_roles_assignees])
 
-          it { is_expected.to be_present }
+        with_them do
+          context 'when feature is licensed' do
+            before do
+              stub_licensed_features(license => true)
+              stub_saas_features(gitlab_com_subscriptions: true)
+            end
+
+            it { is_expected.to be_present }
 
-          context 'when it is not a root group' do
-            let_it_be_with_refind(:subgroup) do
-              create(:group, :private, parent: group).tap do |g|
-                g.add_owner(owner)
+            context 'when it is not a root group' do
+              let_it_be_with_refind(:subgroup) do
+                create(:group, :private, parent: group).tap do |g|
+                  g.add_owner(owner)
+                end
               end
+
+              let(:container) { subgroup }
+
+              it { is_expected.not_to be_present }
             end
 
-            let(:container) { subgroup }
+            context 'when on self-managed' do
+              before do
+                stub_saas_features(gitlab_com_subscriptions: false)
+              end
 
-            it { is_expected.not_to be_present }
+              it { is_expected.not_to be_present }
+            end
           end
 
-          context 'when on self-managed' do
+          context 'when feature is not licensed' do
             before do
-              stub_saas_features(gitlab_com_subscriptions: false)
+              stub_licensed_features(license => false)
+              stub_saas_features(gitlab_com_subscriptions: true)
             end
 
             it { is_expected.not_to be_present }
           end
         end
-
-        context 'when custom_roles feature is not licensed' do
-          before do
-            stub_licensed_features(custom_roles: false)
-            stub_saas_features(gitlab_com_subscriptions: true)
-          end
-
-          it { is_expected.not_to be_present }
-        end
       end
 
       describe 'LDAP sync menu' do
diff --git a/ee/spec/lib/sidebars/admin/panel_spec.rb b/ee/spec/lib/sidebars/admin/panel_spec.rb
index 0ee2a5090fe7509246bec9a171313502f7e2b341..c46d6ecde6d15d5ab5d04e973fa0d609589cf12c 100644
--- a/ee/spec/lib/sidebars/admin/panel_spec.rb
+++ b/ee/spec/lib/sidebars/admin/panel_spec.rb
@@ -2,7 +2,7 @@
 
 require 'spec_helper'
 
-RSpec.describe Sidebars::Admin::Panel, feature_category: :navigation do
+RSpec.describe Sidebars::Admin::Panel, :enable_admin_mode, feature_category: :navigation do
   let_it_be(:user) { build(:admin) }
 
   let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
diff --git a/ee/spec/policies/global_policy_spec.rb b/ee/spec/policies/global_policy_spec.rb
index 7a79468a09d02b2294e482bad464a3bfa8639b14..206895a248c14bf1f5eb6f5fbda31350298fa4ca 100644
--- a/ee/spec/policies/global_policy_spec.rb
+++ b/ee/spec/policies/global_policy_spec.rb
@@ -314,6 +314,42 @@
       end
     end
 
+    describe 'view_member_roles' do
+      let(:permissions) { [:view_member_roles] }
+
+      where(license: [:custom_roles, :default_roles_assignees])
+
+      with_them do
+        context 'when feature is enabled' do
+          before do
+            stub_licensed_features(license => true)
+          end
+
+          it { is_expected.to be_disallowed(*permissions) }
+
+          context 'when admin mode enabled', :enable_admin_mode do
+            let(:current_user) { admin }
+
+            it { is_expected.to be_allowed(*permissions) }
+          end
+
+          context 'when admin mode disabled' do
+            let(:current_user) { admin }
+
+            it { is_expected.to be_disallowed(*permissions) }
+          end
+        end
+
+        context 'when feature is disabled' do
+          let(:current_user) { admin }
+
+          context 'when admin mode enabled', :enable_admin_mode do
+            it { is_expected.to be_disallowed(*permissions) }
+          end
+        end
+      end
+    end
+
     describe 'read_member_role' do
       let(:permissions) { [:read_member_role] }
 
diff --git a/ee/spec/policies/group_policy_spec.rb b/ee/spec/policies/group_policy_spec.rb
index f6f51ba6d7e8a79a92d0efed76f33d9f10e81db0..e18f2e44bfd13854b90c93bae10268ec8bf29587 100644
--- a/ee/spec/policies/group_policy_spec.rb
+++ b/ee/spec/policies/group_policy_spec.rb
@@ -2419,8 +2419,6 @@ def set_access_level(access_level)
       describe ':admin_member_role' do
         using RSpec::Parameterized::TableSyntax
 
-        let(:permissions) { [:admin_member_role] }
-
         where(:role, :allowed) do
           :guest      | false
           :reporter   | false
@@ -2438,30 +2436,56 @@ def set_access_level(access_level)
             enable_admin_mode!(current_user) if role == :admin
           end
 
-          context 'when custom_roles feature is enabled' do
-            before do
-              stub_licensed_features(custom_roles: true)
-            end
+          context 'custom roles license' do
+            let(:license) { :custom_roles }
+            let(:permissions) { [:admin_member_role, :view_member_roles] }
 
-            it { is_expected.to(allowed ? be_allowed(*permissions) : be_disallowed(*permissions)) }
-
-            context 'when memberships are locked to LDAP' do
+            context 'when licensed feature is enabled' do
               before do
-                allow(group).to receive(:ldap_synced?).and_return(true)
-                stub_application_setting(allow_group_owners_to_manage_ldap: true)
-                stub_application_setting(lock_memberships_to_ldap: true)
+                stub_licensed_features(license => true)
               end
 
               it { is_expected.to(allowed ? be_allowed(*permissions) : be_disallowed(*permissions)) }
+
+              context 'when memberships are locked to LDAP' do
+                before do
+                  allow(group).to receive(:ldap_synced?).and_return(true)
+                  stub_application_setting(allow_group_owners_to_manage_ldap: true)
+                  stub_application_setting(lock_memberships_to_ldap: true)
+                end
+
+                it { is_expected.to(allowed ? be_allowed(*permissions) : be_disallowed(*permissions)) }
+              end
+            end
+
+            context 'when licensed feature is disabled' do
+              before do
+                stub_licensed_features(license => false)
+              end
+
+              it { is_expected.to be_disallowed(*permissions) }
             end
           end
 
-          context 'when custom_roles feature is disabled' do
-            before do
-              stub_licensed_features(custom_roles: false)
+          context 'default roles assignees license' do
+            let(:license) { :default_roles_assignees }
+            let(:permissions) { [:view_member_roles] }
+
+            context 'when licensed feature is enabled' do
+              before do
+                stub_licensed_features(license => true)
+              end
+
+              it { is_expected.to(allowed ? be_allowed(*permissions) : be_disallowed(*permissions)) }
             end
 
-            it { is_expected.to be_disallowed(*permissions) }
+            context 'when licensed feature is disabled' do
+              before do
+                stub_licensed_features(license => false)
+              end
+
+              it { is_expected.to be_disallowed(*permissions) }
+            end
           end
         end
       end
diff --git a/ee/spec/requests/admin/application_settings/roles_and_permissions_controller_spec.rb b/ee/spec/requests/admin/application_settings/roles_and_permissions_controller_spec.rb
index dc528dbe296562d0632ed787a304efb6e8a29eda..7a958bab563b335e41af411f1dc3c54194dd024c 100644
--- a/ee/spec/requests/admin/application_settings/roles_and_permissions_controller_spec.rb
+++ b/ee/spec/requests/admin/application_settings/roles_and_permissions_controller_spec.rb
@@ -3,8 +3,7 @@
 require 'spec_helper'
 
 RSpec.describe Admin::ApplicationSettings::RolesAndPermissionsController, :enable_admin_mode, feature_category: :user_management do
-  let_it_be(:member_role) { create(:member_role, :instance, name: 'Custom role') }
-  let_it_be(:role_id) { member_role.id }
+  let_it_be(:role_id) { Gitlab::Access.options.each_key.first }
   let_it_be(:admin) { create(:admin) }
 
   shared_examples 'not found' do
@@ -15,7 +14,7 @@
     end
   end
 
-  shared_examples 'access control' do
+  shared_examples 'access control' do |licenses|
     context 'with non-admin user' do
       let_it_be(:user) { create(:user) }
 
@@ -39,27 +38,33 @@
         sign_in(admin)
       end
 
-      context 'when `custom_roles` license is disabled' do
+      context 'when no suitable license is available' do
         it_behaves_like 'not found'
       end
 
-      context 'when `custom_roles` license is enabled' do
-        before do
-          stub_licensed_features(custom_roles: true)
-        end
-
-        it 'returns a 200 status code' do
-          get_method
+      context 'when a suitable license is available' do
+        using RSpec::Parameterized::TableSyntax
 
-          expect(response).to have_gitlab_http_status(:ok)
-        end
+        where(license: licenses)
 
-        context 'when on SaaS' do
+        with_them do
           before do
-            stub_saas_features(gitlab_com_subscriptions: true)
+            stub_licensed_features(license => true)
+          end
+
+          it 'returns a 200 status code' do
+            get_method
+
+            expect(response).to have_gitlab_http_status(:ok)
           end
 
-          it_behaves_like 'not found'
+          context 'when on SaaS' do
+            before do
+              stub_saas_features(gitlab_com_subscriptions: true)
+            end
+
+            it_behaves_like 'not found'
+          end
         end
       end
     end
@@ -101,20 +106,20 @@
   describe 'GET #index' do
     subject(:get_method) { get admin_application_settings_roles_and_permissions_path }
 
-    it_behaves_like 'access control'
+    it_behaves_like 'access control', [:custom_roles, :default_roles_assignees]
   end
 
   describe 'GET #show' do
     subject(:get_method) { get admin_application_settings_roles_and_permission_path(role_id) }
 
-    it_behaves_like 'access control'
+    it_behaves_like 'access control', [:custom_roles, :default_roles_assignees]
     it_behaves_like 'role existence check'
   end
 
   describe 'GET #edit' do
     subject(:get_method) { get edit_admin_application_settings_roles_and_permission_path(role_id) }
 
-    it_behaves_like 'access control'
+    it_behaves_like 'access control', [:custom_roles]
     it_behaves_like 'role existence check'
   end
 end
diff --git a/ee/spec/requests/groups/settings/roles_and_permissions_controller_spec.rb b/ee/spec/requests/groups/settings/roles_and_permissions_controller_spec.rb
index f410ea2baef638d717f5e9642046c917c3b63006..fe8e506a5b50c5a0a73272b6c51eda1de7dff183 100644
--- a/ee/spec/requests/groups/settings/roles_and_permissions_controller_spec.rb
+++ b/ee/spec/requests/groups/settings/roles_and_permissions_controller_spec.rb
@@ -4,12 +4,12 @@
 
 RSpec.describe Groups::Settings::RolesAndPermissionsController, feature_category: :user_management do
   include AdminModeHelper
+  using RSpec::Parameterized::TableSyntax
 
   let_it_be(:user) { create(:user) }
   let_it_be(:admin) { create(:admin) }
   let_it_be_with_reload(:group) { create(:group) }
-  let_it_be(:member_role) { create(:member_role, namespace: group, name: 'Custom role') }
-  let_it_be(:role_id) { member_role.id }
+  let_it_be(:role_id) { Gitlab::Access.options.each_key.first }
 
   before do
     stub_saas_features(gitlab_com_subscriptions: true)
@@ -23,7 +23,7 @@
     end
   end
 
-  shared_examples 'access control' do
+  shared_examples 'access control' do |licenses|
     shared_examples 'page is found under proper conditions' do
       it 'returns a 200 status code' do
         get_method
@@ -37,72 +37,76 @@
         it_behaves_like 'page is not found'
       end
 
-      context 'when `custom_roles` license is disabled' do
+      context 'when license is disabled' do
         before do
-          stub_licensed_features(custom_roles: false)
+          stub_licensed_features(license => false)
         end
 
         it_behaves_like 'page is not found'
       end
     end
 
-    before do
-      stub_licensed_features(custom_roles: true)
-    end
+    where(license: licenses)
 
-    context 'when not logged in' do
-      it_behaves_like 'page is not found'
-    end
-
-    context 'with different access levels not allowed' do
-      where(access_level: [nil, :guest, :reporter, :developer, :maintainer])
-
-      with_them do
-        before do
-          group.add_member(user, access_level)
-          sign_in(user)
-        end
+    with_them do
+      before do
+        stub_licensed_features(license => true)
+      end
 
+      context 'when not logged in' do
         it_behaves_like 'page is not found'
       end
-    end
 
-    context 'with admins' do
-      before do
-        sign_in(admin)
-        enable_admin_mode!(admin)
-      end
+      context 'with different access levels not allowed' do
+        where(access_level: [nil, :guest, :reporter, :developer, :maintainer])
 
-      it_behaves_like 'page is found under proper conditions'
+        with_them do
+          before do
+            group.add_member(user, access_level)
+            sign_in(user)
+          end
+
+          it_behaves_like 'page is not found'
+        end
+      end
 
-      context 'on self-managed' do
+      context 'with admins' do
         before do
-          stub_saas_features(gitlab_com_subscriptions: false)
+          sign_in(admin)
+          enable_admin_mode!(admin)
         end
 
-        it_behaves_like 'page is not found'
+        it_behaves_like 'page is found under proper conditions'
+
+        context 'on self-managed' do
+          before do
+            stub_saas_features(gitlab_com_subscriptions: false)
+          end
+
+          it_behaves_like 'page is not found'
+        end
       end
-    end
 
-    context 'with group owners' do
-      before do
-        group.add_member(user, :owner)
-        sign_in(user)
+      context 'with group owners' do
+        before do
+          group.add_member(user, :owner)
+          sign_in(user)
+        end
+
+        it_behaves_like 'page is found under proper conditions'
       end
 
-      it_behaves_like 'page is found under proper conditions'
-    end
+      context 'with ldap synced group owner' do
+        let_it_be(:group_link) { create(:ldap_group_link, group: group, group_access: Gitlab::Access::OWNER) }
+        let_it_be(:group_member) { create(:group_member, :owner, :ldap, :active, user: user, source: group) }
 
-    context 'with ldap synced group owner' do
-      let_it_be(:group_link) { create(:ldap_group_link, group: group, group_access: Gitlab::Access::OWNER) }
-      let_it_be(:group_member) { create(:group_member, :owner, :ldap, :active, user: user, source: group) }
+        before do
+          stub_application_setting(lock_memberships_to_ldap: true)
+          sign_in(user)
+        end
 
-      before do
-        stub_application_setting(lock_memberships_to_ldap: true)
-        sign_in(user)
+        it_behaves_like 'page is found under proper conditions'
       end
-
-      it_behaves_like 'page is found under proper conditions'
     end
   end
 
@@ -143,20 +147,20 @@
   describe 'GET #index' do
     subject(:get_method) { get(group_settings_roles_and_permissions_path(group)) }
 
-    it_behaves_like 'access control'
+    it_behaves_like 'access control', [:custom_roles, :default_roles_assignees]
   end
 
   describe 'GET #show' do
     subject(:get_method) { get(group_settings_roles_and_permission_path(group, role_id)) }
 
-    it_behaves_like 'access control'
+    it_behaves_like 'access control', [:custom_roles, :default_roles_assignees]
     it_behaves_like 'role existence check'
   end
 
   describe 'GET #edit' do
     subject(:get_method) { get(edit_group_settings_roles_and_permission_path(group, role_id)) }
 
-    it_behaves_like 'access control'
+    it_behaves_like 'access control', [:custom_roles]
     it_behaves_like 'role existence check'
   end
 end