Skip to content

Commit 8296a06

Browse files
committed
Move configuration from kube_oidc to own top-level configuration. Expand the entire Struct-Auth configuration and only create the configurations if the feature gate is activated.
1 parent 521f471 commit 8296a06

File tree

8 files changed

+117
-56
lines changed

8 files changed

+117
-56
lines changed

inventory/sample/group_vars/k8s_cluster/k8s-cluster.yml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ credentials_dir: "{{ inventory_dir }}/credentials"
4040

4141
## It is possible to activate / deactivate selected authentication methods (oidc, static token auth)
4242
# kube_oidc_auth: false
43-
# kube_oidc_structured_auth: false
4443
# kube_token_auth: false
4544

4645
## Variables for OpenID Connect Configuration https://kubernetes.io/docs/admin/authentication/
@@ -55,13 +54,6 @@ credentials_dir: "{{ inventory_dir }}/credentials"
5554
# kube_oidc_groups_claim: groups
5655
# kube_oidc_groups_prefix: 'oidc:'
5756

58-
# Variables are only valid if kube_oidc_structured_auth is set to true
59-
# kube_oidc_uid_clam: "sub"
60-
# kube_oidc_audiences: []
61-
# kube_oidc_additional_user_validation_rules:
62-
# - expression: "!user.username.startsWith('system:')"
63-
# error_message: "username cannot used reserved system: prefix"
64-
6557
## Variables to control webhook authn/authz
6658
# kube_webhook_token_auth: false
6759
# kube_webhook_token_auth_url: https://...
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
kube_apiserver_structured_auth_jwt_issuers: []
3+
# Example JWT issuer configuration:
4+
# kube_apiserver_structured_auth_jwt_issuers:
5+
# - issuer:
6+
# url: "https://issuer1.example.com"
7+
# audiences:
8+
# - audience1
9+
# - audience2
10+
# audienceMatchPolicy: MatchAny
11+
# claimMappings:
12+
# username:
13+
# expression: "claims.username"
14+
# groups:
15+
# expression: "claims.groups"
16+
# uid:
17+
# expression: "claims.uid"
18+
# userValidationRules:
19+
# - expression: "!user.username.startsWith('system:')"
20+
# message: "username cannot use reserved system: prefix"
21+
# - issuer:
22+
# url: "https://issuer2.example.com"
23+
# discoveryURL: "https://discovery.example.com/.well-known/openid-configuration"
24+
# audiences:
25+
# - audience3
26+
# - audience4
27+
# audienceMatchPolicy: MatchAny
28+
# claimMappings:
29+
# username:
30+
# expression: "claims.username"
31+
# groups:
32+
# expression: "claims.groups"
33+
# uid:
34+
# expression: "claims.uid"
35+
# userValidationRules:
36+
# - expression: "!user.username.startsWith('kubespray:')"
37+
# message: "username cannot use reserved kubespray: prefix"

roles/kubernetes/control-plane/defaults/main/main.yml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ kube_api_runtime_config: []
139139
## Enable/Disable Kube API Server Authentication Methods
140140
kube_token_auth: false
141141
kube_oidc_auth: false
142-
kube_oidc_structured_auth: false
143142

144143
## Variables for webhook token auth https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication
145144
kube_webhook_token_auth: false
@@ -163,19 +162,15 @@ kube_apiserver_admission_plugins_podnodeselector_default_node_selector: ""
163162
# kube_oidc_client_id: kubernetes
164163
## Optional settings for OIDC
165164
# kube_oidc_username_claim: sub
166-
kube_oidc_username_prefix: "oidc:"
165+
# kube_oidc_username_prefix: "oidc:"
167166
# kube_oidc_groups_claim: groups
168-
kube_oidc_groups_prefix: "oidc:"
169-
kube_oidc_uid_claim: "sub"
167+
# kube_oidc_groups_prefix: "oidc:"
168+
# kube_oidc_uid_claim: "sub"
170169
# Copy oidc CA file to the following path if needed
171170
# kube_oidc_ca_file: {{ kube_cert_dir }}/ca.pem
172171
# Optionally include a base64-encoded oidc CA cert
173172
# kube_oidc_ca_cert: c3RhY2thYnVzZS5jb20...
174173

175-
# Variables are only valid if kube_oidc_structured_auth is true
176-
kube_oidc_audiences: []
177-
kube_oidc_additional_user_validation_rules: []
178-
179174
# List of the preferred NodeAddressTypes to use for kubelet connections.
180175
kubelet_preferred_address_types: 'InternalDNS,InternalIP,Hostname,ExternalDNS,ExternalIP'
181176

roles/kubernetes/control-plane/tasks/kubeadm-setup.yml

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,32 @@
8383
when: kube_apiserver_tracing
8484

