Consider the custom_role base_access_level for eligible approvers

What does this MR do and why?

This MR updates the custom_role_ids_with_permission method in ScanResultPolicyRead to also check the custom_role base_access_level since the admin_merge_request can be inherited from the base role.

Database queries

Query for Self-managed

SELECT
    "member_roles"."id"
FROM
    "member_roles"
WHERE
    "member_roles"."namespace_id" IS NULL
    AND "member_roles"."id" = 2
    AND (member_roles.permissions @> ('{"admin_merge_request":true}')::jsonb
        OR base_access_level >= 30)

https://postgres.ai/console/gitlab/gitlab-production-main/sessions/42195/commands/129351

Query for GitLab.com

SELECT
    "member_roles"."id"
FROM
    "member_roles"
WHERE
    "member_roles"."namespace_id" = 70922626
    AND "member_roles"."id" = 2005187
    AND (member_roles.permissions @> ('{"admin_merge_request":true}')::jsonb
        OR "member_roles"."base_access_level" >= 30)

https://postgres.ai/console/gitlab/gitlab-production-main/sessions/42195/commands/129353

References

Related to #558901 (closed)

Screenshots or screen recordings

Before After
Screenshot_2025-08-06_at_12.02.44_PM Screenshot_2025-08-06_at_1.54.09_PM

How to set up and validate locally

Create a new custom role

  1. Go to the Admin Area > Settings > Roles and permissions
  2. Create a custom role with Developer as base role and add any additional permissions
  3. Create a new project
  4. Add a .gitlab-ci.yml file with the content:
include:
- template: Jobs/SAST.gitlab-ci.yml
  1. Go to Manage > Members
  2. Invite a user with the custom role to the project
  3. Go to Secure > Policies
  4. Click on New Policy
  5. Select Merge request approval policy
  6. Create a policy that requires approval from the custom role created on step 1
approval_policy:
  - name: mrap
    description: ''
    enabled: true
    rules:
      - type: scan_finding
        scanners:
          - sast
        vulnerabilities_allowed: 0
        severity_levels: []
        vulnerability_states:
          - new_needs_triage
        branch_type: protected
    actions:
      - type: require_approval
        approvals_required: 1
        role_approvers:
          - 2
      - type: send_bot_message
        enabled: true
    approval_settings:
      block_branch_modification: true
      prevent_pushing_and_force_pushing: true
      prevent_approval_by_author: true
      prevent_approval_by_commit_author: true
      remove_approvals_with_new_commit: true
      require_password_to_approve: false
    fallback_behavior:
      fail: closed
  1. Create a MR adding a file called test.rb with the content:
class RunScript
    def run_script
        system("cat #{params[:path]}") 
    end
end
  1. Verify the MR requires approval and that the user added in step 6 is eligible approver

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Marcos Rocha

Merge request reports

Loading