diff --git a/CHANGELOG.md b/CHANGELOG.md
index a4bd6b7915c8967c01bf6e233a922351c558a8d4..ed8770192fdb468af6cd3ac8ca2a905ee2274309 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,21 @@
 documentation](doc/development/changelog.md) for instructions on adding your own
 entry.
 
+## 16.8.2 (2024-02-07)
+
+### Fixed (3 changes)
+
+- [Fix Redis 6.0 compatibility breakage with Sidekiq 7 gem](gitlab-org/security/gitlab@e61868ad98d2ae640b3deec2b148c01fb52dba77)
+- [Defer ConnectionPool instrumentation setup](gitlab-org/security/gitlab@d31ee125cd7ec9023b7558bd7af44c0293637b94)
+- [Fix invalid records with FK not valid](gitlab-org/security/gitlab@a8dece6c5d160a218d9622a3dab0f93a7b2ca181)
+
+### Security (4 changes)
+
+- [Fix CI component input Regexp](gitlab-org/security/gitlab@96b81737b2b9f1aa3c9d710bc00b80be8359f68f) ([merge request](gitlab-org/security/gitlab!3854))
+- [Make scan result policies block renaming branches](gitlab-org/security/gitlab@6b12a71efe9c82b696cf1dc68c5aa2bc72e5fea3) ([merge request](gitlab-org/security/gitlab!3837))
+- [Restrict group access token creation for custom roles](gitlab-org/security/gitlab@e1d38e70f1f5c9defbb0ca2fa4608e603dcd2858) ([merge request](gitlab-org/security/gitlab!3834))
+- [Limit vulnerabilitiesCountByDay date range to 1 year](gitlab-org/security/gitlab@5e5428919d4773731bed7f724bd650dbc7555d9e) ([merge request](gitlab-org/security/gitlab!3826))
+
 ## 16.8.1 (2024-01-24)
 
 ### Fixed (1 change)
@@ -504,6 +519,18 @@ entry.
 - [Bump the finalize_after date of backfill migration](gitlab-org/gitlab@770ab7faa2048bfeb8bddd506e6f37fe18bb4d06) ([merge request](gitlab-org/gitlab!140109))
 - [Remove code_suggestions_completion_api feature](gitlab-org/gitlab@988e2f57f9635ed9cc3896b15965b608fce54756) ([merge request](gitlab-org/gitlab!138174)) **GitLab Enterprise Edition**
 
+## 16.7.5 (2024-02-07)
+
+### Fixed (1 change)
+
+- [Update dependency prometheus-client-mmap to '~> 1.1', '>= 1.1.1'](gitlab-org/security/gitlab@41326f12836b409735f0745d57b135fd952b54e0)
+
+### Security (3 changes)
+
+- [Fix CI component input Regexp](gitlab-org/security/gitlab@7b29c348a90b3311c5661b57572cbedf6160d02a) ([merge request](gitlab-org/security/gitlab!3855))
+- [Make scan result policies block renaming branches](gitlab-org/security/gitlab@5f8202c849059e28370d79aa79cd94a851abd61a) ([merge request](gitlab-org/security/gitlab!3838))
+- [Limit vulnerabilitiesCountByDay date range to 1 year](gitlab-org/security/gitlab@95c1de1c1c297ba59e7e52485e9703b01d8ad552) ([merge request](gitlab-org/security/gitlab!3827))
+
 ## 16.7.4 (2024-01-24)
 
 ### Fixed (1 change)
@@ -1444,6 +1471,14 @@ entry.
 
 - [Move export buttons next to each other](gitlab-org/gitlab@106bea7a6246cd153cf66d133936a09d46369ae3) ([merge request](gitlab-org/gitlab!137461))
 
