diff --git a/docs/hardening.md b/docs/hardening.md
index 510f7cf12a69528dbf95f9a341bd69d65f4b892d..df757df327d73370ed5851e86bb7950276938cd5 100644
--- a/docs/hardening.md
+++ b/docs/hardening.md
@@ -89,6 +89,11 @@ kubelet_seccomp_default: true
 # additional configurations
 kube_owner: root
 kube_cert_group: root
+
+# create a default Pod Security Configuration and deny running of insecure pods
+# kube_system namespace is exempted by default
+kube_pod_security_use_default: true
+kube_pod_security_default_enforce: restricted
 ```
 
 Let's take a deep look to the resultant **kubernetes** configuration:
diff --git a/roles/kubernetes/control-plane/defaults/main/main.yml b/roles/kubernetes/control-plane/defaults/main/main.yml
index c537432074e1b6d38e43ff60f367a55f4492368c..32cabb91e976f337a3b74e1daad9f4ae14533c37 100644
--- a/roles/kubernetes/control-plane/defaults/main/main.yml
+++ b/roles/kubernetes/control-plane/defaults/main/main.yml
@@ -104,6 +104,18 @@ kube_apiserver_admission_control_config_file: false
 #   cache_size: <cache_size_value>
 kube_apiserver_admission_event_rate_limits: {}
 
+kube_pod_security_use_default: false
+kube_pod_security_default_enforce: baseline
+kube_pod_security_default_enforce_version: latest
+kube_pod_security_default_audit: restricted
+kube_pod_security_default_audit_version: latest
+kube_pod_security_default_warn: restricted
+kube_pod_security_default_warn_version: latest
+kube_pod_security_exemptions_usernames: []
+kube_pod_security_exemptions_runtime_class_names: []
+kube_pod_security_exemptions_namespaces:
+  - kube-system
+
 # 1.10+ list of disabled admission plugins
 kube_apiserver_disable_admission_plugins: []
 
diff --git a/roles/kubernetes/control-plane/templates/podsecurity.yaml.j2 b/roles/kubernetes/control-plane/templates/podsecurity.yaml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..5d39576ffb8e8f31b73eb3d6e6a40727c73573ea
--- /dev/null
+++ b/roles/kubernetes/control-plane/templates/podsecurity.yaml.j2
@@ -0,0 +1,17 @@
+{% if kube_pod_security_use_default %}
+apiVersion: pod-security.admission.config.k8s.io/v1beta1
+kind: PodSecurityConfiguration
+defaults:
+  enforce: "{{ kube_pod_security_default_enforce }}"
+  enforce-version: "{{ kube_pod_security_default_enforce_version }}"
+  audit: "{{ kube_pod_security_default_audit }}"
+  audit-version: "{{ kube_pod_security_default_audit_version }}"
+  warn: "{{ kube_pod_security_default_warn }}"
+  warn-version: "{{ kube_pod_security_default_warn_version }}"
+exemptions:
+  usernames: {{ kube_pod_security_exemptions_usernames|to_json }}
+  runtimeClasses: {{ kube_pod_security_exemptions_runtime_class_names|to_json }}
+  namespaces: {{ kube_pod_security_exemptions_namespaces|to_json }}
+{% else %}
+# This file is intentinally left empty as kube_pod_security_use_default={{ kube_pod_security_use_default }}
+{% endif %}
diff --git a/roles/kubernetes/control-plane/vars/main.yaml b/roles/kubernetes/control-plane/vars/main.yaml
index 57a39f784229921c9ab1aac79228b0ead14985d2..f888d6b0ce80d912cd974ee53ad26a0a8e989cd7 100644
--- a/roles/kubernetes/control-plane/vars/main.yaml
+++ b/roles/kubernetes/control-plane/vars/main.yaml
@@ -1,3 +1,3 @@
 ---
 # list of admission plugins that needs to be configured
-kube_apiserver_admission_plugins_needs_configuration: [EventRateLimit]
+kube_apiserver_admission_plugins_needs_configuration: [EventRateLimit, PodSecurity]