diff --git a/README_CHECKS.md b/README_CHECKS.md index 4aca968c..12486559 100644 --- a/README_CHECKS.md +++ b/README_CHECKS.md @@ -14,10 +14,10 @@ | pod-networkpolicy | Pod | Makes sure that all Pods are targeted by a NetworkPolicy | default | | networkpolicy-targets-pod | NetworkPolicy | Makes sure that all NetworkPolicies targets at least one Pod | default | | pod-probes | Pod | Makes sure that all Pods have safe probe configurations | default | -| container-security-context | Pod | Makes sure that all pods have good securityContexts configured | default | -| container-security-context-user-group-id | Pod | Makes sure that all pods have a security context with valid UID and GID set | optional | -| container-security-context-privileged | Pod | Makes sure that all pods have a unprivileged security context set | optional | -| container-security-context-readonlyrootfilesystem | Pod | Makes sure that all pods have a security context with read only filesystem set | optional | +| container-security-context | Pod | Makes sure that all pods have good securityContexts configured | optional | +| container-security-context-user-group-id | Pod | Makes sure that all pods have a security context with valid UID and GID set | default | +| container-security-context-privileged | Pod | Makes sure that all pods have a unprivileged security context set | default | +| container-security-context-readonlyrootfilesystem | Pod | Makes sure that all pods have a security context with read only filesystem set | default | | container-seccomp-profile | Pod | Makes sure that all pods have at a seccomp policy configured. | optional | | service-targets-pod | Service | Makes sure that all Services targets a Pod | default | | service-type | Service | Makes sure that the Service type is not NodePort | default | @@ -25,6 +25,8 @@ | deployment-has-host-podantiaffinity | Deployment | Makes sure that a podAntiAffinity has been set that prevents multiple pods from being scheduled on the same node. https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ | default | | statefulset-has-host-podantiaffinity | StatefulSet | Makes sure that a podAntiAffinity has been set that prevents multiple pods from being scheduled on the same node. https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ | default | | deployment-targeted-by-hpa-does-not-have-replicas-configured | Deployment | Makes sure that Deployments using a HorizontalPodAutoscaler doesn't have a statically configured replica count set | default | -| statefulset-has-servicename | StatefulSet | Makes sure that StatefulSets have a existing headless serviceName. | default | +| statefulset-has-servicename | StatefulSet | Makes sure that StatefulSets have an existing headless serviceName. | default | +| deployment-pod-selector-labels-match-template-metadata-labels | Deployment | Ensure the StatefulSet selector labels match the template metadata labels. | default | +| statefulset-pod-selector-labels-match-template-metadata-labels | StatefulSet | Ensure the StatefulSet selector labels match the template metadata labels. | default | | label-values | all | Validates label values | default | | horizontalpodautoscaler-has-target | HorizontalPodAutoscaler | Makes sure that the HPA targets a valid object | default | diff --git a/score/score_test.go b/score/score_test.go index c63bf220..21fe0fa7 100644 --- a/score/score_test.go +++ b/score/score_test.go @@ -61,17 +61,6 @@ func testExpectedScore(t *testing.T, filename string, testcase string, expectedS }, testcase, expectedScore) } -func testExpectedScoreReader(t *testing.T, content io.Reader, testcase string, expectedScore scorecard.Grade) []scorecard.TestScoreComment { - return testExpectedScoreWithConfig( - t, config.Configuration{ - AllFiles: []ks.NamedReader{unnamedReader{content}}, - KubernetesVersion: config.Semver{1, 18}, - }, - testcase, - expectedScore, - ) -} - type unnamedReader struct { io.Reader } diff --git a/score/security/security.go b/score/security/security.go index 6917c5d8..0195d090 100644 --- a/score/security/security.go +++ b/score/security/security.go @@ -9,11 +9,11 @@ import ( ) func Register(allChecks *checks.Checks) { - allChecks.RegisterPodCheck("Container Security Context", `Makes sure that all pods have good securityContexts configured`, containerSecurityContext) + allChecks.RegisterOptionalPodCheck("Container Security Context", `Makes sure that all pods have good securityContexts configured`, containerSecurityContext) - allChecks.RegisterOptionalPodCheck("Container Security Context User Group ID", `Makes sure that all pods have a security context with valid UID and GID set `, containerSecurityContextUserGroupID) - allChecks.RegisterOptionalPodCheck("Container Security Context Privileged", "Makes sure that all pods have a unprivileged security context set", containerSecurityContextPrivileged) - allChecks.RegisterOptionalPodCheck("Container Security Context ReadOnlyRootFilesystem", "Makes sure that all pods have a security context with read only filesystem set", containerSecurityContextReadOnlyRootFilesystem) + allChecks.RegisterPodCheck("Container Security Context User Group ID", `Makes sure that all pods have a security context with valid UID and GID set `, containerSecurityContextUserGroupID) + allChecks.RegisterPodCheck("Container Security Context Privileged", "Makes sure that all pods have a unprivileged security context set", containerSecurityContextPrivileged) + allChecks.RegisterPodCheck("Container Security Context ReadOnlyRootFilesystem", "Makes sure that all pods have a security context with read only filesystem set", containerSecurityContextReadOnlyRootFilesystem) allChecks.RegisterOptionalPodCheck("Container Seccomp Profile", `Makes sure that all pods have at a seccomp policy configured.`, podSeccompProfile) } diff --git a/score/security_test.go b/score/security_test.go index efbc1da8..7295dec8 100644 --- a/score/security_test.go +++ b/score/security_test.go @@ -215,7 +215,19 @@ func TestPodSecurityContext(test *testing.T) { output, err := yaml.Marshal(s) assert.Nil(test, err, "caseID=%d", caseID) - comments := testExpectedScoreReader(test, bytes.NewReader(output), "Container Security Context", tc.expectedGrade) + comments := testExpectedScoreWithConfig( + test, config.Configuration{ + AllFiles: []ks.NamedReader{unnamedReader{bytes.NewReader(output)}}, + KubernetesVersion: config.Semver{1, 18}, + EnabledOptionalTests: map[string]struct{}{ + "container-security-context": {}, + }, + }, + "Container Security Context", + tc.expectedGrade, + ) + + // comments := testExpectedScoreReader(test, bytes.NewReader(output), "Container Security Context", tc.expectedGrade) if tc.expectedComment != nil { assert.Contains(test, comments, *tc.expectedComment, "caseID=%d", caseID) @@ -225,27 +237,52 @@ func TestPodSecurityContext(test *testing.T) { func TestContainerSecurityContextPrivileged(t *testing.T) { t.Parallel() - testExpectedScore(t, "pod-security-context-privileged.yaml", "Container Security Context", scorecard.GradeCritical) + testExpectedScoreWithConfig(t, config.Configuration{ + AllFiles: []ks.NamedReader{testFile("pod-security-context-privileged.yaml")}, + EnabledOptionalTests: map[string]struct{}{ + "container-security-context": {}, + }, + }, "Container Security Context", scorecard.GradeCritical) } func TestContainerSecurityContextLowUser(t *testing.T) { t.Parallel() - testExpectedScore(t, "pod-security-context-low-user-id.yaml", "Container Security Context", scorecard.GradeCritical) + testExpectedScoreWithConfig(t, config.Configuration{ + AllFiles: []ks.NamedReader{testFile("pod-security-context-low-user-id.yaml")}, + EnabledOptionalTests: map[string]struct{}{ + "container-security-context": {}, + }, + }, "Container Security Context", scorecard.GradeCritical) } func TestContainerSecurityContextLowGroup(t *testing.T) { t.Parallel() - testExpectedScore(t, "pod-security-context-low-group-id.yaml", "Container Security Context", scorecard.GradeCritical) + testExpectedScoreWithConfig(t, config.Configuration{ + AllFiles: []ks.NamedReader{testFile("pod-security-context-low-group-id.yaml")}, + EnabledOptionalTests: map[string]struct{}{ + "container-security-context": {}, + }, + }, "Container Security Context", scorecard.GradeCritical) } func TestPodSecurityContextInherited(t *testing.T) { t.Parallel() - testExpectedScore(t, "security-inherit-pod-security-context.yaml", "Container Security Context", scorecard.GradeAllOK) + testExpectedScoreWithConfig(t, config.Configuration{ + AllFiles: []ks.NamedReader{testFile("security-inherit-pod-security-context.yaml")}, + EnabledOptionalTests: map[string]struct{}{ + "container-security-context": {}, + }, + }, "Container Security Context", scorecard.GradeAllOK) } func TestContainerSecurityContextAllGood(t *testing.T) { t.Parallel() - c := testExpectedScore(t, "pod-security-context-all-good.yaml", "Container Security Context", scorecard.GradeAllOK) + c := testExpectedScoreWithConfig(t, config.Configuration{ + AllFiles: []ks.NamedReader{testFile("pod-security-context-all-good.yaml")}, + EnabledOptionalTests: map[string]struct{}{ + "container-security-context": {}, + }, + }, "Container Security Context", scorecard.GradeAllOK) assert.Empty(t, c) }