8585
- name: Kubeadm | Configure Structured Authentication
86+
vars:
87+
all_kube_apiserver_feature_gates: "{{ kube_apiserver_feature_gates + kube_feature_gates }}"
8688
when:
87-
- kube_oidc_auth
88-
- kube_oidc_structured_auth
89+
- not kube_oidc_auth
90+
- ("StructuredAuthenticationConfiguration=true" in all_kube_apiserver_feature_gates and kube_version | regex_replace("^v", "") is version("1.30.0", "<", version_type="semver"))
91+
or
92+
("StructuredAuthenticationConfiguration=false" not in all_kube_apiserver_feature_gates and kube_version | regex_replace("^v", "") is version("1.30.0", ">=", version_type="semver"))
8993
block:
90-
- name: Kubeadm | Check if Structured Authentication Configuration is supported
91-
fail:
92-
msg: "OIDC structured auth is supported only from Kubernetes 1.30.0"
93-
when:
94-
- kube_version is version('1.30.0', '<')
95-
9694
- name: Kubeadm | Create apiserver authentication config directory
9795
file:
9896
path: "{{ kube_config_dir }}/authentication"
9997
state: directory
10098
mode: "0640"
10199

100+
- name: Merge additional userValidationRules
101+
set_fact:
102+
kube_apiserver_structured_auth_jwt_issuers: >-
103+
{{
104+
kube_apiserver_structured_auth_jwt_issuers | map('combine', {
105+
'userValidationRules': item.userValidationRules + additional_user_validation_rules
106+
}) | list
107+
}}
108+
loop: "{{ kube_apiserver_structured_auth_jwt_issuers }}"
109+
loop_control:
110+
loop_var: item
111+
102112
- name: Kubeadm | Write apiserver authentication config yaml
103113
template:
104114
src: apiserver-authentication-config.yaml.j2
Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,48 @@
11
---
22
apiVersion: apiserver.config.k8s.io/v1beta1
33
kind: AuthenticationConfiguration
4+
{% if kube_apiserver_structured_auth_jwt_issuers | length > 0 %}
45
jwt:
5-
- issuer:
6-
audiences: {{ ([kube_oidc_client_id] + kube_oidc_audiences) | to_json }}
7-
audienceMatchPolicy: MatchAny
8-
{% if kube_oidc_ca_file is defined %}
9-
certificateAuthority: "{{ kube_oidc_ca_file }}"
6+
{% for issuer in kube_apiserver_structured_auth_jwt_issuers %}
7+
- issuer:
8+
url: "{{ issuer.issuer.url }}"
9+
{% if issuer.issuer.discoveryURL is defined %}
10+
discoveryURL: "{{ issuer.issuer.discoveryURL }}"
1011
{% endif %}
11-
url: "{{ kube_oidc_url }}"
12-
claimMappings:
13-
{% if kube_oidc_username_claim is defined %}
14-
username:
15-
claim: "{{ kube_oidc_username_claim }}"
16-
prefix: "{{ kube_oidc_username_prefix }}"
12+
audiences:
13+
{% for audience in issuer.issuer.audiences %}
14+
- {{ audience }}
15+
{% endfor %}
16+
audienceMatchPolicy: {{ issuer.issuer.audienceMatchPolicy }}
17+
{% if issuer.claimValidationRules is defined %}
18+
claimValidationRules:
19+
{% for validationRule in issuer.claimValidationRules %}
20+
expression: "{{ validationRule.expression }}"
21+
message: "{{ validationRule.message }}"
22+
{% endfor %}
1723
{% endif %}
18-
{% if kube_oidc_groups_claim is defined %}
19-
groups:
20-
claim: "{{ kube_oidc_groups_claim }}"
21-
prefix: "{{ kube_oidc_groups_prefix }}"
24+
claimMappings:
25+
username:
26+
expression: "{{ issuer.claimMappings.username.expression }}"
27+
groups:
28+
expression: "{{ issuer.claimMappings.groups.expression }}"
29+
uid:
30+
expression: "{{ issuer.claimMappings.uid.expression }}"
31+
{% if issuer.claimMappings.extra is defined %}
32+
extra:
33+
{% for extra in issuer.claimMappings.extra %}
34+
- key: "{{ extra.key }}"
35+
expression: "{{ extra.expression }}"
36+
{% endfor %}
2237
{% endif %}
23-
{% if kube_oidc_uid_claim is defined %}
24-
uid:
25-
claim: "{{ kube_oidc_uid_claim }}"
38+
{% if issuer.userValidationRules | length > 0 %}
39+
userValidationRules:
40+
{% for rule in issuer.userValidationRules %}
41+
- expression: "{{ rule.expression }}"
42+
message: "{{ rule.message }}"
43+
{% endfor %}
2644
{% endif %}
27-
userValidationRules:
28-
{% for rule in kube_oidc_user_validation_rules + kube_oidc_additional_user_validation_rules %}
29-
- expression: "{{ rule.expression }}"
30-
message: "{{ rule.message }}"
3145
{% endfor %}
46+
{% else %}
47+
jwt:
48+
{% endif %}

