diff --git a/roles/kubernetes/master/defaults/main.yml b/roles/kubernetes/master/defaults/main.yml
index e40a9d1aa47aa68b0c08e45813a893b95d57fc0f..ab11069187540e265e4d9dd16c2b91218b8e1af6 100644
--- a/roles/kubernetes/master/defaults/main.yml
+++ b/roles/kubernetes/master/defaults/main.yml
@@ -100,6 +100,7 @@ kube_api_runtime_config:
 kube_basic_auth: false
 kube_token_auth: false
 kube_oidc_auth: false
+kube_webhook_token_auth: false
 
 ## Variables for OpenID Connect Configuration https://kubernetes.io/docs/admin/authentication/
 ## To use OpenID you have to deploy additional an OpenID Provider (e.g Dex, Keycloak, ...)
@@ -113,6 +114,9 @@ kube_oidc_auth: false
 # kube_oidc_groups_claim: groups
 # kube_oidc_groups_prefix: oidc:
 
+## Variables for webhook token auth https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication
+# kube_webhook_token_auth_url: https://...
+
 ## Variables for custom flags
 apiserver_custom_flags: []
 
diff --git a/roles/kubernetes/master/tasks/main.yml b/roles/kubernetes/master/tasks/main.yml
index f7faf43f8e3f3cb05e5f4ab9e27232738f53fd6c..43d9f9fa9b2cbba14256b4889633ae0e35bf508d 100644
--- a/roles/kubernetes/master/tasks/main.yml
+++ b/roles/kubernetes/master/tasks/main.yml
@@ -7,6 +7,12 @@
   when:
     - kube_basic_auth|default(true)
 
+- name: Create webhook token auth config
+  template:
+    src: webhook-token-auth-config.yaml.j2
+    dest: "{{ kube_config_dir }}/webhook-token-auth-config.yaml"
+  when: kube_webhook_token_auth|default(false)
+
 - import_tasks: encrypt-at-rest.yml
   when:
     - kube_encrypt_secret_data
diff --git a/roles/kubernetes/master/templates/kubeadm-config.v1alpha1.yaml.j2 b/roles/kubernetes/master/templates/kubeadm-config.v1alpha1.yaml.j2
index 5ffbb97f6cd180d590356c26d31cb7cb307252c5..41e744bc7f914bdac10a60617fcde445ac3276d6 100644
--- a/roles/kubernetes/master/templates/kubeadm-config.v1alpha1.yaml.j2
+++ b/roles/kubernetes/master/templates/kubeadm-config.v1alpha1.yaml.j2
@@ -99,6 +99,9 @@ apiServerExtraArgs:
   oidc-groups-claim: {{ kube_oidc_groups_claim }}
 {%   endif %}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+  authentication-token-webhook-config-file: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% if kube_encrypt_secret_data %}
   experimental-encryption-provider-config: {{ kube_cert_dir }}/secrets_encryption.yaml
 {% endif %}
@@ -152,7 +155,7 @@ schedulerExtraArgs:
   {{ key }}: "{{ kube_kubeadm_scheduler_extra_args[key] }}"
 {% endfor %}
 {% endif %}
-{% if kube_basic_auth|default(true) or kube_token_auth|default(true) %}
+{% if kube_basic_auth|default(true) or kube_token_auth|default(true) or kube_webhook_token_auth|default(false) %}
 apiServerExtraVolumes:
 {% if cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws", "external"] %}
 - name: cloud-config
@@ -169,6 +172,11 @@ apiServerExtraVolumes:
   hostPath: {{ kube_token_dir }}
   mountPath: {{ kube_token_dir }}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+- name: webhook-token-auth-config
+  hostPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+  mountPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% endif %}
 apiServerCertSANs:
 {% for san in  apiserver_sans.split() | unique %}
diff --git a/roles/kubernetes/master/templates/kubeadm-config.v1alpha2.yaml.j2 b/roles/kubernetes/master/templates/kubeadm-config.v1alpha2.yaml.j2
index cf73312935eddcfdcd58cb4d97f93609de36d0d7..141087d3dd1c029ed338e3192e80238bb5fc22d3 100644
--- a/roles/kubernetes/master/templates/kubeadm-config.v1alpha2.yaml.j2
+++ b/roles/kubernetes/master/templates/kubeadm-config.v1alpha2.yaml.j2
@@ -84,6 +84,9 @@ apiServerExtraArgs:
   oidc-groups-claim: {{ kube_oidc_groups_claim }}
 {%   endif %}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+  authentication-token-webhook-config-file: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% if kube_encrypt_secret_data %}
   experimental-encryption-provider-config: {{ kube_cert_dir }}/secrets_encryption.yaml
 {% endif %}
@@ -146,7 +149,7 @@ controllerManagerExtraVolumes:
   mountPath: {{ kube_config_dir }}/cloud_config
 {% endif %}
 {% endif %}
-{% if kubernetes_audit or kube_basic_auth|default(true) or kube_token_auth|default(true) %}
+{% if kubernetes_audit or kube_basic_auth|default(true) or kube_token_auth|default(true) or kube_webhook_token_auth|default(false) %}
 apiServerExtraVolumes:
 {% if kube_basic_auth|default(true) %}
 - name: basic-auth-config
