diff --git a/charts/t8s-cluster/templates/management-cluster/clusterClass/_helpers.tpl b/charts/t8s-cluster/templates/management-cluster/clusterClass/_helpers.tpl index 96a5674a0c..a3d10ea8e0 100644 --- a/charts/t8s-cluster/templates/management-cluster/clusterClass/_helpers.tpl +++ b/charts/t8s-cluster/templates/management-cluster/clusterClass/_helpers.tpl @@ -218,6 +218,10 @@ admission-control-config.yaml {{- if $featureFlags -}} {{- $args = set $args "feature-gates" ($featureFlags | join ",") -}} {{- end -}} + {{- if .context.Values.controlPlane.audit -}} + {{- $args = set $args "audit-policy-file" (include "t8s-cluster.clusterClass.apiServer.auditPolicyPath" (dict)) -}} + {{- $args = set $args "audit-webhook-config-file" (include "t8s-cluster.clusterClass.apiServer.auditWebhookConfigPath" (dict)) -}} + {{- end -}} {{- toYaml $args -}} {{- end }} @@ -235,13 +239,119 @@ admission-control-config.yaml -}} {{- end -}} +{{- define "t8s-cluster.clusterClass.apiServer.auditPolicyFileName" -}} +audit-policy.yaml +{{- end -}} + +{{- define "t8s-cluster.clusterClass.apiServer.auditWebhookConfigFileName" -}} +audit-webhook.kubeconfig +{{- end -}} + +{{- define "t8s-cluster.clusterClass.apiServer.auditPolicyPath" -}} +{{- include "t8s-cluster.clusterClass.configPath" (dict) -}}/{{- include "t8s-cluster.clusterClass.apiServer.auditPolicyFileName" (dict) -}} +{{- end -}} + +{{- define "t8s-cluster.clusterClass.apiServer.auditWebhookConfigPath" -}} +{{- include "t8s-cluster.clusterClass.configPath" (dict) -}}/{{- include "t8s-cluster.clusterClass.apiServer.auditWebhookConfigFileName" (dict) -}} +{{- end -}} + +{{- define "t8s-cluster.clusterClass.apiServer.auditWebhookTokenFileName" -}} +audit-webhook-token +{{- end -}} + +{{- define "t8s-cluster.clusterClass.apiServer.auditWebhookTokenPath" -}} +{{- include "t8s-cluster.clusterClass.configPath" (dict) -}}/{{- include "t8s-cluster.clusterClass.apiServer.auditWebhookTokenFileName" (dict) -}} +{{- end -}} + +{{- define "t8s-cluster.clusterClass.apiServer.auditPolicyRules" -}} +# Long-running requests like watches will not generate an audit event in RequestReceived. +omitStages: + - RequestReceived +rules: + - level: None + users: + - system:kube-controller-manager + - system:kube-scheduler + - system:apiserver + - level: None + resources: + - group: coordination.k8s.io + resources: + - leases + - group: "" + resources: + - events + - level: Metadata + verbs: [] # All verbs + resources: + - group: "" + resources: + - secrets + - level: Metadata + verbs: + - create + - update + - patch + - delete + - deletecollection + resources: [] # All resources +{{- end -}} + +{{- define "t8s-cluster.clusterClass.apiServer.auditPolicy" -}} +apiVersion: audit.k8s.io/v1 +kind: Policy +{{ include "t8s-cluster.clusterClass.apiServer.auditPolicyRules" (dict) -}} +{{- end -}} + +{{- define "t8s-cluster.clusterClass.apiServer.auditWebhookConfig" -}} + {{- $_ := mustMerge . (pick .context "Release") -}} + {{- $server := printf "https://k8s.master.wazuh.teuto.net/%s/%s" .Release.Namespace .Release.Name -}} +apiVersion: v1 +kind: Config +clusters: +- cluster: + server: {{ $server }} + name: webhook +users: +- name: kube-apiserver + user: + tokenFile: {{ include "t8s-cluster.clusterClass.apiServer.auditWebhookTokenPath" (dict) }} +contexts: +- context: + cluster: webhook + user: kube-apiserver + name: webhook +current-context: webhook +{{- end -}} + {{- define "t8s-cluster.clusterClass.apiServer.dynamicFiles" -}} - {{- toYaml (dict + {{- $_ := mustMerge . (pick .context "Values") -}} + {{- $files := dict (include "t8s-cluster.clusterClass.apiServer.authenticationConfigFileName" (dict)) (dict "path" (include "t8s-cluster.clusterClass.apiServer.authenticationConfigPath" (dict)) "fileName" (include "t8s-cluster.clusterClass.apiServer.authenticationConfigFileName" (dict)) "content" (include "t8s-cluster.clusterClass.apiServer.authenticationConfig" (dict "context" .context)) ) - ) -}} + {{- if .Values.controlPlane.audit -}} + {{- $_ := set $files (include "t8s-cluster.clusterClass.apiServer.auditPolicyFileName" (dict)) (dict + "path" (include "t8s-cluster.clusterClass.apiServer.auditPolicyPath" (dict)) + "fileName" (include "t8s-cluster.clusterClass.apiServer.auditPolicyFileName" (dict)) + "content" (include "t8s-cluster.clusterClass.apiServer.auditPolicy" (dict)) + ) + -}} + {{- $_ = set $files (include "t8s-cluster.clusterClass.apiServer.auditWebhookConfigFileName" (dict)) (dict + "path" (include "t8s-cluster.clusterClass.apiServer.auditWebhookConfigPath" (dict)) + "fileName" (include "t8s-cluster.clusterClass.apiServer.auditWebhookConfigFileName" (dict)) + "content" (include "t8s-cluster.clusterClass.apiServer.auditWebhookConfig" (dict "context" .context)) + ) + -}} + {{- $_ = set $files (include "t8s-cluster.clusterClass.apiServer.auditWebhookTokenFileName" (dict)) (dict + "path" (include "t8s-cluster.clusterClass.apiServer.auditWebhookTokenPath" (dict)) + "fileName" (include "t8s-cluster.clusterClass.apiServer.auditWebhookTokenFileName" (dict)) + "contentFrom" (dict "secret" (dict "name" "wazuh-audit-webhook" "key" "token")) + ) + -}} + {{- end -}} + {{- toYaml $files -}} {{- end -}} diff --git a/charts/t8s-cluster/templates/management-cluster/clusterClass/hostedControlPlaneTemplate/_hostedControlPlaneTemplateSpec.yaml b/charts/t8s-cluster/templates/management-cluster/clusterClass/hostedControlPlaneTemplate/_hostedControlPlaneTemplateSpec.yaml index 17d57c9f91..ca62af00fa 100644 --- a/charts/t8s-cluster/templates/management-cluster/clusterClass/hostedControlPlaneTemplate/_hostedControlPlaneTemplateSpec.yaml +++ b/charts/t8s-cluster/templates/management-cluster/clusterClass/hostedControlPlaneTemplate/_hostedControlPlaneTemplateSpec.yaml @@ -25,38 +25,7 @@ deployment: authentication: secretName: wazuh-audit-webhook secretNamespace: capi-hosted-control-plane-system - policy: - # Long-running requests like watches will not generate an audit event in RequestReceived. - omitStages: - - RequestReceived - rules: - - level: None - users: - - system:kube-controller-manager - - system:kube-scheduler - - system:apiserver - - level: None - resources: - - group: coordination.k8s.io - resources: - - leases - - group: "" - resources: - - events - - level: Metadata - verbs: [] # All verbs - resources: - - group: "" - resources: - - secrets - - level: Metadata - verbs: - - create - - update - - patch - - delete - - deletecollection - resources: [] # All resources + policy: {{- include "t8s-cluster.clusterClass.apiServer.auditPolicyRules" (dict) | nindent 8 }} controllerManager: args: {{- include "t8s-cluster.clusterClass.args.controllerManager" (dict "context" .) | nindent 6 }} resources: {{- include "common.resources" .Values.controlPlane | nindent 6 }} diff --git a/charts/t8s-cluster/templates/management-cluster/clusterClass/kubeadmControlPlaneTemplate/_helpers.tpl b/charts/t8s-cluster/templates/management-cluster/clusterClass/kubeadmControlPlaneTemplate/_helpers.tpl index d4b4506456..dcc8c71dde 100644 --- a/charts/t8s-cluster/templates/management-cluster/clusterClass/kubeadmControlPlaneTemplate/_helpers.tpl +++ b/charts/t8s-cluster/templates/management-cluster/clusterClass/kubeadmControlPlaneTemplate/_helpers.tpl @@ -28,7 +28,11 @@ {{- end -}} {{- $dynamicFiles := include "t8s-cluster.clusterClass.apiServer.dynamicFiles" (dict "context" .) | fromYaml | values -}} {{- range $name, $file := $dynamicFiles -}} - {{- $files = append $files (dict "content" (get $file "content" | required (printf "missing content for %s" $name)) "path" (get $file "path" | required (printf "missing path for %s" $name))) -}} + {{- if hasKey $file "contentFrom" -}} + {{- $files = append $files (dict "contentFrom" (get $file "contentFrom") "path" (get $file "path" | required (printf "missing path for %s" $name))) -}} + {{- else -}} + {{- $files = append $files (dict "content" (get $file "content" | required (printf "missing content for %s" $name)) "path" (get $file "path" | required (printf "missing path for %s" $name))) -}} + {{- end -}} {{- end -}} {{- $apiserverPatch := dict "spec" (dict "containers" (list (dict "name" "kube-apiserver" "resources" (include "common.resources" .Values.controlPlane | fromYaml)))) -}} {{- $files = append $files (include "t8s-cluster.patches.patchFile" (dict "values" $apiserverPatch "target" "kube-apiserver" "component" "memory") | fromYaml) -}} diff --git a/charts/t8s-cluster/values.schema.json b/charts/t8s-cluster/values.schema.json index caaaf15130..1e8c302cdc 100644 --- a/charts/t8s-cluster/values.schema.json +++ b/charts/t8s-cluster/values.schema.json @@ -86,6 +86,10 @@ "type": "boolean", "description": "Whether the control plane is hosted on the management cluster" }, + "audit": { + "type": "boolean", + "description": "Whether to configure audit logging for kubeadm control planes (opt-in). Do not set this for hosted control planes, as they always have audit logging enabled via their own mechanism." + }, "flavor": { "type": "string" }, diff --git a/charts/t8s-cluster/values.yaml b/charts/t8s-cluster/values.yaml index cd4537f9a0..7d82ff9f8e 100644 --- a/charts/t8s-cluster/values.yaml +++ b/charts/t8s-cluster/values.yaml @@ -54,6 +54,7 @@ metadata: controlPlane: hosted: false + audit: false flavor: standard.2.1905 singleNode: false allowedCIDRs: []