Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions config/v1/types_apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,35 @@ type APIServerSpec struct {
// The current default is the Intermediate profile.
// +optional
TLSSecurityProfile *TLSSecurityProfile `json:"tlsSecurityProfile,omitempty"`
// tlsAdherence controls which components in the cluster adhere to the TLS security profile
// configured on this APIServer resource.
//
// Valid values are "LegacyExternalAPIServerComponentsOnly" and "StrictAllComponents".
//
// When set to "LegacyExternalAPIServerComponentsOnly", only the externally exposed
// API server components (kube-apiserver, openshift-apiserver, oauth-apiserver) honor the configured
// TLS profile. Other components continue to use their individual TLS configurations.
//
// When set to "StrictAllComponents", all components must honor the configured TLS profile.
// This mode is recommended for security-conscious deployments and is required for
// certain compliance frameworks.
//
// Note: The Kubelet and IngressController components are excluded from tlsAdherence control
// as they have their own dedicated TLS configuration mechanisms via KubeletConfig and
// IngressController CRs respectively.
Comment on lines +78 to +80
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once we settle on this in the EP, we should update this.

My current expectation is that this isn't an exclusion but rather a preference scenario where, if specified, the Kubelet / Ingress Controller components will be configured with what is specified in their existing APIs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that makes sense. It positions apiserver as the truly cluster-wide default. And it is still aligned with the fact that other components may have their own special configuration knobs that override the default.

//
// Components that encounter an unknown value for tlsAdherence should treat it as "StrictAllComponents"
// and log a warning to ensure forward compatibility while defaulting to the more secure behavior.
//
// This field is optional. When omitted, it is interpreted as "no opinion" and the cluster
// defaults to LegacyExternalAPIServerComponentsOnly behavior. Future versions of OpenShift
Comment on lines +85 to +86
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have some standard terminology we like to use here for consistency. As an example:

// When omitted, this means the user has no opinion and the platform is left
// to choose reasonable defaults. These defaults are subject to change over time.
// The current default is All.

We should follow this convention as well so we aren't locked into a contractual default in case we want to do something like change the default behavior to strict but still give admins an option to specify that they want to stay on the legacy mode.

// may require explicitly setting this field to "StrictAllComponents" before upgrading.
// Administrators are encouraged to migrate to "StrictAllComponents" proactively.
//
// Once set, this field may be changed to a different value.
// +openshift:enable:FeatureGate=TLSAdherence
// +optional
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to configure validation on this field, and set the default.

// +kubebuilder:validation:items:Enum:=LegacyExternalAPIServerComponentsOnly;StrictAllComponents
// +kubebuilder:default:=LegacyExternalAPIServerComponentsOnly

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see you are defining the Enum validation on the type, which is fine. Let's also include the +kubebuilder:default marker there as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, reading the tlsAdherence description again, it seems like you are wanting it to be possible for an empty string to be allowed to be persisted for this field in etcd, which would allow us in theory to change the default semantic later in the future from legacy to strict without a change in the actual tlsAdherence value.

In practice, I think the problem with that idea is that each component essentially has their own implementation of this API and we'd have to do a really good job coordinating a semantic switch from legacy to strict.

What do folks think about:

  1. Actually writing LegacyExternalAPIServerComponentsOnly to etcd by default.
  2. Telling implementers they specifically only need to look for StrictAllComponents and will not have to worry about the possibility of "" with changing semantics later.
  3. When want to set StrictAllComponents as the new default, we make sure newly installed clusters get that, and we potentially block upgrades of clusters that still use LegacyExternalAPIServerComponentsOnly? Or maybe there's some other way to encourage users to switch to StrictAllComponents?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For configuration APIs we generally try to avoid setting the default via +kubebuilder:default marker so that we can change the default behavior of the "no-opinion" mechanism.

In this case, I don't think we will be doing that but I still wouldn't use the +kubebuilder:default marker because then we won't be able to distinguish whether or not the user intentionally set the field or if we defaulted it on their behalf and you technically get locked into that default being a contractual default.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so that we can change the default behavior of the "no-opinion" mechanism.

Thanks, I was hoping you'd have some good advice here. It is the intent to eventually make all components honor the cluster-wide default, so I supposed we'll just have to deal with trying to coordinate a semantic change across a bunch of components at once when the time comes.

To facilitate that, I'd suggest a library-go function somehow like this:

// in configv1
const TLSAdherenceNoOpinion = ""
func ShouldAllComponentsAdhere(tlsAdherence configv1.TLSAdherence) bool {
    if tlsAdherence == configv1.TLSAdherenceNoOpinion || tlsAdherence == configv1.LegacyExternalAPIServerComponentsOnly {
        return false
    }
    return true
}

And then when we want to change the semantic, we'd update that function to:

func ShouldAllComponentsAdhere(tlsAdherence configv1.TLSAdherence) bool {
    if tlsAdherence == configv1.LegacyExternalAPIServerComponentsOnly {
        return false
    }
    return true
}

TLSAdherence TLSAdherencePolicy `json:"tlsAdherence,omitempty"`
// audit specifies the settings for audit configuration to be applied to all OpenShift-provided
// API servers in the cluster.
// +optional
Expand Down Expand Up @@ -237,6 +266,23 @@ const (
type APIServerStatus struct {
}

// TLSAdherencePolicy defines which components adhere to the TLS security profile.
// +kubebuilder:validation:Enum=LegacyExternalAPIServerComponentsOnly;StrictAllComponents
type TLSAdherencePolicy string

const (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a constant for "" to represent the no-opinion case because we are using a non-pointer type for the field?

// TLSAdherenceLegacyExternalAPIServerComponentsOnly means only the externally exposed
// API server components (kube-apiserver, openshift-apiserver, oauth-apiserver) honor
// the configured TLS profile. Other components continue to use their individual TLS
// configurations.
TLSAdherenceLegacyExternalAPIServerComponentsOnly TLSAdherencePolicy = "LegacyExternalAPIServerComponentsOnly"

// TLSAdherenceStrictAllComponents means all components must honor the configured TLS
// profile. This mode is recommended for security-conscious deployments and is required
// for certain compliance frameworks.
Comment on lines +280 to +282
Copy link
Member

@joelanford joelanford Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should include a note here (and in the tlsAdherence description) that component-specific configurations can override the tlsSecurityProfile configuration?

TLSAdherenceStrictAllComponents TLSAdherencePolicy = "StrictAllComponents"
Comment on lines +274 to +283
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// TLSAdherenceLegacyExternalAPIServerComponentsOnly means only the externally exposed
// API server components (kube-apiserver, openshift-apiserver, oauth-apiserver) honor
// the configured TLS profile. Other components continue to use their individual TLS
// configurations.
TLSAdherenceLegacyExternalAPIServerComponentsOnly TLSAdherencePolicy = "LegacyExternalAPIServerComponentsOnly"
// TLSAdherenceStrictAllComponents means all components must honor the configured TLS
// profile. This mode is recommended for security-conscious deployments and is required
// for certain compliance frameworks.
TLSAdherenceStrictAllComponents TLSAdherencePolicy = "StrictAllComponents"
// TLSAdherencePolicyLegacyExternalAPIServerComponentsOnly means only the externally exposed
// API server components (kube-apiserver, openshift-apiserver, oauth-apiserver) honor
// the configured TLS profile. Other components continue to use their individual TLS
// configurations.
TLSAdherencePolicyLegacyExternalAPIServerComponentsOnly TLSAdherencePolicy = "LegacyExternalAPIServerComponentsOnly"
// TLSAdherencePolicyStrictAllComponents means all components must honor the configured TLS
// profile. This mode is recommended for security-conscious deployments and is required
// for certain compliance frameworks.
TLSAdherencePolicyStrictAllComponents TLSAdherencePolicy = "StrictAllComponents"

)

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,38 @@ spec:
type: array
x-kubernetes-list-type: atomic
type: object
tlsAdherence:
description: |-
tlsAdherence controls which components in the cluster adhere to the TLS security profile
configured on this APIServer resource.

Valid values are "LegacyExternalAPIServerComponentsOnly" and "StrictAllComponents".

When set to "LegacyExternalAPIServerComponentsOnly", only the externally exposed
API server components (kube-apiserver, openshift-apiserver, oauth-apiserver) honor the configured
TLS profile. Other components continue to use their individual TLS configurations.

When set to "StrictAllComponents", all components must honor the configured TLS profile.
This mode is recommended for security-conscious deployments and is required for
certain compliance frameworks.

Note: The Kubelet and IngressController components are excluded from tlsAdherence control
as they have their own dedicated TLS configuration mechanisms via KubeletConfig and
IngressController CRs respectively.

Components that encounter an unknown value for tlsAdherence should treat it as "StrictAllComponents"
and log a warning to ensure forward compatibility while defaulting to the more secure behavior.

This field is optional. When omitted, it is interpreted as "no opinion" and the cluster
defaults to LegacyExternalAPIServerComponentsOnly behavior. Future versions of OpenShift
may require explicitly setting this field to "StrictAllComponents" before upgrading.
Administrators are encouraged to migrate to "StrictAllComponents" proactively.

Once set, this field may be changed to a different value.
enum:
- LegacyExternalAPIServerComponentsOnly
- StrictAllComponents
type: string
tlsSecurityProfile:
description: |-
tlsSecurityProfile specifies settings for TLS connections for externally exposed servers.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,38 @@ spec:
type: array
x-kubernetes-list-type: atomic
type: object
tlsAdherence:
description: |-
tlsAdherence controls which components in the cluster adhere to the TLS security profile
configured on this APIServer resource.

Valid values are "LegacyExternalAPIServerComponentsOnly" and "StrictAllComponents".

When set to "LegacyExternalAPIServerComponentsOnly", only the externally exposed
API server components (kube-apiserver, openshift-apiserver, oauth-apiserver) honor the configured
TLS profile. Other components continue to use their individual TLS configurations.

When set to "StrictAllComponents", all components must honor the configured TLS profile.
This mode is recommended for security-conscious deployments and is required for
certain compliance frameworks.

Note: The Kubelet and IngressController components are excluded from tlsAdherence control
as they have their own dedicated TLS configuration mechanisms via KubeletConfig and
IngressController CRs respectively.

Components that encounter an unknown value for tlsAdherence should treat it as "StrictAllComponents"
and log a warning to ensure forward compatibility while defaulting to the more secure behavior.

This field is optional. When omitted, it is interpreted as "no opinion" and the cluster
defaults to LegacyExternalAPIServerComponentsOnly behavior. Future versions of OpenShift
may require explicitly setting this field to "StrictAllComponents" before upgrading.
Administrators are encouraged to migrate to "StrictAllComponents" proactively.

Once set, this field may be changed to a different value.
enum:
- LegacyExternalAPIServerComponentsOnly
- StrictAllComponents
type: string
tlsSecurityProfile:
description: |-
tlsSecurityProfile specifies settings for TLS connections for externally exposed servers.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,38 @@ spec:
type: array
x-kubernetes-list-type: atomic
type: object
tlsAdherence:
description: |-
tlsAdherence controls which components in the cluster adhere to the TLS security profile
configured on this APIServer resource.
Valid values are "LegacyExternalAPIServerComponentsOnly" and "StrictAllComponents".
When set to "LegacyExternalAPIServerComponentsOnly", only the externally exposed
API server components (kube-apiserver, openshift-apiserver, oauth-apiserver) honor the configured
TLS profile. Other components continue to use their individual TLS configurations.
When set to "StrictAllComponents", all components must honor the configured TLS profile.
This mode is recommended for security-conscious deployments and is required for
certain compliance frameworks.
Note: The Kubelet and IngressController components are excluded from tlsAdherence control
as they have their own dedicated TLS configuration mechanisms via KubeletConfig and
IngressController CRs respectively.
Components that encounter an unknown value for tlsAdherence should treat it as "StrictAllComponents"
and log a warning to ensure forward compatibility while defaulting to the more secure behavior.
This field is optional. When omitted, it is interpreted as "no opinion" and the cluster
defaults to LegacyExternalAPIServerComponentsOnly behavior. Future versions of OpenShift
may require explicitly setting this field to "StrictAllComponents" before upgrading.
Administrators are encouraged to migrate to "StrictAllComponents" proactively.
Once set, this field may be changed to a different value.
enum:
- LegacyExternalAPIServerComponentsOnly
- StrictAllComponents
type: string
tlsSecurityProfile:
description: |-
tlsSecurityProfile specifies settings for TLS connections for externally exposed servers.
Expand Down
1 change: 1 addition & 0 deletions config/v1/zz_generated.featuregated-crd-manifests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ apiservers.config.openshift.io:
FeatureGates:
- KMSEncryption
- KMSEncryptionProvider
- TLSAdherence
FilenameOperatorName: config-operator
FilenameOperatorOrdering: "01"
FilenameRunLevel: "0000_10"
Expand Down
Loading