@@ -158,6 +161,11 @@ apiServerExtraVolumes:
   hostPath: {{ kube_token_dir }}
   mountPath: {{ kube_token_dir }}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+- name: webhook-token-auth-config
+  hostPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+  mountPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% if kubernetes_audit %}
 - name: {{ audit_policy_name }}
   hostPath: {{ audit_policy_hostpath }}
diff --git a/roles/kubernetes/master/templates/kubeadm-config.v1alpha3.yaml.j2 b/roles/kubernetes/master/templates/kubeadm-config.v1alpha3.yaml.j2
index 6238dffd9c25abc256e3af519a36076655eba530..9cba6a40f1321884dfa74d74ad649be14927e6c8 100644
--- a/roles/kubernetes/master/templates/kubeadm-config.v1alpha3.yaml.j2
+++ b/roles/kubernetes/master/templates/kubeadm-config.v1alpha3.yaml.j2
@@ -94,6 +94,9 @@ apiServerExtraArgs:
   oidc-groups-claim: {{ kube_oidc_groups_claim }}
 {%   endif %}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+  authentication-token-webhook-config-file: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% if kube_encrypt_secret_data %}
   experimental-encryption-provider-config: {{ kube_cert_dir }}/secrets_encryption.yaml
 {% endif %}
@@ -147,7 +150,7 @@ schedulerExtraArgs:
   {{ key }}: "{{ kube_kubeadm_scheduler_extra_args[key] }}"
 {% endfor %}
 {% endif %}
-{% if kubernetes_audit or kube_basic_auth|default(true) or kube_token_auth|default(true) or ( cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws"] ) or apiserver_extra_volumes %}
+{% if kubernetes_audit or kube_basic_auth|default(true) or kube_token_auth|default(true) or kube_webhook_token_auth|default(false) or ( cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws"] ) or apiserver_extra_volumes %}
 apiServerExtraVolumes:
 {% if cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws", "external"] %}
 - name: cloud-config
@@ -164,6 +167,11 @@ apiServerExtraVolumes:
   hostPath: {{ kube_token_dir }}
   mountPath: {{ kube_token_dir }}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+- name: webhook-token-auth-config
+  hostPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+  mountPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% if kubernetes_audit %}
 - name: {{ audit_policy_name }}
   hostPath: {{ audit_policy_hostpath }}
diff --git a/roles/kubernetes/master/templates/kubeadm-config.v1beta1.yaml.j2 b/roles/kubernetes/master/templates/kubeadm-config.v1beta1.yaml.j2
index 6a346cd8315f3819db4bdfc2839d97df6dbdcd18..f2589c9bbfc808e71ec1cd22b099da4eab4e9f8a 100644
--- a/roles/kubernetes/master/templates/kubeadm-config.v1beta1.yaml.j2
+++ b/roles/kubernetes/master/templates/kubeadm-config.v1beta1.yaml.j2
@@ -92,6 +92,9 @@ apiServer:
     oidc-groups-claim: {{ kube_oidc_groups_claim }}
 {%   endif %}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+    authentication-token-webhook-config-file: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% if kube_encrypt_secret_data %}
     encryption-provider-config: {{ kube_cert_dir }}/secrets_encryption.yaml
 {% endif %}
@@ -119,7 +122,7 @@ apiServer:
 {% elif cloud_provider is defined and cloud_provider in ["external"] %}
     cloud-config: {{ kube_config_dir }}/cloud_config
 {% endif %}
-{% if kubernetes_audit or kube_basic_auth|default(true) or kube_token_auth|default(true) or ( cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws"] ) or apiserver_extra_volumes %}
+{% if kubernetes_audit or kube_basic_auth|default(true) or kube_token_auth|default(true) or kube_webhook_token_auth|default(false) or ( cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws"] ) or apiserver_extra_volumes %}
   extraVolumes:
 {% if cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws", "external"] %}
   - name: cloud-config
@@ -136,6 +139,11 @@ apiServer:
     hostPath: {{ kube_token_dir }}
     mountPath: {{ kube_token_dir }}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+  - name: webhook-token-auth-config
+    hostPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+    mountPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% if kubernetes_audit %}
   - name: {{ audit_policy_name }}
     hostPath: {{ audit_policy_hostpath }}
diff --git a/roles/kubernetes/master/templates/webhook-token-auth-config.yaml.j2 b/roles/kubernetes/master/templates/webhook-token-auth-config.yaml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..15559732c6a940190aa48edb5d14c90eab3a2c80
--- /dev/null
+++ b/roles/kubernetes/master/templates/webhook-token-auth-config.yaml.j2
@@ -0,0 +1,17 @@
+# clusters refers to the remote service.
+clusters:
+- name: webhook-token-auth-cluster
+  cluster:
+    server: {{ kube_webhook_token_auth_url }}
+
+# users refers to the API server's webhook configuration.
+users:
+- name: webhook-token-auth-user
+
+# kubeconfig files require a context. Provide one for the API server.
+current-context: webhook-token-auth
+contexts:
+- context:
+    cluster: webhook-token-auth-cluster
+    user: webhook-token-auth-user
+  name: webhook-token-auth
\ No newline at end of file