Skip to content

Add `branch_type` support to scan execution policies

What does this MR do and why?

We are adding branch_type support to security policies (&9468 (closed)).

This MR adds branch_type support to Scan execution policies.

Currently, security policies specify their targeted branches with the branches key. The value can be wildcarded, e.g. feature-* to target mutliple branches. We are now adding branch_type which accepts one of three values: all, protected and default.

For details on branch_type, see Proposal.

How to set up and validate locally

  • Create a new group

  • Create a new contained project

  • Enable the feature flag for the project:

    Feature.enable(:security_policies_branch_type, Project.last)
  • Commit the following .gitlab-ci.yml:

    dummy_job:
      script:
        - exit 0
  • Commit an empty Gemfile.lock for Dependency Scanning jobs to execute.

  • Navigate to Repository > Branches and create the following branches:

    • develop
    • feature-1
    • feature-2
    • legacy
  • Navigate to Settings > Repository, expand the Protected branches section and create the following protected branches:

    • develop
    • feature-*

Validating type: pipeline rules

  • On the group level, navigate to Security and Compliance > Policies and create the following scan execution policy:

    type: scan_execution_policy
    name: Pipeline / Default Branch / Container Scan
    description: ''
    enabled: true
    rules:
      - type: pipeline
        branch_type: default
    actions:
      - scan: container_scanning
        variables:
          CS_IMAGE: "nginx:1"
  • On the project level, navigate to Security and Compliance > Policies and create the following scan execution policies:

    type: scan_execution_policy
    name: Pipeline / Protected Branches / Secret Detection
    description: ''
    enabled: true
    rules:
      - type: pipeline
        branch_type: protected
    actions:
      - scan: secret_detection
    type: scan_execution_policy
    name: Pipeline / All Branches / Dependency Scanning
    description: ''
    enabled: true
    rules:
      - type: pipeline
        branch_type: all
    actions:
      - scan: dependency_scanning
  • Navigate to CI/CD > Pipelines, run pipelines for the following branches and verify their jobs:

    Pipeline branch Jobs
    main dummy_job, container-scanning-0, secret-detection-1, gemnasium-dependency-scanning-2
    develop dummy_job, secret-detection-0, gemnasium-dependency-scanning-1
    feature-1 dummy_job, secret-detection-0, gemnasium-dependency-scanning-1
    legacy dummy_job, gemnasium-dependency-scanning-0

Validating type: schedule rules

  • On the group or project level, navigate to Security and Compliance > Policies and create the following scan execution policies:

    type: scan_execution_policy
    name: Scheduled / Protected Branches / DAST
    description: ''
    enabled: true
    rules:
      - type: schedule
        cadence: "0 0 * * *"
        branch_type: protected
    actions:
      - scan: dast
        site_profile: nonexistent
        scanner_profile: nonexistent
    type: scan_execution_policy
    name: Scheduled / Default Branch / Container Scanning
    description: ''
    enabled: true
    rules:
      - type: schedule
        cadence: "0 0 * * *"
        branch_type: default
    actions:
      - scan: container_scanning
  • Clear the previously created pipelines from with Project.find(ID).all_pipelines.destroy_all.

  • Create run.rb with the following contents:

    PROJECT = Project.find(-1) # replace
    
    configs = PROJECT.all_security_orchestration_policy_configurations
    schedules = Security::OrchestrationPolicyRuleSchedule.where(security_orchestration_policy_configuration_id: configs)
    
    schedules.each do |schedule|
      Security::SecurityOrchestrationPolicies::RuleScheduleService
        .new(container: schedule.security_orchestration_policy_configuration.project, current_user: User.first)
        .execute(schedule)
    end
  • Execute it with bin/rails runner run.rb

  • Navigate to CI/CD > Pipelines and confirm the following (job, branches) pipeline combinations were created:

    Job Branches
    container-scanning-0 main
    dast-on-demand-0 main, develop, feature-1, feature-2

Other things to try

Validate policies with wildcard branches

  • Add the following scan execution policy:

    type: scan_execution_policy
    name: Pipeline / Wildcard Branch / Container Scanning
    description: ''
    enabled: true
    rules:
      - type: pipeline
        branches: ["leg*"]
    actions:
      - scan: container_scanning
        variables:
          CS_IMAGE: "nginx:1"
  • Navigate to CI/CD > Pipelines, run a pipeline for the legacy branch and verify its jobs:

    • dummy_job
    • container-scanning-1
    • gemnasium-dependency-scanning-0

Validate scan result policies

  • Create the following scan execution policy:

    type: scan_result_policy
    name: Scan Result Policy
    description: ''
    enabled: true
    rules:
      - type: scan_finding
        branches: []
        scanners:
          - container_scanning
        vulnerabilities_allowed: 0
        severity_levels: []
        vulnerability_states:
          - new_needs_triage
    actions:
      - type: require_approval
        approvals_required: 1
        user_approvers_ids:
          - 1
  • Add Container Scanning to .gitlab-ci.yml on the develop branch:

    dummy_job:
      script:
        - exit 0
    
    include:
      - template: Security/Container-Scanning.gitlab-ci.yml
  • Open a new Merge Request targeting develop and confirm the Scan Result Policy approval rule applies.

Disabling the feature

Validating type: pipeline rules
  • Ensure the Pipeline / Wildcard Branch / Container Scanning policy from above exists.

  • Disable the feature:

    Feature.disable(:security_policies_branch_type, Project.find(ID)
  • Navigate to CI/CD > Pipelines, run a pipeline for the legacy branch and verify its jobs:

    • dummy_job
    • container-scanning-0
Validating type: schedule rules
  • Ensure you don't have more than 4 scan execution policies, as 5 is the limit per configuration.

  • Create the following scan execution policy:

    name: Scheduled / Wildcard Branch / Container Scanning
    description: ''
    enabled: true
    actions:
    - scan: container_scanning
      tags: []
    rules:
    - type: schedule
      cadence: 0 0 * * *
      branches:
      - leg*
  • Execute bin/rails runner run.rb

  • Verify the container-scanning-0 is the only job in the pipeline.

MR acceptance checklist

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

Related to #404774 (closed)

Edited by Dominic Bauer

Merge request reports