Backfill security policies table from YAML
What does this MR do and why?
The security policies are stored as YAML files in the security policy project. This approach has a lot of advantages (like version control for policies using git, auditable etc), it faces some performance drawbacks. To improve this we are storing security policy data in the security_policies table. This MR adds a migration to backfill data reading from .gitlab/security-policies/policy.yml files.
- It iterates through each rows of
security_orchestration_policy_configurations - read the policy YAML from gitaly
- validates the policy if it matches the schema
- for each policy type and policy, persist the policy to
security_policiestable - It iterate through the
rulesof policy with typesapproval_policy,scan_execution_policy,vulnerability_management_policyand persist the rules toapproval_policy_rules,scan_execution_policy_rules&vulnerability_management_policy_rulescorrespondingly - If the security_orchestration_policy_configuration is mapped to a namepsace, get all projects in the namespace, and for each project check the policy_scope similar to
Security::SecurityOrchestrationPolicies::PolicyScopeCheckerand create entries insecurity_policy_project_links&approval_policy_rule_project_links
Database
We usually isolate background migrations from the rest of the application. In this MR there are two exceptions:
- Use
ee/app/validators/json_schemas/security_orchestration_policy.jsonto validate the security policy schema. We take care not to introduce breaking changes outside of major milestones so I think it is okay to validate against this schema. -
::Gitlab::Gitclasses. We have to access git to load yaml files from repositories. Those classes are a core part of GitLab. Copying this to the background migration will make it significantly larger. Also, we will have to rely on gitaly eventually, so there is still an external dependency.
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
How to setup locally?
- Create a group (
read-model-migration) and create multiple sub-groups and projects - Disable
security_policies_sync_groupfeature flag (Feature.disable(:security_policies_sync_group)) - Create a project (
read-model-migration/read-model-migration-security-policy-project) within the group and create.gitlab/security-policies/policy.ymlfile with:
---
approval_policy:
- name: MRAP - Security Scan
description: ''
enabled: true
policy_scope:
projects:
excluding: []
rules:
- type: scan_finding
scanners: []
vulnerabilities_allowed: 0
severity_levels: []
vulnerability_states: []
branch_type: protected
actions:
- type: require_approval
approvals_required: 1
role_approvers:
- developer
- type: send_bot_message
enabled: true
approval_settings:
block_branch_modification: true
block_group_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: open
- name: MRAP - License Scan
description: ''
enabled: true
policy_scope:
projects:
excluding: []
rules:
- type: license_finding
match_on_inclusion_license: true
license_types:
- Apple MIT License
license_states:
- newly_detected
branch_type: protected
actions:
- type: require_approval
approvals_required: 1
role_approvers:
- developer
- type: send_bot_message
enabled: true
approval_settings:
block_branch_modification: true
block_group_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: open
- name: MRAP - any_merge_request
description: ''
enabled: true
policy_scope:
projects:
excluding: []
rules:
- type: any_merge_request
branch_type: protected
commits: unsigned
actions:
- type: require_approval
approvals_required: 1
role_approvers:
- developer
- type: send_bot_message
enabled: true
approval_settings:
block_branch_modification: true
block_group_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: open
scan_execution_policy:
- name: SEP - Pipeline
description: ''
enabled: true
policy_scope:
projects:
excluding: []
rules:
- type: pipeline
branches:
- "*"
actions:
- scan: secret_detection
- name: SEP - Schedule
description: ''
enabled: true
policy_scope:
projects:
excluding: []
rules:
- type: schedule
cadence: 0 0 * * *
branch_type: default
actions:
- scan: secret_detection
pipeline_execution_policy:
- name: PEP - Inject
description: ''
enabled: true
pipeline_config_strategy: inject_ci
content:
include:
- project: read-model-migration/read-model-migration-security-policy-project
file: basic.yml
vulnerability_management_policy:
- name: Vulnerability management policy
description: ''
enabled: true
rules:
- type: no_longer_detected
scanners: []
severity_levels:
- critical
- high
actions:
- type: auto_resolve
- Create
basic.yml(used by the pipeline execution policy) in the policy project with:
stages:
- .pipeline-policy-pre
- build
- custom
- test
- .pipeline-policy-post
compliance-job:
stage: .pipeline-policy-pre
script:
- echo "Compliance"
policy build job:
stage: build
script:
- echo "Build"
policy test job:
stage: test
script:
- echo "Test"
policy custom job:
stage: custom
script:
- echo "Custom"
duplicate-job:
stage: test
script:
- echo "Duplicate job"
- Assign this project as the security policy project by going to
Secure -> Policies -> Edit Policy Projectand select the created project - Execute the migration by doing
bundle exec rake db:migrate - Verify that the policies are created by doing:
Security::Policy.all.map(&:name)
Security::Policy.all.map(&:projects)
Security::ApprovalPolicyRule.all
Security::ApprovalPolicyRule.all.map(&:projects)
Security::ScanExecutionPolicyRule.all
Security::VulnerabilityManagementPolicyRule.all
Addresses #464033 (closed)
Edited by Sashi Kumar Kumaresan