+## 16.6.7 (2024-02-07)
+
+### Security (3 changes)
+
+- [Fix CI component input Regexp](gitlab-org/security/gitlab@4aea3a2d7f371d57a00eef647f84dce2b6963dc6) ([merge request](gitlab-org/security/gitlab!3856))
+- [Make scan result policies block renaming branches](gitlab-org/security/gitlab@6ea7b750df3a5c2505717555db0875be6b0b3cd0) ([merge request](gitlab-org/security/gitlab!3840))
+- [Limit vulnerabilitiesCountByDay date range to 1 year](gitlab-org/security/gitlab@4896b80a35e3a31b2cf0df28a3545ba5caf9cc6f) ([merge request](gitlab-org/security/gitlab!3831))
+
 ## 16.6.6 (2024-01-24)
 
 ### Fixed (1 change)
diff --git a/app/services/resource_access_tokens/create_service.rb b/app/services/resource_access_tokens/create_service.rb
index 824b1a8c377ee7f0e5ea941125f68798aeb2a886..c36cc981341381e25f8396194ad9f895e7d0dc16 100644
--- a/app/services/resource_access_tokens/create_service.rb
+++ b/app/services/resource_access_tokens/create_service.rb
@@ -128,11 +128,10 @@ def success(access_token)
     end
 
     def validate_access_level(access_level)
-      return true unless resource.is_a?(Project)
       return true if current_user.bot?
-      return true if current_user.can?(:manage_owners, resource)
+      return true if current_user.can?(:owner_access, resource)
 
-      current_user.authorized_project?(resource, access_level.to_i)
+      resource.member?(current_user, access_level.to_i)
     end
 
     def do_not_allow_owner_access_level_for_project_bot?(access_level)
diff --git a/app/views/groups/settings/access_tokens/index.html.haml b/app/views/groups/settings/access_tokens/index.html.haml
index 832fd6e8cebbf85668878ddae459846777382418..b45c5dc7d5fdf14cd8ea6ee6f6883e736019836e 100644
--- a/app/views/groups/settings/access_tokens/index.html.haml
+++ b/app/views/groups/settings/access_tokens/index.html.haml
@@ -47,7 +47,7 @@
               resource: @group,
               token: @resource_access_token,
               scopes: @scopes,
-              access_levels: GroupMember.access_level_roles,
+              access_levels: access_level_roles_user_can_assign(@group),
               default_access_level: Gitlab::Access::GUEST,
               prefix: :resource_access_token,
               description_prefix: :group_access_token,
diff --git a/ee/app/graphql/resolvers/vulnerabilities_count_per_day_resolver.rb b/ee/app/graphql/resolvers/vulnerabilities_count_per_day_resolver.rb
index 36269fff98ac0532b1b46d0b07fc4e2e99b99bdf..26a62e4ac31149b1ce91ad038e84c79344a85e0a 100644
--- a/ee/app/graphql/resolvers/vulnerabilities_count_per_day_resolver.rb
+++ b/ee/app/graphql/resolvers/vulnerabilities_count_per_day_resolver.rb
@@ -4,6 +4,8 @@ module Resolvers
   class VulnerabilitiesCountPerDayResolver < VulnerabilitiesBaseResolver
     include Gitlab::Graphql::Authorize::AuthorizeResource
 
+    MAX_DATE_RANGE_DAYS = 1.year.in_days.floor.freeze
+
     type Types::VulnerabilitiesCountByDayType, null: true
     authorize :read_security_resource
 
@@ -19,6 +21,8 @@ def resolve(**args)
       # Instance security dashboard does not have an object to authorize against.
       authorize!(object) unless resolve_vulnerabilities_for_instance_security_dashboard?
 
+      validate_date_range!(args)
+
       return [] unless vulnerable
 
       vulnerable
@@ -32,6 +36,14 @@ def resolve(**args)
 
     private
 
+    def validate_date_range!(args)
+      # GraphQL::Types::ISO8601Date is instantiated as Date and the difference between
+      # two dates is the number of days between them.
+      return unless (args[:end_date] - args[:start_date]) > MAX_DATE_RANGE_DAYS
+
+      raise Gitlab::Graphql::Errors::ArgumentError, "maximum date range is #{MAX_DATE_RANGE_DAYS} days"
+    end
+
     def generate_missing_dates(calendar_entries, start_date, end_date)
       severities = ::Enums::Vulnerability.severity_levels.keys
       (start_date..end_date)
