Skip to content

Commit 5c75e62

Browse files
Merge pull request #2680 from richardsonnick/tls-adherance-fate
Add TLS adherence feature gate
2 parents bfddfd9 + b1be674 commit 5c75e62

22 files changed

Lines changed: 860 additions & 0 deletions
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
apiVersion: apiextensions.k8s.io/v1
2+
name: "APIServer"
3+
crdName: apiservers.config.openshift.io
4+
featureGates:
5+
- TLSAdherence
6+
tests:
7+
onCreate:
8+
- name: Should be able to create without tlsAdherence
9+
initial: |
10+
apiVersion: config.openshift.io/v1
11+
kind: APIServer
12+
spec: {}
13+
expected: |
14+
apiVersion: config.openshift.io/v1
15+
kind: APIServer
16+
spec:
17+
audit:
18+
profile: Default
19+
- name: Should be able to create with tlsAdherence set to LegacyAdheringComponentsOnly
20+
initial: |
21+
apiVersion: config.openshift.io/v1
22+
kind: APIServer
23+
spec:
24+
tlsAdherence: LegacyAdheringComponentsOnly
25+
expected: |
26+
apiVersion: config.openshift.io/v1
27+
kind: APIServer
28+
spec:
29+
audit:
30+
profile: Default
31+
tlsAdherence: LegacyAdheringComponentsOnly
32+
- name: Should be able to create with tlsAdherence set to StrictAllComponents
33+
initial: |
34+
apiVersion: config.openshift.io/v1
35+
kind: APIServer
36+
spec:
37+
tlsAdherence: StrictAllComponents
38+
expected: |
39+
apiVersion: config.openshift.io/v1
40+
kind: APIServer
41+
spec:
42+
audit:
43+
profile: Default
44+
tlsAdherence: StrictAllComponents
45+
- name: Should reject invalid tlsAdherence value
46+
initial: |
47+
apiVersion: config.openshift.io/v1
48+
kind: APIServer
49+
spec:
50+
tlsAdherence: InvalidValue
51+
expectedError: 'spec.tlsAdherence: Unsupported value: "InvalidValue": supported values: "LegacyAdheringComponentsOnly", "StrictAllComponents"'
52+
onUpdate:
53+
- name: Should be able to update tlsAdherence from LegacyAdheringComponentsOnly to StrictAllComponents
54+
initial: |
55+
apiVersion: config.openshift.io/v1
56+
kind: APIServer
57+
spec:
58+
tlsAdherence: LegacyAdheringComponentsOnly
59+
updated: |
60+
apiVersion: config.openshift.io/v1
61+
kind: APIServer
62+
spec:
63+
tlsAdherence: StrictAllComponents
64+
expected: |
65+
apiVersion: config.openshift.io/v1
66+
kind: APIServer
67+
spec:
68+
audit:
69+
profile: Default
70+
tlsAdherence: StrictAllComponents
71+
- name: Should be able to update tlsAdherence from StrictAllComponents to LegacyAdheringComponentsOnly
72+
initial: |
73+
apiVersion: config.openshift.io/v1
74+
kind: APIServer
75+
spec:
76+
tlsAdherence: StrictAllComponents
77+
updated: |
78+
apiVersion: config.openshift.io/v1
79+
kind: APIServer
80+
spec:
81+
tlsAdherence: LegacyAdheringComponentsOnly
82+
expected: |
83+
apiVersion: config.openshift.io/v1
84+
kind: APIServer
85+
spec:
86+
audit:
87+
profile: Default
88+
tlsAdherence: LegacyAdheringComponentsOnly
89+
- name: Should be able to set tlsAdherence from unset on update
90+
initial: |
91+
apiVersion: config.openshift.io/v1
92+
kind: APIServer
93+
spec: {}
94+
updated: |
95+
apiVersion: config.openshift.io/v1
96+
kind: APIServer
97+
spec:
98+
tlsAdherence: StrictAllComponents
99+
expected: |
100+
apiVersion: config.openshift.io/v1
101+
kind: APIServer
102+
spec:
103+
audit:
104+
profile: Default
105+
tlsAdherence: StrictAllComponents
106+
- name: Should not allow removing tlsAdherence once set
107+
initial: |
108+
apiVersion: config.openshift.io/v1
109+
kind: APIServer
110+
spec:
111+
tlsAdherence: StrictAllComponents
112+
updated: |
113+
apiVersion: config.openshift.io/v1
114+
kind: APIServer
115+
spec: {}
116+
expectedError: "tlsAdherence may not be removed once set"

