Skip to content

Commit ef0a27d

Browse files
nikpivkinsimar7
andauthored
feat(misconf): add ability to disable checks by ID (#7536)
Signed-off-by: nikpivkin <[email protected]> Co-authored-by: Simar <[email protected]>
1 parent ea0cf03 commit ef0a27d

File tree

4 files changed

+110
-6
lines changed

4 files changed

+110
-6
lines changed

pkg/iac/rego/load.go

+6
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,12 @@ func (s *Scanner) filterModules(retriever *MetadataRetriever) error {
295295
continue
296296
}
297297

298+
if IsBuiltinNamespace(getModuleNamespace(module)) {
299+
if _, disabled := s.disabledCheckIDs[meta.ID]; disabled { // ignore builtin disabled checks
300+
continue
301+
}
302+
}
303+
298304
if len(meta.InputOptions.Selectors) == 0 {
299305
s.logger.Warn(
300306
"Module has no input selectors - it will be loaded for all inputs!",

pkg/iac/rego/options.go

+11
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,14 @@ func WithCustomSchemas(schemas map[string][]byte) options.ScannerOption {
106106
}
107107
}
108108
}
109+
110+
// WithDisabledCheckIDs disables checks by their ID (ID field in metadata)
111+
func WithDisabledCheckIDs(ids ...string) options.ScannerOption {
112+
return func(s options.ConfigurableScanner) {
113+
if ss, ok := s.(*Scanner); ok {
114+
for _, id := range ids {
115+
ss.disabledCheckIDs[id] = struct{}{}
116+
}
117+
}
118+
}
119+
}

pkg/iac/rego/scanner.go

+9-6
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ type Scanner struct {
6969
embeddedLibs map[string]*ast.Module
7070
embeddedChecks map[string]*ast.Module
7171
customSchemas map[string][]byte
72+
73+
disabledCheckIDs map[string]struct{}
7274
}
7375

7476
func (s *Scanner) SetIncludeDeprecatedChecks(b bool) {
@@ -109,12 +111,13 @@ func NewScanner(source types.Source, opts ...options.ScannerOption) *Scanner {
109111
}
110112

111113
s := &Scanner{
112-
regoErrorLimit: ast.CompileErrorLimitDefault,
113-
sourceType: source,
114-
ruleNamespaces: make(map[string]struct{}),
115-
runtimeValues: addRuntimeValues(),
116-
logger: log.WithPrefix("rego"),
117-
customSchemas: make(map[string][]byte),
114+
regoErrorLimit: ast.CompileErrorLimitDefault,
115+
sourceType: source,
116+
ruleNamespaces: make(map[string]struct{}),
117+
runtimeValues: addRuntimeValues(),
118+
logger: log.WithPrefix("rego"),
119+
customSchemas: make(map[string][]byte),
120+
disabledCheckIDs: make(map[string]struct{}),
118121
}
119122

120123
maps.Copy(s.ruleNamespaces, builtinNamespaces)

pkg/iac/rego/scanner_test.go

+84
Original file line numberDiff line numberDiff line change
@@ -1153,3 +1153,87 @@ deny {
11531153
})
11541154
}
11551155
}
1156+
1157+
func Test_RegoScanner_WithDisabledCheckIDs(t *testing.T) {
1158+
1159+
check := `# METADATA
1160+
# custom:
1161+
# id: TEST-001
1162+
# avd_id: AVD-TEST-001
1163+
# severity: LOW
1164+
# provider: aws
1165+
# service: s3
1166+
# short_code: test
1167+
package builtin.test
1168+
1169+
deny {
1170+
true
1171+
}
1172+
`
1173+
1174+
tests := []struct {
1175+
name string
1176+
disabledChecks []string
1177+
inputCheck string
1178+
expected bool
1179+
}{
1180+
{
1181+
name: "no disabled checks",
1182+
expected: true,
1183+
inputCheck: check,
1184+
},
1185+
{
1186+
name: "disable check by ID",
1187+
disabledChecks: []string{"TEST-001"},
1188+
inputCheck: check,
1189+
},
1190+
{
1191+
name: "disabling a non-existent check",
1192+
disabledChecks: []string{"FOO"},
1193+
expected: true,
1194+
inputCheck: check,
1195+
},
1196+
{
1197+
name: "one of the identifiers does not exist",
1198+
disabledChecks: []string{"FOO", "TEST-001"},
1199+
inputCheck: check,
1200+
},
1201+
{
1202+
name: "do not disable user checks with builtin IDs",
1203+
inputCheck: `# METADATA
1204+
# custom:
1205+
# id: TEST-001
1206+
# avd_id: AVD-TEST-001
1207+
# severity: LOW
1208+
# provider: aws
1209+
# service: s3
1210+
# short_code: test
1211+
package user.test
1212+
1213+
deny {
1214+
true
1215+
}
1216+
`,
1217+
disabledChecks: []string{"TEST-001"},
1218+
expected: true,
1219+
},
1220+
}
1221+
1222+
for _, tt := range tests {
1223+
t.Run(tt.name, func(t *testing.T) {
1224+
1225+
scanner := rego.NewScanner(
1226+
types.SourceYAML,
1227+
rego.WithPolicyReader(strings.NewReader(tt.inputCheck)),
1228+
rego.WithDisabledCheckIDs(tt.disabledChecks...),
1229+
rego.WithPolicyNamespaces("user"),
1230+
)
1231+
1232+
require.NoError(t, scanner.LoadPolicies(nil))
1233+
results, err := scanner.ScanInput(context.TODO(), rego.Input{})
1234+
require.NoError(t, err)
1235+
1236+
require.Equal(t, tt.expected, len(results.GetFailed()) > 0)
1237+
})
1238+
}
1239+
}

0 commit comments

Comments
 (0)