diff --git a/ee/app/models/security/scan_result_policy_read.rb b/ee/app/models/security/scan_result_policy_read.rb
index 05bd107dbc890265aebc8c9af6e7ae75fba807c0..10ae9438801db28052b5998a42b87fa9c570a926 100644
--- a/ee/app/models/security/scan_result_policy_read.rb
+++ b/ee/app/models/security/scan_result_policy_read.rb
@@ -33,6 +33,9 @@ class ScanResultPolicyRead < ApplicationRecord
     scope :for_project, ->(project) { where(project: project) }
     scope :targeting_commits, -> { where.not(commits: nil) }
     scope :including_approval_merge_request_rules, -> { includes(:approval_merge_request_rules) }
+    scope :blocking_branch_modification, -> do
+      where("project_approval_settings->>'block_branch_modification' = 'true'")
+    end
 
     def newly_detected?
       license_states.include?(ApprovalProjectRule::NEWLY_DETECTED)
diff --git a/ee/app/services/ee/protected_branches/renaming_blocked_by_policy.rb b/ee/app/services/ee/protected_branches/renaming_blocked_by_policy.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ad34fa7d1072542d34987c72959196c9fd85de5b
--- /dev/null
+++ b/ee/app/services/ee/protected_branches/renaming_blocked_by_policy.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module EE
+  module ProtectedBranches
+    module RenamingBlockedByPolicy
+      def execute(protected_branch)
+        raise ::Gitlab::Access::AccessDeniedError if renaming? && blocked?(protected_branch)
+
+        super
+      end
+
+      private
+
+      def renaming?
+        params.key?(:name)
+      end
+
+      def blocked?(protected_branch)
+        return blocking_branch_modification?(protected_branch.project) if protected_branch.project_level?
+
+        blocking_group_branch_modification?(protected_branch.group)
+      end
+
+      def blocking_branch_modification?(project)
+        return false unless project&.licensed_feature_available?(:security_orchestration_policies)
+        return false unless ::Feature.enabled?(:scan_result_policies_block_unprotecting_branches, project)
+
+        project.scan_result_policy_reads.blocking_branch_modification.exists?
+      end
+
+      def blocking_group_branch_modification?(group)
+        return false unless group&.licensed_feature_available?(:security_orchestration_policies)
+        return false unless ::Feature.enabled?(:scan_result_policy_block_group_branch_modification, group)
+
+        ::Security::SecurityOrchestrationPolicies::GroupProtectedBranchesDeletionCheckService
+          .new(group: group)
+          .execute
+      end
+    end
+  end
+end
diff --git a/ee/app/services/ee/protected_branches/update_service.rb b/ee/app/services/ee/protected_branches/update_service.rb
index 86d5f8c5f63822d17ea0baad2a5237d30842a3cd..c79418d1f223c795331e61cd61ac0a6b5c191393 100644
--- a/ee/app/services/ee/protected_branches/update_service.rb
+++ b/ee/app/services/ee/protected_branches/update_service.rb
@@ -3,6 +3,8 @@
 module EE
   module ProtectedBranches
     module UpdateService
+      prepend RenamingBlockedByPolicy
+
       def after_execute(protected_branch:, old_merge_access_levels:, old_push_access_levels:)
         super
 
diff --git a/ee/spec/controllers/ee/projects/protected_branches_controller_spec.rb b/ee/spec/controllers/ee/projects/protected_branches_controller_spec.rb
index b72ad254c5fe83feab79fca2f7e3d39f949be16a..1372a9b262b5f356b7ab7f035b3a8efcb0fa3427 100644
--- a/ee/spec/controllers/ee/projects/protected_branches_controller_spec.rb
+++ b/ee/spec/controllers/ee/projects/protected_branches_controller_spec.rb
@@ -11,17 +11,17 @@
     project.add_maintainer(user)
   end
 
-  shared_examples "protected branch with code owner approvals feature" do |boolean|
-    it "sets code owner approvals to #{boolean} when protecting the branch" do
-      expect do
-        post(:create, params: project_params.merge(protected_branch: create_params))
-      end.to change { ProtectedBranch.count }.by(1)
+  describe "POST #create" do
+    shared_examples "protected branch with code owner approvals feature" do |boolean|
+      it "sets code owner approvals to #{boolean} when protecting the branch" do
+        expect do
+          post(:create, params: project_params.merge(protected_branch: create_params))
+        end.to change { ProtectedBranch.count }.by(1)
 
-      expect(ProtectedBranch.last.attributes["code_owner_approval_required"]).to eq(boolean)
+        expect(ProtectedBranch.last.attributes["code_owner_approval_required"]).to eq(boolean)
+      end
     end
-  end
 
-  describe "POST #create" do
     let(:maintainer_access_level) { [{ access_level: Gitlab::Access::MAINTAINER }] }
     let(:access_level_params) do
       { merge_access_levels_attributes: maintainer_access_level,
@@ -66,4 +66,67 @@
       end
     end
   end
+
+  describe "PUT/PATCH #update" do
+    let(:new_name) { "foobar" }
+
+    let(:params) do
+      { namespace_id: project.namespace.to_param,
+        project_id: project.to_param,
+        id: protected_branch.id,
+        protected_branch: { name: new_name } }
+    end
+
+    subject(:update_protected_branch) { put(:update, params: params) }
+
+    before do
+      sign_in(user)
+    end
+
+    context 'without blocking scan result policy' do
+      it 'renames' do
+        expect { update_protected_branch }.to change { protected_branch.reload.name }.to(new_name)
+      end
+    end
+
+    context 'with blocking scan result policy' do
+      let(:branch_name) { protected_branch.name }
+      let(:policy_configuration) do
+        create(:security_orchestration_policy_configuration, project: project)
+      end
+
+      include_context 'with scan result policy blocking protected branches'
+
+      before do
+        create(:scan_result_policy_read, :blocking_protected_branches, project: project,
+          security_orchestration_policy_configuration: policy_configuration)
+      end
+
+      it 'does not rename' do
+        expect { update_protected_branch }.not_to change { protected_branch.reload.name }
+      end
+
+      it 'responds with 403' do
+        update_protected_branch
+
+        expect(response).to have_gitlab_http_status(:forbidden)
+      end
+
+      context 'with feature disabled' do
+        before do
+          stub_feature_flags(scan_result_policies_block_unprotecting_branches: false)
+        end
+
+        it 'renames' do
+          expect { update_protected_branch }.to change { protected_branch.reload.name }.to(new_name)
+        end
+
+        it 'responds with 200' do
+          update_protected_branch
+
+          expect(response).to have_gitlab_http_status(:success)
+        end
+      end
+    end
+  end
 end
diff --git a/ee/spec/models/security/scan_result_policy_read_spec.rb b/ee/spec/models/security/scan_result_policy_read_spec.rb
index e5c4b83ab65eddced1daeade87634fca12d0f8d6..ca021b0de52d3bd1e3ae4c1d54590e2163c9b011 100644
--- a/ee/spec/models/security/scan_result_policy_read_spec.rb
+++ b/ee/spec/models/security/scan_result_policy_read_spec.rb
@@ -63,6 +63,19 @@
     it { is_expected.to define_enum_for(:age_interval).with_values(**age_interval_values) }
   end
 
+  describe 'scopes' do
+    describe '.blocking_branch_modification' do
+      let_it_be(:non_blocking_read) { create(:scan_result_policy_read) }
+      let_it_be(:blocking_read) do
+        create(:scan_result_policy_read, project_approval_settings: { block_branch_modification: true })
+      end
+
+      it 'returns blocking reads' do
+        expect(described_class.blocking_branch_modification).to contain_exactly(blocking_read)
+      end
+    end
+  end
+
   describe '#newly_detected?' do
     subject { scan_result_policy_read.newly_detected? }
 
diff --git a/ee/spec/requests/api/graphql/branch_rules/update_spec.rb b/ee/spec/requests/api/graphql/branch_rules/update_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..56e51bf24874e7a6062a179e59173fcfb9b32ecd
--- /dev/null
+++ b/ee/spec/requests/api/graphql/branch_rules/update_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'BranchRuleUpdate', feature_category: :source_code_management do
+  include GraphqlHelpers
+
+  let_it_be(:project) { create(:project, :public) }
+  let_it_be(:user) { create(:user) }
+  let!(:branch_rule) { create(:protected_branch, project: project) }
+  let(:current_user) { user }
+  let(:mutation) { graphql_mutation(:branch_rule_update, params) }
+
+  let(:params) do
+    {
+      id: branch_rule.to_global_id,
+      project_path: project.full_path,
+      name: branch_rule.name.reverse
+    }
+  end
+
+  subject(:post_mutation) { post_graphql_mutation(mutation, current_user: user) }
+
+  before_all do
+    project.add_maintainer(user)
+  end
+
+  context 'with blocking scan result policy' do
+    let(:branch_name) { branch_rule.name }
+    let(:policy_configuration) do
+      create(:security_orchestration_policy_configuration, project: project)
+    end
+
+    include_context 'with scan result policy blocking protected branches'
+
+    before do
+      create(:scan_result_policy_read, :blocking_protected_branches, project: project,
+        security_orchestration_policy_configuration: policy_configuration)
+    end
+
+    it_behaves_like 'a mutation that returns top-level errors',
+      errors: ["Internal server error: Gitlab::Access::AccessDeniedError"]
+  end
+end
diff --git a/ee/spec/requests/api/graphql/vulnerabilities/instance_vulnerability_count_by_day_spec.rb b/ee/spec/requests/api/graphql/vulnerabilities/instance_vulnerability_count_by_day_spec.rb
index 4c306c8554a922036cfbda48eb098664cde92c9a..159aa9c38dd1b94c5985ce4981ed22d0892df20d 100644
--- a/ee/spec/requests/api/graphql/vulnerabilities/instance_vulnerability_count_by_day_spec.rb
+++ b/ee/spec/requests/api/graphql/vulnerabilities/instance_vulnerability_count_by_day_spec.rb
@@ -44,6 +44,16 @@
     end
   end
 
+  context 'when requesting a large date range' do
+    let(:args) { { start_date: 366.days.before(date), end_date: date } }
+
+    it 'returns an error' do
+      max_days = ::Resolvers::VulnerabilitiesCountPerDayResolver::MAX_DATE_RANGE_DAYS
+
+      expect_graphql_errors_to_include("maximum date range is #{max_days} days")
+    end
+  end
+
   context 'when user has permission to access the security dashboard of the project' do
     before_all do
       project.add_developer(current_user)
diff --git a/ee/spec/requests/custom_roles/manage_group_access_tokens/request_spec.rb b/ee/spec/requests/custom_roles/manage_group_access_tokens/request_spec.rb
index eb606a902c373e3010f7eec326b7133179c17646..8d2e04ae9770a7ee494526b7844e48e8464334e0 100644
--- a/ee/spec/requests/custom_roles/manage_group_access_tokens/request_spec.rb
+++ b/ee/spec/requests/custom_roles/manage_group_access_tokens/request_spec.rb
@@ -25,20 +25,39 @@
     end
 
     describe '#create' do
-      let_it_be(:access_token_params) { { name: 'TestToken', scopes: ['api'], expires_at: Date.today + 1.month } }
       let_it_be(:resource) { group }
+      let(:access_token_params) do
+        { name: 'TestToken', scopes: ['api'], expires_at: Date.today + 1.month, access_level: access_level }
+      end
 
       subject(:request) do
         post group_settings_access_tokens_path(group, params: { resource_access_token: access_token_params })
       end
 
-      it 'user has access via a custom role' do
-        request
+      context 'when creating a token with an access level that is lower or equal to the current users access level' do
+        let(:access_level) { 10 }
 
-        expect(response).to have_gitlab_http_status(:ok)
+        it 'user has access via a custom role' do
+          request
+
+          expect(response).to have_gitlab_http_status(:ok)
+        end
+
+        it_behaves_like 'POST resource access tokens available'
       end
 
-      it_behaves_like 'POST resource access tokens available'
+      context 'when creating a token with an access level that is higher than the current users access level' do
+        let(:access_level) { 20 }
+
+        it 'renders JSON with an error' do
+          request
+
+          expect(response.parsed_body['new_token']).to be_blank
+          expect(response.parsed_body['errors'])
+            .to include("Access level of the token can't be greater the access level of the user who created the token")
+          expect(response).to have_gitlab_http_status(:unprocessable_entity)
+        end
+      end
     end
 
     describe '#revoke' do
diff --git a/ee/spec/requests/groups/protected_branches_controller_spec.rb b/ee/spec/requests/groups/protected_branches_controller_spec.rb
index c3f2f1de3590e8d6e58b11ead5ba3533ba89e51a..289c795e12b2518eea5496e00e4a60af4cedc4ae 100644
--- a/ee/spec/requests/groups/protected_branches_controller_spec.rb
+++ b/ee/spec/requests/groups/protected_branches_controller_spec.rb
@@ -144,6 +144,56 @@
         expect(response).to have_gitlab_http_status(:unprocessable_entity)
       end
     end
+
+    context 'with blocking scan result policy' do
+      shared_examples 'prevents update of protected branch' do
+        let(:branch_name) { protected_branch.name }
+        let(:policy_configuration) do
+          create(:security_orchestration_policy_configuration, :namespace, namespace_id: group.id)
+        end
+
+        before do
+          stub_licensed_features(group_protected_branches: true, security_orchestration_policies: true)
+        end
+
+        it 'does not rename' do
+          expect { patch member_path, params: update_params }.not_to change { protected_branch.reload.name }
+          expect(response).to have_gitlab_http_status(:forbidden)
+        end
+
+        it 'responds with 403' do
+          patch member_path, params: update_params
+
+          expect(response).to have_gitlab_http_status(:forbidden)
+        end
+
+        context 'with feature disabled' do
+          before do
+            stub_feature_flags(scan_result_policy_block_group_branch_modification: false)
+          end
+
+          it 'renames' do
+            expect { patch member_path, params: update_params }.to change {
+                                                                     protected_branch.reload.name
+                                                                   }.to(update_params.dig(:protected_branch, :name))
+          end
+
+          it 'responds with 200' do
+            patch member_path, params: update_params
+
+            expect(response).to have_gitlab_http_status(:success)
+          end
+        end
+      end
+
+      include_context 'with scan result policy blocking protected branches' do
+        include_examples 'prevents update of protected branch'
+      end
+
+      include_context 'with scan result policy blocking group-level protected branches' do
+        include_examples 'prevents update of protected branch'
+      end
+    end
   end
 
   describe "DELETE #destroy" do
diff --git a/ee/spec/services/ee/protected_branches/update_service_spec.rb b/ee/spec/services/ee/protected_branches/update_service_spec.rb
index 85805d0bec624d7f4dc54dcb55cb212f8f2d34fb..2bdde47981f8cc6a5f4464498cbe1720450ed7d6 100644
--- a/ee/spec/services/ee/protected_branches/update_service_spec.rb
+++ b/ee/spec/services/ee/protected_branches/update_service_spec.rb
@@ -38,4 +38,81 @@
       end
     end
   end
+
+  describe 'blocking scan result policies' do
+    context 'with project-level protected branch' do
+      let(:params) { { name: branch_name.reverse } }
+
+      let(:policy_configuration) do
+        create(:security_orchestration_policy_configuration, project: project)
+      end
+
+      include_context 'with scan result policy blocking protected branches'
+
+      before do
+        create(:scan_result_policy_read, :blocking_protected_branches, project: project,
+          security_orchestration_policy_configuration: policy_configuration)
+      end
+
+      it 'raises' do
+        expect { service.execute(protected_branch) }.to raise_error(::Gitlab::Access::AccessDeniedError)
+      end
+
+      context 'with feature disabled' do
+        before do
+          stub_feature_flags(scan_result_policies_block_unprotecting_branches: false)
+        end
+
+        it 'renames' do
+          expect { service.execute(protected_branch) }.to change {
+            protected_branch.reload.name
+          }.to(branch_name.reverse)
+        end
+      end
+    end
+
+    context 'with group-level protected branch' do
+      let_it_be(:user) { create(:user) }
+      let_it_be(:group) { create(:group) }
+      let_it_be(:protected_branch) { create(:protected_branch, project_id: nil, namespace_id: group.id) }
+
+      before_all do
+        group.add_owner(user)
+      end
+
+      context 'with blocking scan result policy' do
+        let(:params) { { name: branch_name.reverse } }
+
+        let(:policy_configuration) do
+          create(:security_orchestration_policy_configuration, :namespace, namespace_id: group.id)
+        end
+
+        shared_examples 'prevents update of protected branch' do
+          it 'raises' do
+            expect { service.execute(protected_branch) }.to raise_error(::Gitlab::Access::AccessDeniedError)
+          end
+
+          context 'with feature disabled' do
+            before do
+              stub_feature_flags(scan_result_policy_block_group_branch_modification: false)
+            end
+
+            it 'renames' do
+              expect { service.execute(protected_branch) }.to change {
+                protected_branch.reload.name
+              }.to(branch_name.reverse)
+            end
+          end
+        end
+
+        include_context 'with scan result policy blocking protected branches' do
+          include_examples 'prevents update of protected branch'
+        end
+
+        include_context 'with scan result policy blocking group-level protected branches' do
+          include_examples 'prevents update of protected branch'
+        end
+      end
+    end
+  end
 end
diff --git a/lib/gitlab/ci/config/interpolation/block.rb b/lib/gitlab/ci/config/interpolation/block.rb
index aec19299e86feca4263ce6b8981aacc01f14b4d1..dc1ca423a81673c821532b5b6b42966551384174 100644
--- a/lib/gitlab/ci/config/interpolation/block.rb
+++ b/lib/gitlab/ci/config/interpolation/block.rb
@@ -14,7 +14,7 @@ module Interpolation
         # they are presented.
         class Block
           PREFIX = '$[['
-          PATTERN = /(?<block>\$\[\[\s*(?<data>.*?)\s*\]\])/
+          PATTERN = /(?<block>\$\[\[\s*(?<data>\S{1}.*?\S{1})\s*\]\])/
           MAX_FUNCTIONS = 3
 
           attr_reader :block, :data, :ctx, :errors
diff --git a/spec/lib/gitlab/ci/config/interpolation/block_spec.rb b/spec/lib/gitlab/ci/config/interpolation/block_spec.rb
index bfaa4eb3e05652f1f4da954d5b1d5fb407c9f432..7b9111f11d373b52bf60cbe41bf07ec090fa37ad 100644
--- a/spec/lib/gitlab/ci/config/interpolation/block_spec.rb
+++ b/spec/lib/gitlab/ci/config/interpolation/block_spec.rb
@@ -31,9 +31,9 @@
         .to yield_successive_args(['$[[ access1 ]]', 'access1'], ['$[[ access2 ]]', 'access2'])
     end
 
-    it 'matches an empty block' do
+    it 'does not match an empty block' do
       expect { |b| described_class.match('$[[]]', &b) }
-        .to yield_with_args('$[[]]', '')
+        .not_to yield_with_args(anything)
     end
 
     context 'when functions are specified in the block' do
diff --git a/spec/support/shared_examples/services/protected_branches_shared_examples.rb b/spec/support/shared_examples/services/protected_branches_shared_examples.rb
index 980241ad586fe0bc254205dc284c4ca2428675e2..74bf57ea5ea2abbdf63d96dbb30021be4c9de691 100644
--- a/spec/support/shared_examples/services/protected_branches_shared_examples.rb
+++ b/spec/support/shared_examples/services/protected_branches_shared_examples.rb
@@ -30,6 +30,14 @@
   end
 end
 
+RSpec.shared_context 'with scan result policy blocking group-level protected branches' do
+  include_context 'with scan result policy' do
+    let(:scan_result_policy) do
+      build(:scan_result_policy, branches: [branch_name], approval_settings: { block_group_branch_modification: true })
+    end
+  end
+end
+
 RSpec.shared_context 'with scan result policy preventing force pushing' do
   include_context 'with scan result policy' do
     let(:prevent_pushing_and_force_pushing) { true }