diff --git a/Makefile b/Makefile index 80c73bfeaa4ea73eb0364ec824e9aff69f65473b..97662e7a91a6054b2d26be91189cfedcdf99da43 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,8 @@ JSONNETFMT_ARGS=-n 2 --max-blank-lines 2 --string-style s --comment-style s MDOX_VALIDATE_CONFIG?=.mdox.validate.yaml MD_FILES_TO_FORMAT=$(shell find docs developer-workspace examples experimental jsonnet manifests -name "*.md") $(shell ls *.md) +KUBESCAPE_THRESHOLD=9 + all: generate fmt test docs .PHONY: clean @@ -66,7 +68,7 @@ kubeconform: crdschemas manifests $(KUBECONFORM_BIN) .PHONY: kubescape kubescape: $(KUBESCAPE_BIN) ## Runs a security analysis on generated manifests - failing if risk score is above threshold percentage 't' - $(KUBESCAPE_BIN) scan -s framework -t 17 nsa manifests/*.yaml --exceptions 'kubescape-exceptions.json' + $(KUBESCAPE_BIN) scan -s framework -t $(KUBESCAPE_THRESHOLD) nsa manifests/*.yaml --exceptions 'kubescape-exceptions.json' .PHONY: fmt fmt: $(JSONNETFMT_BIN) diff --git a/docs/security.md b/docs/security.md index de9c13f50ea57b4254d8c177739aacda0670660b..bb888c7eacc3aa3e360a1b5b7bb226f2e0292665 100644 --- a/docs/security.md +++ b/docs/security.md @@ -9,3 +9,16 @@ While we aim for best practices in terms of security by default, due to the natu * Host Port is set. [Kubernetes already sets a Host Port by default when Host Network is enabled.](https://github.com/kubernetes/kubernetes/blob/1945829906546caf867992669a0bfa588edf8be6/pkg/apis/core/v1/defaults.go#L402-L411). Since nothing can be done here, we configure it to our preference port. * Host PID is set to `true`, since node-exporter requires direct access to the host namespace to gather statistics. * Host Network is set to `true`, since node-exporter requires direct access to the host network to gather statistics. +* `automountServiceAccountToken` is set to `true` on Pod level as kube-rbac-proxy sidecar requires connection to kubernetes API server. + +#### prometheus-adapter +* `automountServiceAccountToken` is set to `true` on Pod level as application requires connection to kubernetes API server. + +#### blackbox-exporter +* `automountServiceAccountToken` is set to `true` on Pod level as kube-rbac-proxy sidecar requires connection to kubernetes API server. + +#### kube-state-metrics +* `automountServiceAccountToken` is set to `true` on Pod level as kube-rbac-proxy sidecars requires connection to kubernetes API server. + +#### prometheus-operator +* `automountServiceAccountToken` is set to `true` on Pod level as kube-rbac-proxy sidecars requires connection to kubernetes API server. diff --git a/jsonnet/kube-prometheus/components/alertmanager.libsonnet b/jsonnet/kube-prometheus/components/alertmanager.libsonnet index 4d17c8ab2ac3e86e210b8f09d13b52bc3c4077c2..a2f29e671d737fd8c1454fb93fb0bc059e51916f 100644 --- a/jsonnet/kube-prometheus/components/alertmanager.libsonnet +++ b/jsonnet/kube-prometheus/components/alertmanager.libsonnet @@ -121,6 +121,7 @@ function(params) { apiVersion: 'v1', kind: 'ServiceAccount', metadata: am._metadata, + automountServiceAccountToken: false, }, service: { diff --git a/jsonnet/kube-prometheus/components/blackbox-exporter.libsonnet b/jsonnet/kube-prometheus/components/blackbox-exporter.libsonnet index 8a05beff286c1d8f4ae14724b8e3af9ee2242bb2..162bd9a631028d20054aad1fac49127d07b2dc01 100644 --- a/jsonnet/kube-prometheus/components/blackbox-exporter.libsonnet +++ b/jsonnet/kube-prometheus/components/blackbox-exporter.libsonnet @@ -115,6 +115,7 @@ function(params) { apiVersion: 'v1', kind: 'ServiceAccount', metadata: bb._metadata, + automountServiceAccountToken: false, }, clusterRole: { @@ -238,6 +239,7 @@ function(params) { spec: { containers: [blackboxExporter, reloader, kubeRbacProxy], nodeSelector: { 'kubernetes.io/os': 'linux' }, + automountServiceAccountToken: true, serviceAccountName: 'blackbox-exporter', volumes: [{ name: 'config', diff --git a/jsonnet/kube-prometheus/components/grafana.libsonnet b/jsonnet/kube-prometheus/components/grafana.libsonnet index 2ba9518c87d1134184860a214f9c0f2d8a342897..a89e170e92d98bc6f28a97e39362fa130fbb7fed 100644 --- a/jsonnet/kube-prometheus/components/grafana.libsonnet +++ b/jsonnet/kube-prometheus/components/grafana.libsonnet @@ -88,10 +88,12 @@ function(params) // 'allowPrivilegeEscalation: false' can be deleted when https://github.com/brancz/kubernetes-grafana/pull/128 gets merged. // 'readOnlyRootFilesystem: true' can be deleted when https://github.com/brancz/kubernetes-grafana/pull/129 gets merged. // 'capabilities: { drop: ['ALL'] }' can be deleted when https://github.com/brancz/kubernetes-grafana/pull/130 gets merged. + // FIXME(paulfantom): `automountServiceAccountToken` can be removed after porting to brancz/kuberentes-grafana deployment+: { spec+: { template+: { spec+: { + automountServiceAccountToken: false, containers: std.map(function(c) c { securityContext+: { allowPrivilegeEscalation: false, diff --git a/jsonnet/kube-prometheus/components/kube-state-metrics.libsonnet b/jsonnet/kube-prometheus/components/kube-state-metrics.libsonnet index cd925c0b82f240ab69ceb47c874d0fe0081c86db..c63891ec624603c71575c2d8cfaa405eb9816929 100644 --- a/jsonnet/kube-prometheus/components/kube-state-metrics.libsonnet +++ b/jsonnet/kube-prometheus/components/kube-state-metrics.libsonnet @@ -129,6 +129,7 @@ function(params) (import 'github.com/kubernetes/kube-state-metrics/jsonnet/kube- }, }, spec+: { + automountServiceAccountToken: true, containers: std.map(function(c) c { ports:: null, livenessProbe:: null, diff --git a/jsonnet/kube-prometheus/components/node-exporter.libsonnet b/jsonnet/kube-prometheus/components/node-exporter.libsonnet index 2b0e45ff1660af258a826b6dc93b502231367b22..5e6cf8533a8b4933418a882e5c55a03dcbe59124 100644 --- a/jsonnet/kube-prometheus/components/node-exporter.libsonnet +++ b/jsonnet/kube-prometheus/components/node-exporter.libsonnet @@ -114,6 +114,7 @@ function(params) { apiVersion: 'v1', kind: 'ServiceAccount', metadata: ne._metadata, + automountServiceAccountToken: false, }, service: { @@ -246,6 +247,7 @@ function(params) { { name: 'sys', hostPath: { path: '/sys' } }, { name: 'root', hostPath: { path: '/' } }, ], + automountServiceAccountToken: true, serviceAccountName: ne._config.name, securityContext: { runAsUser: 65534, diff --git a/jsonnet/kube-prometheus/components/prometheus-adapter.libsonnet b/jsonnet/kube-prometheus/components/prometheus-adapter.libsonnet index b0cf3a4bddf294e5a9c188cb2f8191c18e97edd9..1ac3aced0ca4ffee8818e48ac14c0da000392b5d 100644 --- a/jsonnet/kube-prometheus/components/prometheus-adapter.libsonnet +++ b/jsonnet/kube-prometheus/components/prometheus-adapter.libsonnet @@ -253,6 +253,7 @@ function(params) { spec: { containers: [c], serviceAccountName: $.serviceAccount.metadata.name, + automountServiceAccountToken: true, nodeSelector: { 'kubernetes.io/os': 'linux' }, volumes: [ { name: 'tmpfs', emptyDir: {} }, @@ -268,6 +269,7 @@ function(params) { apiVersion: 'v1', kind: 'ServiceAccount', metadata: pa._metadata, + automountServiceAccountToken: false, }, clusterRole: { diff --git a/jsonnet/kube-prometheus/components/prometheus-operator.libsonnet b/jsonnet/kube-prometheus/components/prometheus-operator.libsonnet index b6139da1cb96cfc1af45918f4575a11893f1834e..68ebf94cc5b9c85addb018dc34e4a3e65260eb12 100644 --- a/jsonnet/kube-prometheus/components/prometheus-operator.libsonnet +++ b/jsonnet/kube-prometheus/components/prometheus-operator.libsonnet @@ -131,6 +131,7 @@ function(params) spec+: { template+: { spec+: { + automountServiceAccountToken: true, containers: std.map(function(c) c { securityContext+: { capabilities: { drop: ['ALL'] }, diff --git a/jsonnet/kube-prometheus/components/prometheus.libsonnet b/jsonnet/kube-prometheus/components/prometheus.libsonnet index db1e2cd0e4c635e8a025cb8ea2ef95ed4d719df1..c21a65a92badf2b2f3c7d3230ad4ef4d2418b9c6 100644 --- a/jsonnet/kube-prometheus/components/prometheus.libsonnet +++ b/jsonnet/kube-prometheus/components/prometheus.libsonnet @@ -98,6 +98,7 @@ function(params) { apiVersion: 'v1', kind: 'ServiceAccount', metadata: p._metadata, + automountServiceAccountToken: false, }, service: { diff --git a/kubescape-exceptions.json b/kubescape-exceptions.json index 11ae81866af5726d0b2de9672ac30fd7c0d2e79f..c260b9f7cfa9042a268e769d0be375d06453815c 100644 --- a/kubescape-exceptions.json +++ b/kubescape-exceptions.json @@ -1,4 +1,53 @@ [ + { + "name": "exclude-automountServiceAccountToken-checks", + "policyType": "postureExceptionPolicy", + "actions": [ + "alertOnly" + ], + "resources": [ + { + "designatorType": "Attributes", + "attributes": { + "kind": "DaemonSet", + "name": "node-exporter" + } + }, + { + "designatorType": "Attributes", + "attributes": { + "kind": "Deployment", + "name": "blackbox-exporter" + } + }, + { + "designatorType": "Attributes", + "attributes": { + "kind": "Deployment", + "name": "kube-state-metrics" + } + }, + { + "designatorType": "Attributes", + "attributes": { + "kind": "Deployment", + "name": "prometheus-adapter" + } + }, + { + "designatorType": "Attributes", + "attributes": { + "kind": "Deployment", + "name": "prometheus-operator" + } + } + ], + "posturePolicies": [ + { + "controlName": "Automatic mapping of service account" + } + ] + }, { "name": "exclude-node-exporter-host-access-checks", "policyType": "postureExceptionPolicy", diff --git a/manifests/alertmanager-serviceAccount.yaml b/manifests/alertmanager-serviceAccount.yaml index 5fafffaab7f03747be1a088bc7c792ab08927b14..0bf6621afd625eb849dc025a3a2d9bc12fc16c4a 100644 --- a/manifests/alertmanager-serviceAccount.yaml +++ b/manifests/alertmanager-serviceAccount.yaml @@ -1,4 +1,5 @@ apiVersion: v1 +automountServiceAccountToken: false kind: ServiceAccount metadata: labels: diff --git a/manifests/blackboxExporter-deployment.yaml b/manifests/blackboxExporter-deployment.yaml index fed1d365dfbd890fed01a573e681d8057f852f55..e5e689f45e12011c53b114cd76e05466e8af7643 100644 --- a/manifests/blackboxExporter-deployment.yaml +++ b/manifests/blackboxExporter-deployment.yaml @@ -25,6 +25,7 @@ spec: app.kubernetes.io/part-of: kube-prometheus app.kubernetes.io/version: 0.19.0 spec: + automountServiceAccountToken: true containers: - args: - --config.file=/etc/blackbox_exporter/config.yml diff --git a/manifests/blackboxExporter-serviceAccount.yaml b/manifests/blackboxExporter-serviceAccount.yaml index a708ea3991f910d6d82f02424a79cbfd99f62aa9..0f59b576f23b7be78ed19625c94586868980e2df 100644 --- a/manifests/blackboxExporter-serviceAccount.yaml +++ b/manifests/blackboxExporter-serviceAccount.yaml @@ -1,4 +1,5 @@ apiVersion: v1 +automountServiceAccountToken: false kind: ServiceAccount metadata: labels: diff --git a/manifests/grafana-deployment.yaml b/manifests/grafana-deployment.yaml index a25a6cba6ca408345d0a5980d778a58bc12ca061..69eb37a6d7bd3d210075fc4d613dd793e73911dc 100644 --- a/manifests/grafana-deployment.yaml +++ b/manifests/grafana-deployment.yaml @@ -27,6 +27,7 @@ spec: app.kubernetes.io/part-of: kube-prometheus app.kubernetes.io/version: 8.3.4 spec: + automountServiceAccountToken: false containers: - env: [] image: grafana/grafana:8.3.4 diff --git a/manifests/nodeExporter-daemonset.yaml b/manifests/nodeExporter-daemonset.yaml index cec3b2654c123a266e9df77a68dda27d93d945fb..0a03eaac28c4c732c90e87c8ffc66629dda00218 100644 --- a/manifests/nodeExporter-daemonset.yaml +++ b/manifests/nodeExporter-daemonset.yaml @@ -24,6 +24,7 @@ spec: app.kubernetes.io/part-of: kube-prometheus app.kubernetes.io/version: 1.3.1 spec: + automountServiceAccountToken: true containers: - args: - --web.listen-address=127.0.0.1:9100 diff --git a/manifests/nodeExporter-serviceAccount.yaml b/manifests/nodeExporter-serviceAccount.yaml index 55fac9e9520f7e88ca955971a3e955be99cae7e3..c04d5daf9a95c95d9fb24e8fbf8c77c1bda14f6e 100644 --- a/manifests/nodeExporter-serviceAccount.yaml +++ b/manifests/nodeExporter-serviceAccount.yaml @@ -1,4 +1,5 @@ apiVersion: v1 +automountServiceAccountToken: false kind: ServiceAccount metadata: labels: diff --git a/manifests/prometheus-serviceAccount.yaml b/manifests/prometheus-serviceAccount.yaml index 954222c56867aa45ff0d5d4cf3b64b15da26d009..1778f13c38136a12307826b2ad9c0b0de360b1c0 100644 --- a/manifests/prometheus-serviceAccount.yaml +++ b/manifests/prometheus-serviceAccount.yaml @@ -1,4 +1,5 @@ apiVersion: v1 +automountServiceAccountToken: false kind: ServiceAccount metadata: labels: diff --git a/manifests/prometheusAdapter-deployment.yaml b/manifests/prometheusAdapter-deployment.yaml index 8f2eeae6bd12054c3f76a2f642d625740c1d13b7..a15128d09866057649caee75c174e2ec00927a0f 100644 --- a/manifests/prometheusAdapter-deployment.yaml +++ b/manifests/prometheusAdapter-deployment.yaml @@ -27,6 +27,7 @@ spec: app.kubernetes.io/part-of: kube-prometheus app.kubernetes.io/version: 0.9.1 spec: + automountServiceAccountToken: true containers: - args: - --cert-dir=/var/run/serving-cert diff --git a/manifests/prometheusAdapter-serviceAccount.yaml b/manifests/prometheusAdapter-serviceAccount.yaml index 0da73ec6f62679f1b8834af4423ed3f431de8525..ea607f3af39c40105812b7ba2f124ea5f91af6ea 100644 --- a/manifests/prometheusAdapter-serviceAccount.yaml +++ b/manifests/prometheusAdapter-serviceAccount.yaml @@ -1,4 +1,5 @@ apiVersion: v1 +automountServiceAccountToken: false kind: ServiceAccount metadata: labels: