Skip to content

Extend Scan Result Policies to process License Approval Policies

Sashi Kumar Kumaresan requested to merge sk/385605-service-changes into master

What does this MR do and why?

Addresses #385606 (closed) and #385605 (closed)

DB Changes MR 1: !111682 (merged) DB Changes MR 2: !110947 (merged)

Feature flag: license_scanning_policies

Motivation:

Currently we are only processing Scan Result Policies with scan_finding rule type. In scope of this MR we want to change it to also support Scan Result Policies with license_finding rule type.

Currently License Approvals are configured in the Project's Settings -> Merge Requests -> Merge request approvals, you can specify there branches, approvers and how many approvals are needed. Any additional software license policies are configured in Security & Compliance -> License Compliance -> Policies tab (see https://gitlab.com/gitlab-org/gitlab/-/licenses#policies). With this feature we want to support it in one place, as License Approval Policy under Scan Result Policy.

This feature is behind existing feature flag (license_scanning_policies), so policy will be only processed when this feature flag is enabled for the project.

DB Query analysis:

Note: This query does not get actual data as the migration to add/update the index/columns are in !110947 (merged). The query plan are just to show that it uses the index created in the DB MR.

Query to get approval rules related to scan_result_policy_id

SELECT
    "approval_merge_request_rules".* 
FROM
    "approval_merge_request_rules" 
INNER JOIN
    "merge_requests" 
        ON "merge_requests"."id" = "approval_merge_request_rules"."merge_request_id" 
WHERE
    "approval_merge_request_rules"."rule_type" = 3 
    AND "approval_merge_request_rules"."report_type" = 2 
    AND "approval_merge_request_rules"."scan_result_policy_id" IS NOT NULL 
    AND "merge_requests"."state_id" != 3 
    AND "approval_merge_request_rules"."merge_request_id" IN (
        SELECT
            "merge_requests"."id" 
        FROM
            "merge_requests" 
        WHERE
            "merge_requests"."head_pipeline_id" = 771621540
    ) 

console.postgres.ai


Query to get license policies related to scan_result_policy_id

SELECT
    "software_license_policies".* 
FROM
    "software_license_policies" 
WHERE
    "software_license_policies"."project_id" = 278964 
    AND "software_license_policies"."scan_result_policy_id" = 1 
 Index Scan using idx_software_license_policies_unique_on_project_and_scan_policy on public.software_license_policies  (cost=0.29..3.21 rows=1 width=40) (actual time=0.150..0.150 rows=0 loops=1)
   Index Cond: ((software_license_policies.project_id = 278964) AND (software_license_policies.scan_result_policy_id = 1))
   Buffers: shared read=2
   I/O Timings: read=0.078 write=0.000

console.postgres.ai

Policy sample:

type: scan_result_policy
name: License Policy
description: ''
enabled: true
rules:
  - type: license_finding
    branches: []
    match_on_inclusion: false
    license_types:
      - MIT
      - Apache 2.0
    license_states:
      - newly_detected
actions:
  - type: require_approval
    approvals_required: 1
    group_approvers_ids:
      - 24

The above rule translates to: Whenever an MR (for a project that has license compliance enabled)) introduces a new dependency belonging a license type other that MIT and Apache 2.0 requires approval from members of group with id 24.

Also, as per the requirements:

The newly_detected state, will trigger anytime either a new package is being introduced or when a new license for an existing package is detected.

  1. Note: This will allow users to require approval anytime a new dependency is introduced (even if it does not violate a license policy)

if license_state contains newly_detected, the MR should require approval even if a new dependency is detected with a valid license.

Screenshots or screen recordings

Demo recording(Private): https://www.youtube.com/watch?v=8atMp1IGo4c

Policy

Screenshot_2023-02-08_at_1.09.56_AM

MR Approval

Screenshot_2023-02-08_at_1.09.41_AM

How to set up and validate locally

  • Clone https://gitlab.com/sashi_kumar/license-approval-policy and enable license_scanning_policies feature flag for the project
  • Create Scan result policy from: Security & Compliance -> Policies -> New scan result policy -> License Scan
  • Create MRs by updating the report.json in .gitlab-ci.yml and check if the MR requires approval based on the license policy created in previous step

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Sashi Kumar Kumaresan

Merge request reports