roles/kubernetes/control-plane/templates/kubeadm-config.v1beta3.yaml.j2

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ apiServer:
154154
{% if kube_apiserver_service_account_lookup %}
155155
service-account-lookup: "{{ kube_apiserver_service_account_lookup }}"
156156
{% endif %}
157-
{% if kube_oidc_auth and kube_oidc_url is defined and kube_oidc_client_id is defined and not kube_oidc_structured_auth %}
157+
{% if kube_oidc_auth and kube_oidc_url is defined and kube_oidc_client_id is defined %}
158158
oidc-issuer-url: "{{ kube_oidc_url }}"
159159
oidc-client-id: "{{ kube_oidc_client_id }}"
160160
{% if kube_oidc_ca_file is defined %}
@@ -173,7 +173,7 @@ apiServer:
173173
oidc-groups-prefix: "{{ kube_oidc_groups_prefix }}"
174174
{% endif %}
175175
{% endif %}
176-
{% if kube_oidc_auth and kube_oidc_url is defined and kube_oidc_client_id is defined and kube_oidc_structured_auth %}
176+
{% if not kube_oidc_auth %}
177177
authentication-config: {{ kube_config_dir }}/authentication/apiserver-authentication-config.yaml
178178
{% endif %}
179179
{% if kube_webhook_token_auth | default(false) %}
@@ -264,7 +264,7 @@ apiServer:
264264
readOnly: false
265265
pathType: DirectoryOrCreate
266266
{% endif %}
267-
{% if kube_oidc_structured_auth %}
267+
{% if not kube_oidc_auth %}
268268
- name: structauth
269269
hostPath: {{ kube_config_dir }}/authentication
270270
mountPath: {{ kube_config_dir }}/authentication

roles/kubernetes/control-plane/templates/kubeadm-config.v1beta4.yaml.j2

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ apiServer:
182182
- name: service-account-lookup
183183
value: "{{ kube_apiserver_service_account_lookup }}"
184184
{% endif %}
185-
{% if kube_oidc_auth | default(false) and kube_oidc_url is defined and kube_oidc_client_id is defined %}
185+
{% if kube_oidc_auth and kube_oidc_url is defined and kube_oidc_client_id is defined %}
186186
- name: oidc-issuer-url
187187
value: "{{ kube_oidc_url }}"
188188
- name: oidc-client-id
@@ -208,6 +208,10 @@ apiServer:
208208
value: "{{ kube_oidc_groups_prefix }}"
209209
{% endif %}
210210
{% endif %}
211+
{% if not kube_oidc_auth %}
212+
- name: authentication-config
213+
value: "{{ kube_config_dir }}/authentication/apiserver-authentication-config.yaml"
214+
{% endif %}
211215
{% if kube_webhook_token_auth | default(false) %}
212216
- name: authentication-token-webhook-config-file
213217
value: "{{ kube_config_dir }}/webhook-token-auth-config.yaml"
@@ -317,6 +321,13 @@ apiServer:
317321
readOnly: false
318322
pathType: DirectoryOrCreate
319323
{% endif %}
324+
{% if not kube_oidc_auth %}
325+
- name: structauth
326+
hostPath: {{ kube_config_dir }}/authentication
327+
mountPath: {{ kube_config_dir }}/authentication
328+
readOnly: true
329+
pathType: DirectoryOrCreate
330+
{% endif %}
320331
{% if kube_apiserver_tracing %}
321332
- name: tracing
322333
hostPath: {{ kube_config_dir }}/tracing

roles/kubernetes/control-plane/vars/main.yaml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ kube_apiserver_admission_plugins_needs_configuration:
77
- PodSecurity
88
- PodNodeSelector
99
- ResourceQuota
10-
# default user validation rules for OIDC
11-
kube_oidc_user_validation_rules:
12-
- expression: "!user.username.startsWith('system:')"
13-
message: "username cannot used reserved system: prefix"
14-
- expression: "user.groups.all(group, !group.startsWith('system:'))"
15-
message: "groups cannot used reserved system: prefix"
10+
additional_user_validation_rules:
11+
- expression: "!user.username.startsWith('system:')"
12+
message: "username cannot used reserved system: prefix"
13+
- expression: "user.groups.all(group, !group.startsWith('system:'))"
14+
message: "groups cannot used reserved system: prefix"

0 commit comments

Comments
 (0)