config/v1/types_apiserver.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type APIServer struct {
3434
Status APIServerStatus `json:"status"`
3535
}
3636

37+
// +openshift:validation:FeatureGateAwareXValidation:featureGate=TLSAdherence,rule="has(oldSelf.tlsAdherence) ? has(self.tlsAdherence) : true",message="tlsAdherence may not be removed once set"
3738
type APIServerSpec struct {
3839
// servingCert is the TLS cert info for serving secure traffic. If not specified, operator managed certificates
3940
// will be used for serving secure traffic.
@@ -62,6 +63,39 @@ type APIServerSpec struct {
6263
// The current default is the Intermediate profile.
6364
// +optional
6465
TLSSecurityProfile *TLSSecurityProfile `json:"tlsSecurityProfile,omitempty"`
66+
// tlsAdherence controls if components in the cluster adhere to the TLS security profile
67+
// configured on this APIServer resource.
68+
//
69+
// Valid values are "LegacyAdheringComponentsOnly" and "StrictAllComponents".
70+
//
71+
// When set to "LegacyAdheringComponentsOnly", components that already honor the
72+
// cluster-wide TLS profile continue to do so. Components that do not already honor
73+
// it continue to use their individual TLS configurations.
74+
//
75+
// When set to "StrictAllComponents", all components must honor the configured TLS
76+
// profile unless they have a component-specific TLS configuration that overrides
77+
// it. This mode is recommended for security-conscious deployments and is required
78+
// for certain compliance frameworks.
79+
//
80+
// Note: Some components such as Kubelet and IngressController have their own
81+
// dedicated TLS configuration mechanisms via KubeletConfig and IngressController
82+
// CRs respectively. When these component-specific TLS configurations are set,
83+
// they take precedence over the cluster-wide tlsSecurityProfile. When not set,
84+
// these components fall back to the cluster-wide default.
85+
//
86+
// Components that encounter an unknown value for tlsAdherence should treat it
87+
// as "StrictAllComponents" and log a warning to ensure forward compatibility
88+
// while defaulting to the more secure behavior.
89+
//
90+
// This field is optional.
91+
// When omitted, this means the user has no opinion and the platform is left
92+
// to choose reasonable defaults. These defaults are subject to change over time.
93+
// The current default is LegacyAdheringComponentsOnly.
94+
//
95+
// Once set, this field may be changed to a different value, but may not be removed.
96+
// +openshift:enable:FeatureGate=TLSAdherence
97+
// +optional
98+
TLSAdherence TLSAdherencePolicy `json:"tlsAdherence,omitempty"`
6599
// audit specifies the settings for audit configuration to be applied to all OpenShift-provided
66100
// API servers in the cluster.
67101
// +optional
@@ -237,6 +271,35 @@ const (
237271
type APIServerStatus struct {
238272
}
239273

274+
// TLSAdherencePolicy defines which components adhere to the TLS security profile.
275+
// Implementors should use the ShouldHonorClusterTLSProfile helper function from library-go
276+
// rather than checking these values directly.
277+
// +kubebuilder:validation:Enum=LegacyAdheringComponentsOnly;StrictAllComponents
278+
type TLSAdherencePolicy string
279+
280+
const (
281+
// TLSAdherencePolicyNoOpinion represents an empty/unset value for tlsAdherence.
282+
// This value cannot be explicitly set and is only present when the field is omitted.
283+
// When the field is omitted, the cluster defaults to LegacyAdheringComponentsOnly
284+
// behavior. Components should treat this the same as LegacyAdheringComponentsOnly.
285+
TLSAdherencePolicyNoOpinion TLSAdherencePolicy = ""
286+
287+
// TLSAdherencePolicyLegacyAdheringComponentsOnly maintains backward-compatible behavior.
288+
// Components that already honor the cluster-wide TLS profile (such as kube-apiserver,
289+
// openshift-apiserver, oauth-apiserver, and others) continue to do so. Components that do
290+
// not already honor it continue to use their individual TLS configurations (e.g.,
291+
// IngressController.spec.tlsSecurityProfile, KubeletConfig.spec.tlsSecurityProfile,
292+
// or component defaults). No additional components are required to start honoring the
293+
// cluster-wide profile in this mode.
294+
TLSAdherencePolicyLegacyAdheringComponentsOnly TLSAdherencePolicy = "LegacyAdheringComponentsOnly"
295+
296+
// TLSAdherencePolicyStrictAllComponents means all components must honor the configured TLS
297+
// profile unless they have a component-specific TLS configuration that overrides it.
298+
// This mode is recommended for security-conscious deployments and is required
299+
// for certain compliance frameworks.
300+
TLSAdherencePolicyStrictAllComponents TLSAdherencePolicy = "StrictAllComponents"
301+
)
302+
240303
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
241304

242305
// Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).

config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,42 @@ spec:
292292
type: array
293293
x-kubernetes-list-type: atomic
294294
type: object
295+
tlsAdherence:
296+
description: |-
297+
tlsAdherence controls if components in the cluster adhere to the TLS security profile
298+
configured on this APIServer resource.
299+
300+
Valid values are "LegacyAdheringComponentsOnly" and "StrictAllComponents".
301+
302+
When set to "LegacyAdheringComponentsOnly", components that already honor the
303+
cluster-wide TLS profile continue to do so. Components that do not already honor
304+
it continue to use their individual TLS configurations.
305+
306+
When set to "StrictAllComponents", all components must honor the configured TLS
307+
profile unless they have a component-specific TLS configuration that overrides
308+
it. This mode is recommended for security-conscious deployments and is required
309+
for certain compliance frameworks.
310+
311+
Note: Some components such as Kubelet and IngressController have their own
312+
dedicated TLS configuration mechanisms via KubeletConfig and IngressController
313+
CRs respectively. When these component-specific TLS configurations are set,
314+
they take precedence over the cluster-wide tlsSecurityProfile. When not set,
315+
these components fall back to the cluster-wide default.
316+
317+
Components that encounter an unknown value for tlsAdherence should treat it
318+
as "StrictAllComponents" and log a warning to ensure forward compatibility
319+
while defaulting to the more secure behavior.
320+
321+
This field is optional.
322+
When omitted, this means the user has no opinion and the platform is left
323+
to choose reasonable defaults. These defaults are subject to change over time.
324+
The current default is LegacyAdheringComponentsOnly.
325+
326+
Once set, this field may be changed to a different value, but may not be removed.
327+
enum:
328+
- LegacyAdheringComponentsOnly
329+
- StrictAllComponents
330+
type: string
295331
tlsSecurityProfile:
296332
description: |-
297333
tlsSecurityProfile specifies settings for TLS connections for externally exposed servers.
@@ -427,6 +463,9 @@ spec:
427463
type: string
428464
type: object
429465
type: object
466+
x-kubernetes-validations:
467+
- message: tlsAdherence may not be removed once set
468+
rule: 'has(oldSelf.tlsAdherence) ? has(self.tlsAdherence) : true'
430469
status:
431470
description: status holds observed values from the cluster. They may not
432471
be overridden.

config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,42 @@ spec:
292292
type: array
293293
x-kubernetes-list-type: atomic
294294
type: object
295+
tlsAdherence:
296+
description: |-
297+
tlsAdherence controls if components in the cluster adhere to the TLS security profile
298+
configured on this APIServer resource.
299+
300+
Valid values are "LegacyAdheringComponentsOnly" and "StrictAllComponents".
301+
302+
When set to "LegacyAdheringComponentsOnly", components that already honor the
303+
cluster-wide TLS profile continue to do so. Components that do not already honor
304+
it continue to use their individual TLS configurations.
305+
306+
When set to "StrictAllComponents", all components must honor the configured TLS
307+
profile unless they have a component-specific TLS configuration that overrides
308+
it. This mode is recommended for security-conscious deployments and is required
309+
for certain compliance frameworks.
310+
311+
Note: Some components such as Kubelet and IngressController have their own
312+
dedicated TLS configuration mechanisms via KubeletConfig and IngressController
313+
CRs respectively. When these component-specific TLS configurations are set,
314+
they take precedence over the cluster-wide tlsSecurityProfile. When not set,
315+
these components fall back to the cluster-wide default.
316+
317+
Components that encounter an unknown value for tlsAdherence should treat it
318+
as "StrictAllComponents" and log a warning to ensure forward compatibility
319+
while defaulting to the more secure behavior.
320+
321+
This field is optional.
322+
When omitted, this means the user has no opinion and the platform is left
323+
to choose reasonable defaults. These defaults are subject to change over time.
324+
The current default is LegacyAdheringComponentsOnly.
325+
326+
Once set, this field may be changed to a different value, but may not be removed.
327+
enum:
328+
- LegacyAdheringComponentsOnly
329+
- StrictAllComponents
330+
type: string
295331
tlsSecurityProfile:
296332
description: |-
297333
tlsSecurityProfile specifies settings for TLS connections for externally exposed servers.
@@ -427,6 +463,9 @@ spec:
427463
type: string
428464
type: object
429465
type: object
466+
x-kubernetes-validations:
467+
- message: tlsAdherence may not be removed once set
468+
rule: 'has(oldSelf.tlsAdherence) ? has(self.tlsAdherence) : true'
430469
status:
431470
description: status holds observed values from the cluster. They may not
432471
be overridden.

config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,42 @@ spec:
224224
type: array
225225
x-kubernetes-list-type: atomic
226226
type: object
227+
tlsAdherence:
228+
description: |-
229+
tlsAdherence controls if components in the cluster adhere to the TLS security profile
230+
configured on this APIServer resource.
231+
232+
Valid values are "LegacyAdheringComponentsOnly" and "StrictAllComponents".
233+
234+
When set to "LegacyAdheringComponentsOnly", components that already honor the
235+
cluster-wide TLS profile continue to do so. Components that do not already honor
236+
it continue to use their individual TLS configurations.
237+
238+
When set to "StrictAllComponents", all components must honor the configured TLS
239+
profile unless they have a component-specific TLS configuration that overrides
240+
it. This mode is recommended for security-conscious deployments and is required
241+
for certain compliance frameworks.
242+
243+
Note: Some components such as Kubelet and IngressController have their own
244+
dedicated TLS configuration mechanisms via KubeletConfig and IngressController
245+
CRs respectively. When these component-specific TLS configurations are set,
246+
they take precedence over the cluster-wide tlsSecurityProfile. When not set,
247+
these components fall back to the cluster-wide default.
248+
249+
Components that encounter an unknown value for tlsAdherence should treat it
250+
as "StrictAllComponents" and log a warning to ensure forward compatibility
251+
while defaulting to the more secure behavior.
252+
253+
This field is optional.
254+
When omitted, this means the user has no opinion and the platform is left
255+
to choose reasonable defaults. These defaults are subject to change over time.
256+
The current default is LegacyAdheringComponentsOnly.
257+
258+
Once set, this field may be changed to a different value, but may not be removed.
259+
enum:
260+
- LegacyAdheringComponentsOnly
261+
- StrictAllComponents
262+
type: string
227263
tlsSecurityProfile:
228264
description: |-
229265
tlsSecurityProfile specifies settings for TLS connections for externally exposed servers.
@@ -359,6 +395,9 @@ spec:
359395
type: string
360396
type: object
361397
type: object
398+
x-kubernetes-validations:
399+
- message: tlsAdherence may not be removed once set
400+
rule: 'has(oldSelf.tlsAdherence) ? has(self.tlsAdherence) : true'
362401
status:
363402
description: status holds observed values from the cluster. They may not
364403
be overridden.

config/v1/zz_generated.featuregated-crd-manifests.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ apiservers.config.openshift.io:
88
FeatureGates:
99
- KMSEncryption
1010
- KMSEncryptionProvider
11+
- TLSAdherence
1112
FilenameOperatorName: config-operator
1213
FilenameOperatorOrdering: "01"
1314
FilenameRunLevel: "0000_10"

0 commit comments

Comments
 (0)