diff --git a/checks/clusterrolePodExecAttach.yaml b/checks/clusterrolePodExecAttach.yaml index efc7bdc26..44a419f94 100644 --- a/checks/clusterrolePodExecAttach.yaml +++ b/checks/clusterrolePodExecAttach.yaml @@ -18,9 +18,8 @@ schemaString: | - const: 'admin' - const: "cluster-admin" - const: "edit" - - const: "system:aggregate-to-edit" - - const: "system:controller:generic-garbage-collector" - - const: "system:controller:namespace-controller" + - pattern: '^system:' + - const: "gce:podsecuritypolicy:calico-sa" - properties: rules: type: array diff --git a/checks/clusterrolebindingClusterAdmin.yaml b/checks/clusterrolebindingClusterAdmin.yaml index 113b6c30c..c4464ec70 100644 --- a/checks/clusterrolebindingClusterAdmin.yaml +++ b/checks/clusterrolebindingClusterAdmin.yaml @@ -17,8 +17,8 @@ schemaString: | type: string anyOf: - const: "cluster-admin" - - const: "system:controller:generic-garbage-collector" - - const: "system:controller:namespace-controller" + - pattern: '^system:' + - const: "gce:podsecuritypolicy:calico-sa" - required: ["roleRef"] properties: roleRef: @@ -39,7 +39,7 @@ additionalSchemaStrings: rbac.authorization.k8s.io/ClusterRole: | type: object # Do not alert on default ClusterRoleBindings. - {{ if and (ne .metadata.name "cluster-admin") (ne .metadata.name "system:controller:generic-garbage-collector") (ne .metadata.name "system:controller:namespace-controller") }} + {{ if and (ne .metadata.name "cluster-admin") (not (hasPrefix .metadata.name "system:")) (ne .metadata.name "gce:podsecuritypolicy:calico-sa") }} required: ["metadata", "rules"] allOf: - properties: diff --git a/checks/clusterrolebindingPodExecAttach.yaml b/checks/clusterrolebindingPodExecAttach.yaml index f1a4a6d4b..cf5d510c2 100644 --- a/checks/clusterrolebindingPodExecAttach.yaml +++ b/checks/clusterrolebindingPodExecAttach.yaml @@ -17,8 +17,8 @@ schemaString: | type: string anyOf: - const: "cluster-admin" - - const: "system:controller:generic-garbage-collector" - - const: "system:controller:namespace-controller" + - pattern: '^system:' + - const: "gce:podsecuritypolicy:calico-sa" - required: ["roleRef"] properties: roleRef: @@ -37,7 +37,7 @@ additionalSchemaStrings: rbac.authorization.k8s.io/ClusterRole: | type: object # Do not alert on default ClusterRoleBindings. - {{ if and (ne .metadata.name "cluster-admin") (ne .metadata.name "system:controller:generic-garbage-collector") (ne .metadata.name "system:controller:namespace-controller") }} + {{ if and (ne .metadata.name "cluster-admin") (not (hasPrefix .metadata.name "system:")) (ne .metadata.name "gce:podsecuritypolicy:calico-sa") }} required: ["metadata", "rules"] allOf: - properties: diff --git a/checks/rolePodExecAttach.yaml b/checks/rolePodExecAttach.yaml index 61c270214..39c780d01 100644 --- a/checks/rolePodExecAttach.yaml +++ b/checks/rolePodExecAttach.yaml @@ -6,40 +6,51 @@ schemaString: | '$schema': http://json-schema.org/draft-07/schema type: object required: ["metadata", "rules"] - properties: - metadata: - required: ["name"] - properties: - name: - type: string - rules: - type: array - items: - type: object - not: - required: ["apiGroups", "resources", "verbs"] + anyOf: + # Do not alert on default Roles. + - properties: + metadata: + required: ["name"] properties: - apiGroups: - type: array - contains: - type: string - anyOf: - - const: "" - - const: '*' - resources: - type: array - contains: - type: string - anyOf: - - const: '*' - - const: "pods/exec" - - const: "pods/attach" - verbs: - type: array - contains: - type: string - anyOf: - - const: '*' - # An exec is also possible by `get`ing a web socket. - - const: 'get' - - const: 'create' + name: + type: string + anyOf: + - pattern: '^system:' + - const: "gce:podsecuritypolicy:calico-sa" + - properties: + metadata: + required: ["name"] + properties: + name: + type: string + rules: + type: array + items: + type: object + not: + required: ["apiGroups", "resources", "verbs"] + properties: + apiGroups: + type: array + contains: + type: string + anyOf: + - const: "" + - const: '*' + resources: + type: array + contains: + type: string + anyOf: + - const: '*' + - const: "pods/exec" + - const: "pods/attach" + verbs: + type: array + contains: + type: string + anyOf: + - const: '*' + # An exec is also possible by `get`ing a web socket. + - const: 'get' + - const: 'create' diff --git a/checks/rolebindingClusterAdminClusterRole.yaml b/checks/rolebindingClusterAdminClusterRole.yaml index 89d845b8d..c515bbb4f 100644 --- a/checks/rolebindingClusterAdminClusterRole.yaml +++ b/checks/rolebindingClusterAdminClusterRole.yaml @@ -15,6 +15,18 @@ schemaString: | kind: type: string const: "Role" + # Do not alert on default ClusterRoleBindings. + - required: ["metadata"] + properties: + metadata: + type: object + required: ["name"] + properties: + name: + type: string + anyOf: + - pattern: '^system:' + - const: "gce:podsecuritypolicy:calico-sa" - required: ["roleRef"] properties: roleRef: @@ -36,6 +48,7 @@ additionalSchemaStrings: type: object # This schema is validated for all roleBindings, regardless of their roleRef. {{ if eq .roleRef.kind "ClusterRole" }} + {{ if and (not (hasPrefix .metadata.name "system:")) (ne .metadata.name "gce:podsecuritypolicy:calico-sa") }} required: ["metadata", "rules"] allOf: - properties: @@ -82,3 +95,4 @@ additionalSchemaStrings: - "patch" - "delete" {{ end }} + {{ end }} diff --git a/checks/rolebindingClusterAdminRole.yaml b/checks/rolebindingClusterAdminRole.yaml index 914497b47..2e5af37e0 100644 --- a/checks/rolebindingClusterAdminRole.yaml +++ b/checks/rolebindingClusterAdminRole.yaml @@ -15,6 +15,18 @@ schemaString: | kind: type: string const: "ClusterRole" + # Do not alert on default RoleBindings. + - required: ["metadata"] + properties: + metadata: + type: object + required: ["name"] + properties: + name: + type: string + anyOf: + - pattern: '^system:' + - const: "gce:podsecuritypolicy:calico-sa" - required: ["roleRef"] properties: roleRef: @@ -34,6 +46,7 @@ additionalSchemaStrings: type: object # This schema is validated for all roleBindings, regardless of their roleRef. {{ if eq .roleRef.kind "Role" }} + {{ if and (not (hasPrefix .metadata.name "system:")) (ne .metadata.name "gce:podsecuritypolicy:calico-sa") }} required: ["metadata", "rules"] allOf: - properties: @@ -80,3 +93,4 @@ additionalSchemaStrings: - "patch" - "delete" {{ end }} + {{ end }} diff --git a/checks/rolebindingClusterRolePodExecAttach.yaml b/checks/rolebindingClusterRolePodExecAttach.yaml index 87e1c02e9..1842ea6d1 100644 --- a/checks/rolebindingClusterRolePodExecAttach.yaml +++ b/checks/rolebindingClusterRolePodExecAttach.yaml @@ -15,6 +15,18 @@ schemaString: | kind: type: string const: "Role" + # Do not alert on default RoleBindings. + - required: ["metadata"] + properties: + metadata: + type: object + required: ["name"] + properties: + name: + type: string + anyOf: + - pattern: '^system:' + - const: "gce:podsecuritypolicy:calico-sa" - required: ["roleRef"] properties: roleRef: @@ -34,6 +46,7 @@ additionalSchemaStrings: type: object # This schema is validated for all roleBindings, regardless of their roleRef. {{ if eq .roleRef.kind "ClusterRole" }} + {{ if and (not (hasPrefix .metadata.name "system:")) (ne .metadata.name "gce:podsecuritypolicy:calico-sa") }} required: ["metadata", "rules"] allOf: - properties: @@ -76,3 +89,4 @@ additionalSchemaStrings: - const: 'get' - const: 'create' {{ end }} + {{ end }} diff --git a/checks/rolebindingRolePodExecAttach.yaml b/checks/rolebindingRolePodExecAttach.yaml index 06fb82873..95e20fa5b 100644 --- a/checks/rolebindingRolePodExecAttach.yaml +++ b/checks/rolebindingRolePodExecAttach.yaml @@ -18,6 +18,18 @@ schemaString: | kind: type: string const: "Role" + # Do not alert on default RoleBindings. + - required: ["metadata"] + properties: + metadata: + type: object + required: ["name"] + properties: + name: + type: string + anyOf: + - pattern: '^system:' + - const: "gce:podsecuritypolicy:calico-sa" - required: ["roleRef"] properties: roleRef: @@ -37,6 +49,7 @@ additionalSchemaStrings: type: object # This schema is validated for all roleBindings, regardless of their roleRef. {{ if eq .roleRef.kind "Role" }} + {{ if and (not (hasPrefix .metadata.name "system:")) (ne .metadata.name "gce:podsecuritypolicy:calico-sa") }} required: ["metadata", "rules"] allOf: - properties: @@ -79,3 +92,4 @@ additionalSchemaStrings: - const: 'get' - const: 'create' {{ end }} + {{ end }} diff --git a/checks/sensitiveContainerEnvVar.yaml b/checks/sensitiveContainerEnvVar.yaml index 2a7ea9031..8527a94cd 100644 --- a/checks/sensitiveContainerEnvVar.yaml +++ b/checks/sensitiveContainerEnvVar.yaml @@ -10,34 +10,41 @@ schemaString: | type: array items: type: object - required: ["name"] - properties: - name: - type: string - '$comment': These environment variable names will be disallowed. - allOf: - - not: - pattern: '(?i)^AWS_SECRET_ACCESS_KEY$' - - not: - pattern: '(?i)^GOOGLE_APPLICATION_CREDENTIALS$' - - not: - pattern: '(?i)^AZURE_.+KEY$' - - not: - pattern: '(?i)^OCI_CLI_KEY_CONTENT$' - - not: - pattern: '(?i)password' - - not: - pattern: '(?i)token' - - not: - pattern: '(?i)bearer' - - not: - pattern: '(?i)secret' - '$comment': This allows variable names not excluded above. - - pattern: '(?i).*' - value: - type: string - '$comment': These environment variable values will be disallowed. - allOf: - - not: - '$comment': THis matches variations like begin private key, begin rsa private key ... - pattern: '(?i)\s*-BEGIN\s+.*PRIVATE KEY-\s*' + oneOf: + - required: ["name", "value"] + properties: + name: + type: string + '$comment': These environment variable names will be disallowed. + allOf: + - not: + pattern: '(?i)^AWS_SECRET_ACCESS_KEY$' + - not: + pattern: '(?i)^GOOGLE_APPLICATION_CREDENTIALS$' + - not: + pattern: '(?i)^AZURE_.+KEY$' + - not: + pattern: '(?i)^OCI_CLI_KEY_CONTENT$' + - not: + pattern: '(?i)password' + - not: + pattern: '(?i)token' + - not: + pattern: '(?i)bearer' + - not: + pattern: '(?i)secret' + '$comment': This allows variable names not excluded above. + - pattern: '(?i).*' + value: + type: string + '$comment': These environment variable values will be disallowed. + allOf: + - not: + '$comment': THis matches variations like begin private key, begin rsa private key ... + pattern: '(?i)\s*-BEGIN\s+.*PRIVATE KEY-\s*' + - required: ["name", "valueFrom"] + properties: + name: + type: string + valueFrom: + type: object diff --git a/docs/customization/custom-checks.md b/docs/customization/custom-checks.md index 9d905d658..ca22683c5 100644 --- a/docs/customization/custom-checks.md +++ b/docs/customization/custom-checks.md @@ -167,6 +167,18 @@ schemaString: | {{ end }} ``` +### Additional Go Template Functions + +These functions are also available in the GO template. + +* [hasPrefix](https://pkg.go.dev/strings#HasPrefix) - for example, `hasPrefix "string" "prefix"` +* [hasSuffix](https://pkg.go.dev/strings#HasSuffix) - for example, `hasSuffix "string" "suffix"` + +For example, the `hasPrefix` function can be used in a template to determine whether a resource name starts with `system:` +``` +{{ if hasPrefix .metadata.name "system:" }} +``` + ## Multi-Resource Checks You can write checks that span multiple resources. This is helpful for ensuring e.g. that every Deployment has a PDB or an HPA associated with it. diff --git a/examples/config-full.yaml b/examples/config-full.yaml index 15804c58b..38a244354 100644 --- a/examples/config-full.yaml +++ b/examples/config-full.yaml @@ -32,6 +32,9 @@ checks: clusterrolebindingPodExecAttach: danger rolebindingClusterRolePodExecAttach: danger rolebindingRolePodExecAttach: danger + clusterrolebindingClusterAdmin: danger + rolebindingClusterAdminClusterRole: danger + rolebindingClusterAdminRole: danger # custom resourceLimits: warning imageRegistry: danger diff --git a/examples/config.yaml b/examples/config.yaml index 5ea55016b..ec4483835 100644 --- a/examples/config.yaml +++ b/examples/config.yaml @@ -16,8 +16,11 @@ checks: memoryRequestsMissing: warning memoryLimitsMissing: warning # security + automountServiceAccountToken: ignore hostIPCSet: danger hostPIDSet: danger + linuxHardening: warning + missingNetworkPolicy: ignore notReadOnlyRootFilesystem: warning privilegeEscalationAllowed: danger runAsRootAllowed: danger @@ -27,11 +30,62 @@ checks: hostNetworkSet: danger hostPortSet: warning tlsSettingsMissing: warning + # These are initially warning and will later be promoted to danger. + sensitiveContainerEnvVar: warning + sensitiveConfigmapContent: warning + clusterrolePodExecAttach: warning + rolePodExecAttach: warning + clusterrolebindingPodExecAttach: warning + rolebindingClusterRolePodExecAttach: warning + rolebindingRolePodExecAttach: warning + clusterrolebindingClusterAdmin: warning + rolebindingClusterAdminClusterRole: warning + rolebindingClusterAdminRole: warning + mutations: - pullPolicyNotAlways exemptions: + - namespace: kube-system + controllerNames: + - dns-controller + - ebs-csi-controller + - ebs-csi-node + - kindnet + - kops-controller + - kube-dns + - kube-flannel-ds + - kube-proxy + - kube-scheduler + - vpa-recommender + rules: + - automountServiceAccountToken + - linuxHardening + - missingNetworkPolicy + - namespace: kube-system + controllerNames: + - coredns + rules: + - automountServiceAccountToken + - missingNetworkPolicy + - namespace: kube-system + controllerNames: + - ebs-csi-controller + rules: + - sensitiveContainerEnvVar + - namespace: kube-system + controllerNames: + - coredns-autoscaler + rules: + - linuxHardening + - namespace: local-path-storage + controllerNames: + - local-path-provisioner + rules: + - automountServiceAccountToken + - linuxHardening + - missingNetworkPolicy - namespace: kube-system controllerNames: - kube-apiserver @@ -54,7 +108,48 @@ exemptions: - runAsPrivileged - notReadOnlyRootFilesystem - hostPIDSet + - namespace: datadog + controllerNames: + - datadogtoken + rules: + - sensitiveConfigmapContent + - namespace: datadog + controllerNames: + - datadog-cluster-agent-apiserver + rules: + - rolebindingClusterAdminRole + - rolebindingRolePodExecAttach + - controllerNames: + - ingress-nginx-controller + rules: + - sensitiveConfigmapContent + - controllerNames: + - ingress-nginx-controller + - ingress-nginx-default-backend + - polaris + - rbac-manager + rules: + - automountServiceAccountToken + - missingNetworkPolicy + - controllerNames: + - aws-iam-authenticator + - aws-load-balancer-controller + - docker-registry + - external-dns + - kube2iam + - metrics-server + rules: + - automountServiceAccountToken + - linuxHardening + - missingNetworkPolicy + - controllerNames: + - oauth2-proxy + rules: + - automountServiceAccountToken + - linuxHardening + - missingNetworkPolicy + - sensitiveContainerEnvVar - controllerNames: - kube-flannel-ds rules: @@ -72,6 +167,9 @@ exemptions: - runAsRootAllowed - readinessProbeMissing - livenessProbeMissing + - automountServiceAccountToken + - linuxHardening + - missingNetworkPolicy - controllerNames: - cluster-autoscaler @@ -79,6 +177,9 @@ exemptions: - notReadOnlyRootFilesystem - runAsRootAllowed - readinessProbeMissing + - automountServiceAccountToken + - linuxHardening + - missingNetworkPolicy - controllerNames: - vpa @@ -95,6 +196,10 @@ exemptions: - readinessProbeMissing - livenessProbeMissing - notReadOnlyRootFilesystem + - automountServiceAccountToken + - linuxHardening + - missingNetworkPolicy + - sensitiveContainerEnvVar - controllerNames: - nginx-ingress-controller diff --git a/pkg/config/schema.go b/pkg/config/schema.go index 3528acd66..b72700426 100644 --- a/pkg/config/schema.go +++ b/pkg/config/schema.go @@ -223,7 +223,10 @@ func (check SchemaCheck) TemplateForResource(res interface{}) (*SchemaCheck, err newCheck.AdditionalSchemaStrings = map[string]string{} for kind, tmplString := range templateStrings { - tmpl := template.New(newCheck.ID) + tmpl := template.New(newCheck.ID).Funcs(template.FuncMap{ + "hasPrefix": strings.HasPrefix, + "hasSuffix": strings.HasSuffix, + }) tmpl, err := tmpl.Parse(tmplString) if err != nil { return nil, err diff --git a/test/checks/clusterrolePodExecAttach/success.gce_calico_clusterrole.yaml b/test/checks/clusterrolePodExecAttach/success.gce_calico_clusterrole.yaml new file mode 100644 index 000000000..ad053d6ab --- /dev/null +++ b/test/checks/clusterrolePodExecAttach/success.gce_calico_clusterrole.yaml @@ -0,0 +1,9 @@ +# This succeeds because the clusterRole is an exempt name `gce:podsecuritypolicy:calico-sa` +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: gce:podsecuritypolicy:calico-sa +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] diff --git a/test/checks/clusterrolePodExecAttach/success.system_prefix.yaml b/test/checks/clusterrolePodExecAttach/success.system_prefix.yaml new file mode 100644 index 000000000..ba2d4e40c --- /dev/null +++ b/test/checks/clusterrolePodExecAttach/success.system_prefix.yaml @@ -0,0 +1,9 @@ +# This succeeds because the clusterRole has an exempt `system:` prefix. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: system:test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] diff --git a/test/checks/clusterrolebindingClusterAdmin/failure.binding_to_system_prefix.yaml b/test/checks/clusterrolebindingClusterAdmin/failure.binding_to_system_prefix.yaml new file mode 100644 index 000000000..444af22ff --- /dev/null +++ b/test/checks/clusterrolebindingClusterAdmin/failure.binding_to_system_prefix.yaml @@ -0,0 +1,35 @@ +# This fails because the clusterRoleBinding references a ClusterRole that uses all wildcards which happens to have a `system:` prefix. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + # The system: prefix does not cause this test to fail, but this test + # avoids incorectly ignoring user-created bindings to system ClusterRoles. + name: system:test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: test-binding-to-system-prefix-clusterrole +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser +--- +# This Role exists so there is at least one Role for the additionalSchema to find. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: not-used + namespace: test +rules: + - apiGroups: [ "" ] + resources: [ "pods" ] + verbs: [ list ] diff --git a/test/checks/clusterrolebindingClusterAdmin/success.gce_calico_binding.yaml b/test/checks/clusterrolebindingClusterAdmin/success.gce_calico_binding.yaml new file mode 100644 index 000000000..3f70eb5ed --- /dev/null +++ b/test/checks/clusterrolebindingClusterAdmin/success.gce_calico_binding.yaml @@ -0,0 +1,33 @@ +# This succeeds because the clusterRoleBinding is an exempt name `gce:podsecuritypolicy:calico-sa` +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gce:podsecuritypolicy:calico-sa +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser +--- +# This Role exists so there is at least one Role for the additionalSchema to find. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: not-used + namespace: test +rules: + - apiGroups: [ "" ] + resources: [ "pods" ] + verbs: [ list ] diff --git a/test/checks/clusterrolebindingClusterAdmin/success.system_prefix_binding.yaml b/test/checks/clusterrolebindingClusterAdmin/success.system_prefix_binding.yaml new file mode 100644 index 000000000..464812876 --- /dev/null +++ b/test/checks/clusterrolebindingClusterAdmin/success.system_prefix_binding.yaml @@ -0,0 +1,33 @@ +# This succeeds because the clusterRoleBinding has an exempt `system:` prefix. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: system:test +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser +--- +# This Role exists so there is at least one Role for the additionalSchema to find. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: not-used + namespace: test +rules: + - apiGroups: [ "" ] + resources: [ "pods" ] + verbs: [ list ] diff --git a/test/checks/clusterrolebindingPodExecAttach/failure.binding_to_system_prefix.yaml b/test/checks/clusterrolebindingPodExecAttach/failure.binding_to_system_prefix.yaml new file mode 100644 index 000000000..444af22ff --- /dev/null +++ b/test/checks/clusterrolebindingPodExecAttach/failure.binding_to_system_prefix.yaml @@ -0,0 +1,35 @@ +# This fails because the clusterRoleBinding references a ClusterRole that uses all wildcards which happens to have a `system:` prefix. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + # The system: prefix does not cause this test to fail, but this test + # avoids incorectly ignoring user-created bindings to system ClusterRoles. + name: system:test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: test-binding-to-system-prefix-clusterrole +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser +--- +# This Role exists so there is at least one Role for the additionalSchema to find. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: not-used + namespace: test +rules: + - apiGroups: [ "" ] + resources: [ "pods" ] + verbs: [ list ] diff --git a/test/checks/clusterrolebindingPodExecAttach/success.gce_calico_binding.yaml b/test/checks/clusterrolebindingPodExecAttach/success.gce_calico_binding.yaml new file mode 100644 index 000000000..3f70eb5ed --- /dev/null +++ b/test/checks/clusterrolebindingPodExecAttach/success.gce_calico_binding.yaml @@ -0,0 +1,33 @@ +# This succeeds because the clusterRoleBinding is an exempt name `gce:podsecuritypolicy:calico-sa` +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gce:podsecuritypolicy:calico-sa +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser +--- +# This Role exists so there is at least one Role for the additionalSchema to find. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: not-used + namespace: test +rules: + - apiGroups: [ "" ] + resources: [ "pods" ] + verbs: [ list ] diff --git a/test/checks/clusterrolebindingPodExecAttach/success.system_prefix_binding.yaml b/test/checks/clusterrolebindingPodExecAttach/success.system_prefix_binding.yaml new file mode 100644 index 000000000..464812876 --- /dev/null +++ b/test/checks/clusterrolebindingPodExecAttach/success.system_prefix_binding.yaml @@ -0,0 +1,33 @@ +# This succeeds because the clusterRoleBinding has an exempt `system:` prefix. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: system:test +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser +--- +# This Role exists so there is at least one Role for the additionalSchema to find. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: not-used + namespace: test +rules: + - apiGroups: [ "" ] + resources: [ "pods" ] + verbs: [ list ] diff --git a/test/checks/rolePodExecAttach/success.gce_calico_binding.yaml b/test/checks/rolePodExecAttach/success.gce_calico_binding.yaml new file mode 100644 index 000000000..8a257a830 --- /dev/null +++ b/test/checks/rolePodExecAttach/success.gce_calico_binding.yaml @@ -0,0 +1,10 @@ +# This succeeds because the role is an exempt name `gce:podsecuritypolicy:calico-sa` +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: gce:podsecuritypolicy:calico-sa + namespace: kube-system +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] diff --git a/test/checks/rolePodExecAttach/success.system_prefix_binding.yaml b/test/checks/rolePodExecAttach/success.system_prefix_binding.yaml new file mode 100644 index 000000000..4e89775e5 --- /dev/null +++ b/test/checks/rolePodExecAttach/success.system_prefix_binding.yaml @@ -0,0 +1,10 @@ +# This succeeds because the Role has an exempt `system:` prefix. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: system:controller:glbc + namespace: kube-system +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] diff --git a/test/checks/rolebindingClusterAdminClusterRole/failure.binding_to_system_prefix.yaml b/test/checks/rolebindingClusterAdminClusterRole/failure.binding_to_system_prefix.yaml new file mode 100644 index 000000000..35ee85447 --- /dev/null +++ b/test/checks/rolebindingClusterAdminClusterRole/failure.binding_to_system_prefix.yaml @@ -0,0 +1,26 @@ +# This fails because the roleBinding references a ClusterRole that uses all wildcards which happens to have a `system:` prefix. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + # The system: prefix does not cause this test to fail, but this test + # avoids incorectly ignoring user-created bindings to system ClusterRoles. + name: system:test + namespace: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: test-binding-to-system-prefix-role + namespace: test +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser diff --git a/test/checks/rolebindingClusterAdminClusterRole/success.gce_calico_binding.yaml b/test/checks/rolebindingClusterAdminClusterRole/success.gce_calico_binding.yaml new file mode 100644 index 000000000..8d13a9001 --- /dev/null +++ b/test/checks/rolebindingClusterAdminClusterRole/success.gce_calico_binding.yaml @@ -0,0 +1,23 @@ +# This succeeds because the roleBinding is an exempt name `gce:podsecuritypolicy:calico-sa` +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: gce:podsecuritypolicy:calico-sa + namespace: test +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser diff --git a/test/checks/rolebindingClusterAdminClusterRole/success.system_prefix_binding.yaml b/test/checks/rolebindingClusterAdminClusterRole/success.system_prefix_binding.yaml new file mode 100644 index 000000000..7ad4ed01b --- /dev/null +++ b/test/checks/rolebindingClusterAdminClusterRole/success.system_prefix_binding.yaml @@ -0,0 +1,24 @@ +# This succeeds because the RoleBinding has an exempt `system:` prefix. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: system:test + namespace: test +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser + diff --git a/test/checks/rolebindingClusterAdminRole/failure.binding_to_system_prefix.yaml b/test/checks/rolebindingClusterAdminRole/failure.binding_to_system_prefix.yaml new file mode 100644 index 000000000..7214a785c --- /dev/null +++ b/test/checks/rolebindingClusterAdminRole/failure.binding_to_system_prefix.yaml @@ -0,0 +1,36 @@ +# This fails because the roleBinding references a Role that uses all wildcards which happens to have a `system:` prefix. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + # The system: prefix does not cause this test to fail, but this test + # avoids incorectly ignoring user-created bindings to system ClusterRoles. + name: system:test + namespace: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: test-binding-to-system-prefix-role + namespace: test +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: system:test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser +--- +# This ClusterRole exists so there is at least one ClusterRole for the additionalSchema to find. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: not-used +rules: + - apiGroups: [ "" ] + resources: [ "pods" ] + verbs: [ list ] diff --git a/test/checks/rolebindingClusterAdminRole/success.gce_calico_binding.yaml b/test/checks/rolebindingClusterAdminRole/success.gce_calico_binding.yaml new file mode 100644 index 000000000..344d6b0d5 --- /dev/null +++ b/test/checks/rolebindingClusterAdminRole/success.gce_calico_binding.yaml @@ -0,0 +1,34 @@ +# This succeeds because the roleBinding is an exempt name `gce:podsecuritypolicy:calico-sa` +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: test + namespace: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: gce:podsecuritypolicy:calico-sa + namespace: test +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser +--- +# This ClusterRole exists so there is at least one ClusterRole for the additionalSchema to find. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: not-used +rules: + - apiGroups: [ "" ] + resources: [ "pods" ] + verbs: [ list ] diff --git a/test/checks/rolebindingClusterAdminRole/success.system_prefix_binding.yaml b/test/checks/rolebindingClusterAdminRole/success.system_prefix_binding.yaml new file mode 100644 index 000000000..8ac7dcc83 --- /dev/null +++ b/test/checks/rolebindingClusterAdminRole/success.system_prefix_binding.yaml @@ -0,0 +1,34 @@ +# This succeeds because the RoleBinding has an exempt `system:` prefix. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: test + namespace: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: system:test + namespace: test +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser +--- +# This ClusterRole exists so there is at least one ClusterRole for the additionalSchema to find. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: not-used +rules: + - apiGroups: [ "" ] + resources: [ "pods" ] + verbs: [ list ] diff --git a/test/checks/rolebindingClusterRolePodExecAttach/failure.binding_to_system_prefix.yaml b/test/checks/rolebindingClusterRolePodExecAttach/failure.binding_to_system_prefix.yaml new file mode 100644 index 000000000..35ee85447 --- /dev/null +++ b/test/checks/rolebindingClusterRolePodExecAttach/failure.binding_to_system_prefix.yaml @@ -0,0 +1,26 @@ +# This fails because the roleBinding references a ClusterRole that uses all wildcards which happens to have a `system:` prefix. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + # The system: prefix does not cause this test to fail, but this test + # avoids incorectly ignoring user-created bindings to system ClusterRoles. + name: system:test + namespace: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: test-binding-to-system-prefix-role + namespace: test +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser diff --git a/test/checks/rolebindingClusterRolePodExecAttach/success.gce_calico_binding.yaml b/test/checks/rolebindingClusterRolePodExecAttach/success.gce_calico_binding.yaml new file mode 100644 index 000000000..8d13a9001 --- /dev/null +++ b/test/checks/rolebindingClusterRolePodExecAttach/success.gce_calico_binding.yaml @@ -0,0 +1,23 @@ +# This succeeds because the roleBinding is an exempt name `gce:podsecuritypolicy:calico-sa` +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: gce:podsecuritypolicy:calico-sa + namespace: test +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser diff --git a/test/checks/rolebindingClusterRolePodExecAttach/success.system_prefix_binding.yaml b/test/checks/rolebindingClusterRolePodExecAttach/success.system_prefix_binding.yaml new file mode 100644 index 000000000..7ad4ed01b --- /dev/null +++ b/test/checks/rolebindingClusterRolePodExecAttach/success.system_prefix_binding.yaml @@ -0,0 +1,24 @@ +# This succeeds because the RoleBinding has an exempt `system:` prefix. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: system:test + namespace: test +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser + diff --git a/test/checks/rolebindingRolePodExecAttach/failure.binding_to_system_prefix.yaml b/test/checks/rolebindingRolePodExecAttach/failure.binding_to_system_prefix.yaml new file mode 100644 index 000000000..cb3c3dc19 --- /dev/null +++ b/test/checks/rolebindingRolePodExecAttach/failure.binding_to_system_prefix.yaml @@ -0,0 +1,26 @@ +# This fails because the roleBinding references a Role that uses all wildcards which happens to have a `system:` prefix. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + # The system: prefix does not cause this test to fail, but this test + # avoids incorectly ignoring user-created bindings to system ClusterRoles. + name: system:test + namespace: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: test-binding-to-system-prefix-role + namespace: test +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: system:test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser diff --git a/test/checks/rolebindingRolePodExecAttach/success.gce_calico_binding.yaml b/test/checks/rolebindingRolePodExecAttach/success.gce_calico_binding.yaml new file mode 100644 index 000000000..3426273a7 --- /dev/null +++ b/test/checks/rolebindingRolePodExecAttach/success.gce_calico_binding.yaml @@ -0,0 +1,24 @@ +# This succeeds because the roleBinding is an exempt name `gce:podsecuritypolicy:calico-sa` +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: test + namespace: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: gce:podsecuritypolicy:calico-sa + namespace: test +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser diff --git a/test/checks/rolebindingRolePodExecAttach/success.system_prefix_binding.yaml b/test/checks/rolebindingRolePodExecAttach/success.system_prefix_binding.yaml new file mode 100644 index 000000000..a813d876f --- /dev/null +++ b/test/checks/rolebindingRolePodExecAttach/success.system_prefix_binding.yaml @@ -0,0 +1,24 @@ +# This succeeds because the RoleBinding has an exempt `system:` prefix. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: test + namespace: test +rules: + - apiGroups: [ "*" ] + resources: [ "*" ] + verbs: [ "*" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: system:test + namespace: test +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: test +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: testuser diff --git a/test/checks/sensitiveContainerEnvVar/success.sensitive_key_uses_valueFrom.yaml b/test/checks/sensitiveContainerEnvVar/success.sensitive_key_uses_valueFrom.yaml new file mode 100644 index 000000000..788bf97fe --- /dev/null +++ b/test/checks/sensitiveContainerEnvVar/success.sensitive_key_uses_valueFrom.yaml @@ -0,0 +1,17 @@ +# This succeeds because a sensitive environment variable name references an external value. +apiVersion: v1 +kind: Pod +metadata: + name: test-pod +spec: + containers: + - name: nginx + env: + - name: token + valueFrom: + secretKeyRef: + key: token + name: a-secret + image: nginx + ports: + - containerPort: 80