-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathloader.go
More file actions
135 lines (118 loc) · 3.4 KB
/
loader.go
File metadata and controls
135 lines (118 loc) · 3.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package config
import (
"fmt"
"os"
"gopkg.in/yaml.v3"
)
// SecurityConfig represents the security-config.yml structure
type SecurityConfig struct {
Version string `yaml:"version"`
Language string `yaml:"language"`
Framework string `yaml:"framework"`
SeverityThreshold string `yaml:"severity_threshold"`
Tools ToolsConfig `yaml:"tools"`
ExcludePaths []string `yaml:"exclude_paths"`
FailOn map[string]int `yaml:"fail_on"`
Licenses LicensesConfig `yaml:"licenses"`
Notifications NotificationsConfig `yaml:"notifications"`
}
// ToolsConfig represents the tools section
type ToolsConfig struct {
Semgrep bool `yaml:"semgrep"`
Trivy bool `yaml:"trivy"`
Gitleaks bool `yaml:"gitleaks"`
}
// LicensesConfig represents the licenses section
type LicensesConfig struct {
Enabled bool `yaml:"enabled"`
Deny []string `yaml:"deny"`
Allow []string `yaml:"allow"`
}
// NotificationsConfig represents the notifications section
type NotificationsConfig struct {
PRComment bool `yaml:"pr_comment"`
Slack bool `yaml:"slack"`
Email bool `yaml:"email"`
}
// LoadConfig loads and parses security-config.yml
func LoadConfig(configPath string) (*SecurityConfig, error) {
// Check if file exists
_, err := os.Stat(configPath)
if err != nil {
if os.IsNotExist(err) {
// Return default config if file doesn't exist
return getDefaultConfig(), nil
}
return nil, fmt.Errorf("failed to stat config file: %w", err)
}
// Read file
data, err := os.ReadFile(configPath)
if err != nil {
return nil, fmt.Errorf("failed to read config file: %w", err)
}
// Parse YAML
config := &SecurityConfig{}
if err := yaml.Unmarshal(data, config); err != nil {
return nil, fmt.Errorf("failed to parse YAML config: %w", err)
}
// Set defaults for unset values
setConfigDefaults(config)
return config, nil
}
// getDefaultConfig returns the default configuration
func getDefaultConfig() *SecurityConfig {
return &SecurityConfig{
Version: "0.3.0",
SeverityThreshold: "high",
Tools: ToolsConfig{
Semgrep: true,
Gitleaks: true,
Trivy: true,
},
ExcludePaths: []string{},
FailOn: map[string]int{
"gitleaks": 0,
"semgrep": 10,
"trivy_critical": 0,
"trivy_high": 5,
"trivy_medium": -1,
"trivy_low": -1,
},
Notifications: NotificationsConfig{
PRComment: true,
Slack: false,
Email: false,
},
}
}
// setConfigDefaults fills in missing values with sensible defaults
func setConfigDefaults(config *SecurityConfig) {
// Ensure FailOn map exists and has all keys
if config.FailOn == nil {
config.FailOn = make(map[string]int)
}
defaults := map[string]int{
"gitleaks": 0,
"semgrep": 10,
"trivy_critical": 0,
"trivy_high": 5,
"trivy_medium": -1,
"trivy_low": -1,
"license_violations": -1,
}
for key, defaultValue := range defaults {
if _, exists := config.FailOn[key]; !exists {
config.FailOn[key] = defaultValue
}
}
// Set default threshold if not specified
if config.SeverityThreshold == "" {
config.SeverityThreshold = "high"
}
// Set default tools if all are false
if !config.Tools.Semgrep && !config.Tools.Gitleaks && !config.Tools.Trivy {
config.Tools.Semgrep = true
config.Tools.Gitleaks = true
config.Tools.Trivy = true
}
}