diff --git a/app/validators/json_schemas/member_role_permissions.json b/app/validators/json_schemas/member_role_permissions.json
index 9d14329c3671b93ab6bb694e4766262b653fb867..a4b6109da101dfbb2451d1a1280cd9fda7588e06 100644
--- a/app/validators/json_schemas/member_role_permissions.json
+++ b/app/validators/json_schemas/member_role_permissions.json
@@ -13,6 +13,9 @@
"admin_merge_request": {
"type": "boolean"
},
+ "admin_push_rules": {
+ "type": "boolean"
+ },
"admin_terraform_state": {
"type": "boolean"
},
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 477882526763618e13449b261cbc0426073f3bae..a8f6858f807104640c5681e7bb1ccff8436fd179 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -32281,6 +32281,7 @@ Member role permission.
| `ADMIN_CICD_VARIABLES` | Create, read, update, and delete CI/CD variables. |
| `ADMIN_GROUP_MEMBER` | Add or remove users in a group, and assign roles to users. When assigning a role, users with this custom permission must select a role that has the same or fewer permissions as the default role used as the base for their custom role. |
| `ADMIN_MERGE_REQUEST` | Allows approval of merge requests. |
+| `ADMIN_PUSH_RULES` | Configure push rules for repositories at the group or project level. |
| `ADMIN_TERRAFORM_STATE` | Execute terraform commands, lock/unlock terraform state files, and remove file versions. |
| `ADMIN_VULNERABILITY` | Edit the vulnerability object, including the status and linking an issue. Includes the `read_vulnerability` permission actions. |
| `ARCHIVE_PROJECT` | Allows archiving of projects. |
diff --git a/doc/user/custom_roles/abilities.md b/doc/user/custom_roles/abilities.md
index 9c15f3e1262e59ee694d7349e0807ea3662cf0aa..9919b543f1dc1b66aa841371374638bc430bb1c5 100644
--- a/doc/user/custom_roles/abilities.md
+++ b/doc/user/custom_roles/abilities.md
@@ -56,6 +56,12 @@ These requirements are documented in the `Required permission` column in the fol
|:-----|:------------|:------------------|:---------|:--------------|:---------|
| [`admin_cicd_variables`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/143369) | | Create, read, update, and delete CI/CD variables. | GitLab [16.10](https://gitlab.com/gitlab-org/gitlab/-/issues/437947) | | |
+## Source code management
+
+| Name | Required permission | Description | Introduced in | Feature flag | Enabled in |
+|:-----|:------------|:------------------|:---------|:--------------|:---------|
+| [`admin_push_rules`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/147872) | | Configure push rules for repositories at the group or project level. | GitLab [16.11](https://gitlab.com/gitlab-org/gitlab/-/issues/421786) | `custom_ability_admin_push_rules` | |
+
## System access
| Name | Required permission | Description | Introduced in | Feature flag | Enabled in |
diff --git a/ee/app/policies/ee/group_policy.rb b/ee/app/policies/ee/group_policy.rb
index cb2cdb227ab6497fdb48ecaf068852716f41f3a2..c6eb2d433a0f81d795993ffa4d461d23aa4904a2 100644
--- a/ee/app/policies/ee/group_policy.rb
+++ b/ee/app/policies/ee/group_policy.rb
@@ -265,6 +265,15 @@ module GroupPolicy
).has_ability?
end
+ desc 'Custom role on group that enables admin push rules for repositories'
+ condition(:role_enables_admin_push_rules) do
+ ::Auth::MemberRoleAbilityLoader.new(
+ user: @user,
+ resource: @subject,
+ ability: :admin_push_rules
+ ).has_ability?
+ end
+
rule { owner & unique_project_download_limit_enabled }.policy do
enable :ban_group_member
end
@@ -580,6 +589,10 @@ module GroupPolicy
enable :remove_group
end
+ rule { custom_roles_allowed & role_enables_admin_push_rules }.policy do
+ enable :admin_push_rules
+ end
+
rule { can?(:read_group_security_dashboard) }.policy do
enable :create_vulnerability_export
enable :read_security_resource
diff --git a/ee/app/policies/ee/project_policy.rb b/ee/app/policies/ee/project_policy.rb
index 2a8c3a728d17f5a0d619a7645021c69e90d3ec15..1e28c8aa9a50796d6149eedd227f2fa31f86529c 100644
--- a/ee/app/policies/ee/project_policy.rb
+++ b/ee/app/policies/ee/project_policy.rb
@@ -307,6 +307,15 @@ module ProjectPolicy
).has_ability?
end
+ desc 'Custom role on project that enables admin push rules for repositories'
+ condition(:role_enables_admin_push_rules) do
+ ::Auth::MemberRoleAbilityLoader.new(
+ user: @user,
+ resource: @subject,
+ ability: :admin_push_rules
+ ).has_ability?
+ end
+
condition(:developer_access_to_admin_vulnerability) do
::Feature.disabled?(:disable_developer_access_to_admin_vulnerability, subject&.root_namespace) &&
can?(:developer_access)
@@ -387,6 +396,10 @@ module ProjectPolicy
enable :admin_cicd_variables
end
+ rule { custom_roles_allowed & role_enables_admin_push_rules }.policy do
+ enable :admin_push_rules
+ end
+
condition(:ci_cancellation_maintainers_only, scope: :subject) do
project.ci_cancellation_restriction.maintainers_only_allowed?
end
diff --git a/ee/config/custom_abilities/admin_push_rules.yml b/ee/config/custom_abilities/admin_push_rules.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ec4dbd26874cc947399d7bfeedc230515823ac94
--- /dev/null
+++ b/ee/config/custom_abilities/admin_push_rules.yml
@@ -0,0 +1,12 @@
+---
+name: admin_push_rules
+description: Configure push rules for repositories at the group or project level.
+introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/421786
+introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/147872
+feature_category: source_code_management
+milestone: '16.11'
+group_ability: true
+project_ability: true
+requirements: []
+feature_flag: custom_ability_admin_push_rules
+available_from_access_level:
diff --git a/ee/config/feature_flags/wip/custom_ability_admin_push_rules.yml b/ee/config/feature_flags/wip/custom_ability_admin_push_rules.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c958a72e69d7c365c18183803be5d20850b60de2
--- /dev/null
+++ b/ee/config/feature_flags/wip/custom_ability_admin_push_rules.yml
@@ -0,0 +1,9 @@
+---
+name: custom_ability_admin_push_rules
+feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/421786
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/147872
+rollout_issue_url:
+milestone: '16.11'
+group: group::authorization
+type: wip
+default_enabled: false
diff --git a/ee/spec/policies/group_policy_spec.rb b/ee/spec/policies/group_policy_spec.rb
index 036863108b7c2aaf13e1373f790f2a2f8a0e1a5f..bc92adf8bff5d556d227fa9f21824e6cff6dafb4 100644
--- a/ee/spec/policies/group_policy_spec.rb
+++ b/ee/spec/policies/group_policy_spec.rb
@@ -3329,6 +3329,13 @@ def create_member_role(member, abilities = member_role_abilities)
it { is_expected.to be_disallowed(*allowed_abilities) }
end
end
+
+ context 'for a custom role with the `admin_push_rules` ability' do
+ let(:member_role_abilities) { { admin_push_rules: true } }
+ let(:allowed_abilities) { [:admin_push_rules] }
+
+ it_behaves_like 'custom roles abilities'
+ end
end
context 'for :read_limit_alert' do
diff --git a/ee/spec/policies/project_policy_spec.rb b/ee/spec/policies/project_policy_spec.rb
index 5cba645b27ecf09ed0d8753295e0673937daf678..640823d3cb9d1df45ff7f927aad16b1b2da59067 100644
--- a/ee/spec/policies/project_policy_spec.rb
+++ b/ee/spec/policies/project_policy_spec.rb
@@ -2783,6 +2783,13 @@ def create_member_role(member, abilities = member_role_abilities)
it_behaves_like 'custom roles abilities'
end
+
+ context 'for a custom role with the `admin_push_rules` ability' do
+ let(:member_role_abilities) { { admin_push_rules: true } }
+ let(:allowed_abilities) { [:admin_push_rules] }
+
+ it_behaves_like 'custom roles abilities'
+ end
end
describe 'permissions for suggested reviewers bot', :saas do