Commit 8165db74 authored by Markus Koller's avatar Markus Koller

Merge branch 'limit-policy-to-file' into 'master'

Limit security policy to a file

See merge request gitlab-org/gitlab!57736
parents a1519664 b7e3049d
......@@ -6,7 +6,8 @@ module Security
self.table_name = 'security_orchestration_policy_configurations'
POLICIES_BASE_PATH = '.gitlab/security-policies/'
POLICY_PATH = '.gitlab/security-policies/policy.yml'
POLICY_LIMIT = 5
ON_DEMAND_SCANS = %w[dast].freeze
......@@ -23,12 +24,7 @@ module Security
def active_policies
return [] unless enabled?
security_policy_management_project
.repository
.ls_files(security_policy_management_project.default_branch_or_master)
.grep(/\A#{Regexp.escape(POLICIES_BASE_PATH)}.+\.(yml|yaml)\z/)
.map { |path| policy_at(path) }
.select { |config| config[:enabled] }
scan_execution_policy_at(POLICY_PATH).select { |config| config[:enabled] }.first(POLICY_LIMIT)
end
def on_demand_scan_actions(branch)
......@@ -48,6 +44,14 @@ module Security
private
def policy_repo
security_policy_management_project.repository
end
def default_branch_or_master
security_policy_management_project.default_branch_or_master
end
def active_policy_names_with_dast_profiles
strong_memoize(:active_policy_names_with_dast_profiles) do
profiles = { site_profiles: Hash.new { Set.new }, scanner_profiles: Hash.new { Set.new } }
......@@ -65,11 +69,9 @@ module Security
end
end
def policy_at(path)
security_policy_management_project
.repository
.blob_data_at(security_policy_management_project.default_branch_or_master, path)
.then { |config| Gitlab::Config::Loader::Yaml.new(config).load! }
def scan_execution_policy_at(path)
policy_repo.blob_data_at(default_branch_or_master, path)
.then { |config| Gitlab::Config::Loader::Yaml.new(config).load!.fetch(:scan_execution_policy, []) }
end
def applicable_for_branch?(policy, ref)
......
scan_execution_policy:
- name: Run DAST in every pipeline
description: This policy enforces to run DAST for every pipeline within the project
enabled: true
rules:
- type: pipeline
branches:
- "production"
actions:
- scan: dast
site_profile: Site Profile
scanner_profile: Scanner Profile
- name: Run DAST in every pipeline_v1
description: This policy enforces to run DAST for every pipeline within the project
enabled: true
rules:
- type: pipeline
branches:
- "master"
actions:
- scan: dast
site_profile: Site Profile
scanner_profile: Scanner Profile
- name: Disabled policy
description: This policy is disabled
enabled: false
rules: []
actions: []
- name: Disabled policy_v2
description: This policy is disabled v2
enabled: false
rules: []
actions: []
- name: Run DAST in every pipeline_v3
description: This policy enforces to run DAST for every pipeline within the project
enabled: true
rules:
- type: pipeline
branches:
- "master"
actions:
- scan: dast
site_profile: Site Profile
scanner_profile: Scanner Profile
- name: Run DAST in every pipeline_v4
description: This policy enforces to run DAST for every pipeline within the project
enabled: true
rules:
- type: pipeline
branches:
- "master"
actions:
- scan: dast
site_profile: Site Profile
scanner_profile: Scanner Profile
- name: Run DAST in every pipeline_v5
description: This policy enforces to run DAST for every pipeline within the project
enabled: true
rules:
- type: pipeline
branches:
- "master"
actions:
- scan: dast
site_profile: Site Profile
scanner_profile: Scanner Profile
- name: Run DAST in every pipeline_v6
description: This policy enforces to run DAST for every pipeline within the project
enabled: true
rules:
- type: pipeline
branches:
- "master"
actions:
- scan: dast
site_profile: Site Profile
scanner_profile: Scanner Profile
\ No newline at end of file
......@@ -4,7 +4,9 @@ require 'spec_helper'
RSpec.describe Security::OrchestrationPolicyConfiguration do
let_it_be(:security_policy_management_project) { create(:project, :repository) }
let_it_be(:security_orchestration_policy_configuration) { create(:security_orchestration_policy_configuration, security_policy_management_project: security_policy_management_project) }
let_it_be(:security_orchestration_policy_configuration) do
create( :security_orchestration_policy_configuration, security_policy_management_project: security_policy_management_project)
end
let(:default_branch) { security_policy_management_project.default_branch_or_master }
let(:repository) { instance_double(Repository, root_ref: 'master') }
......@@ -57,26 +59,54 @@ RSpec.describe Security::OrchestrationPolicyConfiguration do
EOS
end
let(:disabled_policy_yaml) do
<<-EOS
type: scan_execution_policy
name: Disabled policy
description: This policy is disabled
enabled: false
rules: []
actions: []
EOS
end
let(:policy_yaml) { fixture_file('security_orchestration.yml', dir: 'ee') }
let(:expected_active_policies) do
[
{
type: 'scan_execution_policy',
name: 'Run DAST in every pipeline',
description: 'This policy enforces to run DAST for every pipeline within the project',
enabled: true,
rules: [{ type: 'pipeline', branches: ['production'] }],
actions: [{ scan: 'dast', site_profile: 'Site Profile', scanner_profile: 'Scanner Profile' }]
rules: [{ type: 'pipeline', branches: %w[production] }],
actions: [
{ scan: 'dast', site_profile: 'Site Profile', scanner_profile: 'Scanner Profile' }
]
},
{
name: 'Run DAST in every pipeline_v1',
description: 'This policy enforces to run DAST for every pipeline within the project',
enabled: true,
rules: [{ type: 'pipeline', branches: %w[master] }],
actions: [
{ scan: 'dast', site_profile: 'Site Profile', scanner_profile: 'Scanner Profile' }
]
},
{
name: 'Run DAST in every pipeline_v3',
description: 'This policy enforces to run DAST for every pipeline within the project',
enabled: true,
rules: [{ type: 'pipeline', branches: %w[master] }],
actions: [
{ scan: 'dast', site_profile: 'Site Profile', scanner_profile: 'Scanner Profile' }
]
},
{
name: 'Run DAST in every pipeline_v4',
description: 'This policy enforces to run DAST for every pipeline within the project',
enabled: true,
rules: [{ type: 'pipeline', branches: %w[master] }],
actions: [
{ scan: 'dast', site_profile: 'Site Profile', scanner_profile: 'Scanner Profile' }
]
},
{
name: 'Run DAST in every pipeline_v5',
description: 'This policy enforces to run DAST for every pipeline within the project',
enabled: true,
rules: [{ type: 'pipeline', branches: %w[master] }],
actions: [
{ scan: 'dast', site_profile: 'Site Profile', scanner_profile: 'Scanner Profile' }
]
}
]
end
......@@ -85,17 +115,7 @@ RSpec.describe Security::OrchestrationPolicyConfiguration do
before do
allow(security_policy_management_project).to receive(:repository).and_return(repository)
allow(repository).to receive(:ls_files).and_return(['README.md', '.gitlab/security-policies/enforce-dast.yml', '.gitlab/security-policies/disabled-policy.yml', '.gitlab-ci.yml'])
allow(repository).to receive(:blob_data_at).with(default_branch, '.gitlab/security-policies/enforce-dast.yml').and_return(enforce_dast_yaml)
allow(repository).to receive(:blob_data_at).with(default_branch, '.gitlab/security-policies/disabled-policy.yml').and_return(disabled_policy_yaml)
end
it 'reads yml file from repository' do
expect(repository).to receive(:ls_files).with(default_branch)
expect(repository).to receive(:blob_data_at).with(default_branch, '.gitlab/security-policies/enforce-dast.yml')
expect(repository).to receive(:blob_data_at).with(default_branch, '.gitlab/security-policies/disabled-policy.yml')
active_policies
allow(repository).to receive(:blob_data_at).with( default_branch, Security::OrchestrationPolicyConfiguration::POLICY_PATH).and_return(policy_yaml)
end
it 'returns only enabled policies' do
......@@ -114,65 +134,47 @@ RSpec.describe Security::OrchestrationPolicyConfiguration do
end
describe '#on_demand_scan_actions' do
let(:policy_1_yaml) do
<<-EOS
type: scan_execution_policy
name: Run DAST in every pipeline
enabled: true
rules:
- type: pipeline
branches:
- "production"
actions:
- scan: dast
site_profile: Site Profile
scanner_profile: Scanner Profile
EOS
end
let(:policy_2_yaml) do
let(:policy_yaml) do
<<-EOS
type: scan_execution_policy
name: Run DAST in every pipeline
enabled: true
rules:
- type: pipeline
branches:
- "release/*"
actions:
- scan: dast
site_profile: Site Profile 2
scanner_profile: Scanner Profile 2
EOS
end
let(:policy_3_yaml) do
<<-EOS
type: scan_execution_policy
name: Run DAST in every pipeline
enabled: true
rules:
- type: pipeline
branches:
- "*"
actions:
- scan: dast
site_profile: Site Profile 3
scanner_profile: Scanner Profile 3
EOS
end
let(:policy_4_yaml) do
<<-EOS
type: scan_execution_policy
name: Run SAST in every pipeline
enabled: true
rules:
- type: pipeline
branches:
- "release/*"
actions:
- scan: sast
scan_execution_policy:
- name: Run DAST in every pipeline
enabled: true
rules:
- type: pipeline
branches:
- "production"
actions:
- scan: dast
site_profile: Site Profile
scanner_profile: Scanner Profile
- name: Run DAST in every pipeline
enabled: true
rules:
- type: pipeline
branches:
- "release/*"
actions:
- scan: dast
site_profile: Site Profile 2
scanner_profile: Scanner Profile 2
- name: Run DAST in every pipeline
enabled: true
rules:
- type: pipeline
branches:
- "*"
actions:
- scan: dast
site_profile: Site Profile 3
scanner_profile: Scanner Profile 3
- name: Run SAST in every pipeline
enabled: true
rules:
- type: pipeline
branches:
- "release/*"
actions:
- scan: sast
EOS
end
......@@ -183,15 +185,13 @@ RSpec.describe Security::OrchestrationPolicyConfiguration do
]
end
subject(:on_demand_scan_actions) { security_orchestration_policy_configuration.on_demand_scan_actions('release/123') }
subject(:on_demand_scan_actions) do
security_orchestration_policy_configuration.on_demand_scan_actions('release/123')
end
before do
allow(security_policy_management_project).to receive(:repository).and_return(repository)
allow(repository).to receive(:ls_files).and_return(['.gitlab/security-policies/policy-1.yml', '.gitlab/security-policies/policy-2.yml', '.gitlab/security-policies/policy-3.yml', '.gitlab/security-policies/policy-4.yml'])
allow(repository).to receive(:blob_data_at).with(default_branch, '.gitlab/security-policies/policy-1.yml').and_return(policy_1_yaml)
allow(repository).to receive(:blob_data_at).with(default_branch, '.gitlab/security-policies/policy-2.yml').and_return(policy_2_yaml)
allow(repository).to receive(:blob_data_at).with(default_branch, '.gitlab/security-policies/policy-3.yml').and_return(policy_3_yaml)
allow(repository).to receive(:blob_data_at).with(default_branch, '.gitlab/security-policies/policy-4.yml').and_return(policy_4_yaml)
allow(repository).to receive(:blob_data_at).with(default_branch, Security::OrchestrationPolicyConfiguration::POLICY_PATH).and_return(policy_yaml)
end
it 'returns only actions for on-demand scans applicable for branch' do
......@@ -200,62 +200,61 @@ RSpec.describe Security::OrchestrationPolicyConfiguration do
end
describe '#active_policy_names_with_dast_site_profile' do
let(:enforce_dast_yaml) do
let(:policy_yaml) do
<<-EOS
type: scan_execution_policy
name: Run DAST in every pipeline
description: This policy enforces to run DAST for every pipeline within the project
enabled: true
rules:
- type: pipeline
branches:
- "production"
actions:
- scan: dast
site_profile: Site Profile
scanner_profile: Scanner Profile
- scan: dast
site_profile: Site Profile
scanner_profile: Scanner Profile 2
scan_execution_policy:
- name: Run DAST in every pipeline
description: This policy enforces to run DAST for every pipeline within the project
enabled: true
rules:
- type: pipeline
branches:
- "production"
actions:
- scan: dast
site_profile: Site Profile
scanner_profile: Scanner Profile
- scan: dast
site_profile: Site Profile
scanner_profile: Scanner Profile 2
EOS
end
before do
allow(security_policy_management_project).to receive(:repository).and_return(repository)
allow(repository).to receive(:ls_files).and_return(['.gitlab/security-policies/enforce-dast.yml'])
allow(repository).to receive(:blob_data_at).with(default_branch, '.gitlab/security-policies/enforce-dast.yml').and_return(enforce_dast_yaml)
allow(repository).to receive(:blob_data_at).with(default_branch, Security::OrchestrationPolicyConfiguration::POLICY_PATH).and_return(policy_yaml)
end
it 'returns list of policy names where site profile is referenced' do
expect(security_orchestration_policy_configuration.active_policy_names_with_dast_site_profile('Site Profile')).to contain_exactly('Run DAST in every pipeline')
expect( security_orchestration_policy_configuration.active_policy_names_with_dast_site_profile('Site Profile')).to contain_exactly('Run DAST in every pipeline')
end
end
describe '#active_policy_names_with_dast_scanner_profile' do
let(:enforce_dast_yaml) do
<<-EOS
type: scan_execution_policy
name: Run DAST in every pipeline
description: This policy enforces to run DAST for every pipeline within the project
enabled: true
rules:
- type: pipeline
branches:
- "production"
actions:
- scan: dast
site_profile: Site Profile
scanner_profile: Scanner Profile
- scan: dast
site_profile: Site Profile 2
scanner_profile: Scanner Profile
scan_execution_policy:
type: scan_execution_policy
- name: Run DAST in every pipeline
description: This policy enforces to run DAST for every pipeline within the project
enabled: true
rules:
- type: pipeline
branches:
- "production"
actions:
- scan: dast
site_profile: Site Profile
scanner_profile: Scanner Profile
- scan: dast
site_profile: Site Profile 2
scanner_profile: Scanner Profile
EOS
end
before do
allow(security_policy_management_project).to receive(:repository).and_return(repository)
allow(repository).to receive(:ls_files).and_return(['.gitlab/security-policies/enforce-dast.yml'])
allow(repository).to receive(:blob_data_at).with(default_branch, '.gitlab/security-policies/enforce-dast.yml').and_return(enforce_dast_yaml)
allow(repository).to receive(:blob_data_at).with(default_branch, Security::OrchestrationPolicyConfiguration::POLICY_PATH).and_return(enforce_dast_yaml)
end
it 'returns list of policy names where site profile is referenced' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment