Skip to content

Conversation

@richardsonnick
Copy link

@richardsonnick richardsonnick commented Jan 29, 2026

User description

Add TLSAdherence feature gate for cluster-wide TLS configuration

This PR introduces the TLSAdherence feature gate and adds the tlsAdherence field to the APIServer config resource (apiserver.config.openshift.io/v1).

Summary

The tlsAdherence field controls how strictly components in the cluster adhere to the TLS security profile configured on the APIServer resource.

Valid values:

  • Legacy (default): Backward-compatible behavior where components attempt to honor the configured TLS profile but may fall back to their individual defaults if conflicts arise. This mode is intended for clusters that need to maintain compatibility with existing configurations during migration.
  • Strict: Enforces strict adherence to the TLS configuration. All components must honor the configured profile. This mode is recommended for security-conscious deployments and is required for certain compliance frameworks.

Feature Gate Details

  • Feature Gate Name: TLSAdherence
  • Enabled in: DevPreviewNoUpgrade, TechPreviewNoUpgrade
  • Contact: @joelanford
  • Jira Component: kube-apiserver

Related

@openshift-ci-robot
Copy link

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 29, 2026

Hello @richardsonnick! Some important instructions when contributing to openshift/api:
API design plays an important part in the user experience of OpenShift and as such API PRs are subject to a high level of scrutiny to ensure they follow our best practices. If you haven't already done so, please review the OpenShift API Conventions and ensure that your proposed changes are compliant. Following these conventions will help expedite the api review process for your PR.

@coderabbitai
Copy link

coderabbitai bot commented Jan 29, 2026

📝 Walkthrough

Walkthrough

This pull request introduces a new TLSAdherence feature for APIServer configuration. A new TLSAdherencePolicy type is added with two enum values: LegacyExternalAPIServerComponentsOnly and StrictAllComponents. The corresponding TLSAdherence field is added to APIServerSpec with feature-gate support. A new feature gate FeatureGateTLSAdherence is registered, enabled in DevPreviewNoUpgrade and TechPreviewNoUpgrade modes. Multiple CRD manifests across different feature gate profiles are updated to include the tlsAdherence field and feature gate entries. API documentation and OpenAPI generation code are updated accordingly. Additionally, ManagedBootImagesCPMS feature gate configuration is updated.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title mentions 'TLS adherance feature gate' which is directly related to the main change introducing the TLSAdherence feature gate and tlsAdherence field to APIServer config.
Description check ✅ Passed The description clearly explains the TLSAdherence feature gate introduction, its purpose, valid values (Legacy and Strict), feature gate configuration, and related enhancement PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.5.0)

Error: build linters: unable to load custom analyzer "kubeapilinter": tools/_output/bin/kube-api-linter.so, plugin: not implemented
The command is terminated due to an error: build linters: unable to load custom analyzer "kubeapilinter": tools/_output/bin/kube-api-linter.so, plugin: not implemented


Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci openshift-ci bot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Jan 29, 2026
@qodo-code-review
Copy link

qodo-code-review bot commented Jan 29, 2026

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Defaulting not enforced: The new tlsAdherence field documents defaulting/unknown-value behavior (default Legacy,
unknown treated as Strict with warning) but this PR only adds API types/CRD enum and does
not show any code that enforces defaulting or handles unset/unknown values at runtime.

Referred Code
// tlsAdherence controls how strictly components in the cluster adhere to the TLS security profile
// configured on this APIServer resource.
//
// Valid values are "Legacy" and "Strict".
//
// When set to "Legacy" (the default), components attempt to honor the configured TLS profile
// but may fall back to their individual defaults if conflicts arise. This mode is intended for
// clusters that need to maintain compatibility with existing configurations during migration.
//
// When set to "Strict", all components must strictly honor the configured TLS profile.
// This mode is recommended for security-conscious deployments and is required for
// certain compliance frameworks.
//
// Components that encounter an unknown value for tlsAdherence should treat it as "Strict"
// and log a warning to ensure forward compatibility while defaulting to the more secure behavior.
//
// When omitted, the default value is "Legacy".
// +openshift:enable:FeatureGate=TLSAdherence
// +optional
TLSAdherence TLSAdherencePolicy `json:"tlsAdherence,omitempty"`

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Missing input constraints: The new curves field is introduced as a free-form string array without visible validation
constraints (e.g., allowed values/patterns), so it is unclear from this diff alone whether
invalid curve names are rejected or safely handled downstream.

Referred Code
// curves is used to specify the elliptic curves that are used during
// the TLS handshake.  Operators may remove entries their operands do
// not support.  For example, to use X25519 and P-256 (yaml):
//
//   curves:
//     - X25519
//     - P-256
Curves []string `json:"curves,omitempty"`
// minTLSVersion is used to specify the minimal version of the TLS protocol

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link

qodo-code-review bot commented Jan 29, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Use pointer for an optional field

*Change the TLSAdherence field to a pointer type (TLSAdherencePolicy) to
correctly handle its optional nature and resolve ambiguity between an omitted
value and an empty string.

config/v1/types_apiserver.go [81-84]

 // When omitted, the default value is "Legacy".
 // +openshift:enable:FeatureGate=TLSAdherence
 // +optional
-TLSAdherence TLSAdherencePolicy `json:"tlsAdherence,omitempty"`
+TLSAdherence *TLSAdherencePolicy `json:"tlsAdherence,omitempty"`
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a significant ambiguity in the API design where omitting the TLSAdherence field leads to conflicting documented behaviors, and proposes using a pointer type, which is the idiomatic Go solution to distinguish between an omitted and an empty value.

Medium
High-level
Unify API documentation source
Suggestion Impact:The commit addressed the documentation inconsistency, but not by adding the excluded-components note to the Go type. Instead, it removed that note from the generated CRD and updated both Go and CRD text (including renamed enum values) so the descriptions align.

code diff:

# File: config/v1/types_apiserver.go
@@ -65,20 +65,21 @@
 	// tlsAdherence controls how strictly components in the cluster adhere to the TLS security profile
 	// configured on this APIServer resource.
 	//
-	// Valid values are "Legacy" and "Strict".
-	//
-	// When set to "Legacy" (the default), components attempt to honor the configured TLS profile
-	// but may fall back to their individual defaults if conflicts arise. This mode is intended for
-	// clusters that need to maintain compatibility with existing configurations during migration.
-	//
-	// When set to "Strict", all components must strictly honor the configured TLS profile.
+	// Valid values are "LegacyExternalAPIServerComponentsOnly" and "StrictAllComponents".
+	//
+	// When set to "LegacyExternalAPIServerComponentsOnly" (the default), components attempt to honor
+	// the configured TLS profile but may fall back to their individual defaults if conflicts arise.
+	// This mode is intended for clusters that need to maintain compatibility with existing
+	// configurations during migration.
+	//
+	// When set to "StrictAllComponents", all components must strictly honor the configured TLS profile.
 	// This mode is recommended for security-conscious deployments and is required for
 	// certain compliance frameworks.
 	//
-	// Components that encounter an unknown value for tlsAdherence should treat it as "Strict"
+	// 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.
 	//
-	// When omitted, the default value is "Legacy".
+	// When omitted, the default value is "LegacyExternalAPIServerComponentsOnly".
 	// +openshift:enable:FeatureGate=TLSAdherence
 	// +optional
 	TLSAdherence TLSAdherencePolicy `json:"tlsAdherence,omitempty"`
@@ -258,20 +259,20 @@
 }
 
 // TLSAdherencePolicy defines how strictly components adhere to the TLS security profile.
-// +kubebuilder:validation:Enum=Legacy;Strict
+// +kubebuilder:validation:Enum=LegacyExternalAPIServerComponentsOnly;StrictAllComponents
 type TLSAdherencePolicy string
 
 const (
-	// TLSAdherenceLegacy provides backward-compatible behavior where components attempt to
-	// honor the configured TLS profile but may fall back to their individual defaults if
-	// conflicts arise. This mode is intended for clusters that need to maintain compatibility
-	// with existing configurations during migration.
-	TLSAdherenceLegacy TLSAdherencePolicy = "Legacy"
-
-	// TLSAdherenceStrict enforces strict adherence to the TLS configuration. All components
-	// must honor the configured profile. This mode is recommended for security-conscious
-	// deployments and is required for certain compliance frameworks.
-	TLSAdherenceStrict TLSAdherencePolicy = "Strict"
+	// TLSAdherenceLegacyExternalAPIServerComponentsOnly provides backward-compatible behavior
+	// where components attempt to honor the configured TLS profile but may fall back to their
+	// individual defaults if conflicts arise. This mode is intended for clusters that need to
+	// maintain compatibility with existing configurations during migration.
+	TLSAdherenceLegacyExternalAPIServerComponentsOnly TLSAdherencePolicy = "LegacyExternalAPIServerComponentsOnly"
+
+	// TLSAdherenceStrictAllComponents enforces strict adherence to the TLS configuration.
+	// All components must honor the configured profile. This mode is recommended for
+	// security-conscious deployments and is required for certain compliance frameworks.
+	TLSAdherenceStrictAllComponents TLSAdherencePolicy = "StrictAllComponents"
 )
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

# File: config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml
@@ -297,27 +297,24 @@
                   tlsAdherence controls how strictly components in the cluster adhere to the TLS security profile
                   configured on this APIServer resource.
 
-                  Valid values are "Legacy" and "Strict".
-
-                  When set to "Legacy" (the default), components attempt to honor the configured TLS profile
-                  but may fall back to their individual defaults if conflicts arise. This mode is intended for
-                  clusters that need to maintain compatibility with existing configurations during migration.
-
-                  When set to "Strict", all components must strictly honor the configured TLS profile.
+                  Valid values are "LegacyExternalAPIServerComponentsOnly" and "StrictAllComponents".
+
+                  When set to "LegacyExternalAPIServerComponentsOnly" (the default), components attempt to honor
+                  the configured TLS profile but may fall back to their individual defaults if conflicts arise.
+                  This mode is intended for clusters that need to maintain compatibility with existing
+                  configurations during migration.
+
+                  When set to "StrictAllComponents", all components must strictly honor the configured TLS profile.
                   This mode is recommended for security-conscious deployments and is required for
                   certain compliance frameworks.
 
-                  Components that encounter an unknown value for tlsAdherence should treat it as "Strict"
+                  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.
 
-                  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.
-
-                  When omitted, the default value is "Legacy".
+                  When omitted, the default value is "LegacyExternalAPIServerComponentsOnly".
                 enum:
-                - Legacy
-                - Strict
+                - LegacyExternalAPIServerComponentsOnly
+                - StrictAllComponents
                 type: string

The documentation for the tlsAdherence field is inconsistent across files. The
Go type definition is missing an important note about excluded components that
is present in the generated CRD, indicating a need to unify the documentation
source.

Examples:

config/v1/types_apiserver.go [65-84]
	// tlsAdherence controls how strictly components in the cluster adhere to the TLS security profile
	// configured on this APIServer resource.
	//
	// Valid values are "Legacy" and "Strict".
	//
	// When set to "Legacy" (the default), components attempt to honor the configured TLS profile
	// but may fall back to their individual defaults if conflicts arise. This mode is intended for
	// clusters that need to maintain compatibility with existing configurations during migration.
	//
	// When set to "Strict", all components must strictly honor the configured TLS profile.

 ... (clipped 10 lines)
config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml [296-317]
                description: |-
                  tlsAdherence controls how strictly components in the cluster adhere to the TLS security profile
                  configured on this APIServer resource.

                  Valid values are "Legacy" and "Strict".

                  When set to "Legacy" (the default), components attempt to honor the configured TLS profile
                  but may fall back to their individual defaults if conflicts arise. This mode is intended for
                  clusters that need to maintain compatibility with existing configurations during migration.


 ... (clipped 12 lines)

Solution Walkthrough:

Before:

// file: config/v1/types_apiserver.go

type APIServerSpec struct {
    // ... (documentation without the note)
    // When omitted, the default value is "Legacy".
    // +openshift:enable:FeatureGate=TLSAdherence
    // +optional
    TLSAdherence TLSAdherencePolicy `json:"tlsAdherence,omitempty"`
    // ...
}

After:

// file: config/v1/types_apiserver.go

type APIServerSpec struct {
    // ... (documentation with the note)
    // 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.
    //
    // When omitted, the default value is "Legacy".
    // +openshift:enable:FeatureGate=TLSAdherence
    // +optional
    TLSAdherence TLSAdherencePolicy `json:"tlsAdherence,omitempty"`
    // ...
}
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a significant documentation inconsistency, where crucial information in the CRD is missing from the source Go type, indicating a flawed generation process.

Medium
General
Mark curves as optional atomic list

Add +listType=atomic and +optional markers to the Curves field in TLSProfileSpec
for consistency and correct CRD generation.

config/v1/types_tlssecurityprofile.go [171-178]

+// +listType=atomic
+// +optional
 // curves is used to specify the elliptic curves that are used during
 // the TLS handshake.  Operators may remove entries their operands do
 // not support.  For example, to use X25519 and P-256 (yaml):
 //
 //   curves:
 //     - X25519
 //     - P-256
 Curves []string `json:"curves,omitempty"`
  • Apply / Chat
Suggestion importance[1-10]: 5

__

Why: The suggestion correctly points out that the new Curves field should have +listType=atomic and +optional markers for consistency with the existing Ciphers field and to ensure correct CRD generation, improving API consistency.

Low
  • Update

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 29, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign everettraven for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@config/v1/types_apiserver.go`:
- Around line 65-84: Update the TLSAdherence field documentation to include the
exclusion note from the CRD manifests: explicitly state that Kubelet and
IngressController are excluded from tlsAdherence control and instead use their
own TLS config (KubeletConfig and IngressController CRs). Edit the comment above
the TLSAdherence TLSAdherencePolicy field (the docblock that documents
TLSAdherence) to append a short sentence noting this exclusion so generated API
docs reflect the same caveat as the CRD manifests.

In `@features.md`:
- Line 78: The table row containing the "TLSAdherence" feature is missing a
space before the first pipe after the feature name, violating markdownlint table
spacing; edit the row that starts with "TLSAdherence" and insert a single space
before the following "|" so it reads "TLSAdherence |" (preserving the rest of
the cells exactly) to conform to the configured table style.

In `@openapi/generated_openapi/zz_generated.openapi.go`:
- Around line 12447-12461: Add a kubebuilder enum validation for the Curves
field so only supported TLS curve identifiers are accepted: add a comment marker
like +kubebuilder:validation:Enum=X25519;P-256;P-384;P-521 immediately above the
Curves []string field in the struct in config/v1/types_tlssecurityprofile.go
(mirror the pattern used for TLSProtocolVersion), then re-run
controller-gen/openapi generation to update
openapi/generated_openapi/zz_generated.openapi.go so the "curves" schema
includes the enum restriction.
🧹 Nitpick comments (5)
config/v1/types_tlssecurityprofile.go (1)

169-178: Consider adding listType=atomic for Curves for SSA consistency.
This mirrors the Ciphers list semantics and avoids any unexpected merge behavior.

🔧 Proposed tweak
 	//   curves:
 	//     - X25519
 	//     - P-256
 	//
+	// +listType=atomic
 	Curves []string `json:"curves,omitempty"`
openapi/generated_openapi/zz_generated.openapi.go (1)

9102-9108: Add enum validation for tlsAdherence to match the documented valid values.

The schema only declares a free-form string even though the description defines just "Legacy" and "Strict". That means invalid values will pass admission and only be handled at runtime. Consider adding kubebuilder enum (and, if desired, a default) on the source type so the generated OpenAPI enforces the allowed values.

[Suggested fix (apply in config/v1/types_apiserver.go, not this generated file):]

🔧 Example annotation update
 // +optional
+// +kubebuilder:validation:Enum=Legacy;Strict
+// +kubebuilder:default=Legacy
 TLSAdherence TLSAdherencePolicy `json:"tlsAdherence,omitempty"`
payload-manifests/crds/0000_10_config-operator_01_apiservers-Default.crd.yaml (1)

259-270: Consider adding x-kubernetes-list-type annotation for consistency.

The curves field is missing the x-kubernetes-list-type annotation that the ciphers field has (line 258 shows x-kubernetes-list-type: atomic for ciphers). For consistency and to ensure proper list merge behavior, consider adding the same annotation.

📝 Suggested fix
                       curves:
                         description: |-
                           curves is used to specify the elliptic curves that are used during
                           the TLS handshake.  Operators may remove entries their operands do
                           not support.  For example, to use X25519 and P-256 (yaml):

                             curves:
                               - X25519
                               - P-256
                         items:
                           type: string
                         type: array
+                        x-kubernetes-list-type: atomic
payload-manifests/crds/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml (1)

287-298: Same annotation consistency issue as Default CRD.

The curves field here also lacks the x-kubernetes-list-type: atomic annotation that ciphers has. See the comment on the Default CRD for the suggested fix.

payload-manifests/crds/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml (1)

355-366: Same annotation consistency issue.

The curves field here also lacks x-kubernetes-list-type: atomic. This is consistent across all the CRD files in this PR but differs from the ciphers field pattern.

Comment on lines 12447 to 12461
"curves": {
SchemaProps: spec.SchemaProps{
Description: "curves is used to specify the elliptic curves that are used during the TLS handshake. Operators may remove entries their operands do not support. For example, to use X25519 and P-256 (yaml):\n\n curves:\n - X25519\n - P-256",
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Default: "",
Type: []string{"string"},
Format: "",
},
},
},
},
},
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Go 1.21 1.22 crypto/tls supported curve names CurveID identifiers

💡 Result:

In Go 1.21 and Go 1.22, crypto/tls exposes these supported (named group) CurveID constants:

TLS group / curve name Go constant CurveID (uint16)
NIST P-256 (secp256r1) tls.CurveP256 23
NIST P-384 (secp384r1) tls.CurveP384 24
NIST P-521 (secp521r1) tls.CurveP521 25
X25519 tls.X25519 29

These are the CurveID identifiers defined by crypto/tls for those versions. [1]

Sources:
[1] https://go.googlesource.com/go/+/go1.14.8/src/crypto/tls/common.go


🏁 Script executed:

# First, find the source code that generates this OpenAPI schema
# The file is auto-generated, so we need to find what generates it
fd -t f "*.go" | head -20 | xargs grep -l "curves is used to specify" 2>/dev/null | head -5

Repository: openshift/api

Length of output: 340


🏁 Script executed:

# Search for the source field definition
rg -A 5 -B 5 "curves.*TLS.*handshake" --type go

Repository: openshift/api

Length of output: 3653


🏁 Script executed:

# Check for OpenAPI generation tooling and look for the source type
find . -name "*openapi*" -o -name "*swagger*" | grep -v generated | head -10

Repository: openshift/api

Length of output: 427


🏁 Script executed:

# Look for struct definitions with a "curves" field that might be the source
rg "Curves\s*\[\]" --type go | head -20

Repository: openshift/api

Length of output: 359


🏁 Script executed:

# Read the source file that defines the Curves field
cat -n config/v1/types_tlssecurityprofile.go

Repository: openshift/api

Length of output: 11992


🏁 Script executed:

# Look for validation rules or constants in the codebase
rg "enum.*curve|Curve.*enum|CurveID|X25519|P-256|P-384|P-521" --type go config/v1/ | head -30

Repository: openshift/api

Length of output: 568


🏁 Script executed:

# Search for validation struct tags or validation rules in similar fields
rg "json:.*omitempty.*validation|kubebuilder:validation" --type go config/v1/types_tlssecurityprofile.go -A 3 -B 3

Repository: openshift/api

Length of output: 490


🏁 Script executed:

# Check how other string arrays are validated in the codebase
rg '\[\]string.*json' --type go config/v1/ -A 2 | grep -A 2 "kubebuilder" | head -40

Repository: openshift/api

Length of output: 39


Add validation for curves field to restrict entries to supported TLS curve identifiers.

The Curves field in config/v1/types_tlssecurityprofile.go (line 178) accepts any string with no validation, allowing invalid curve names to be accepted during config validation but fail later at TLS handshake time. Add a +kubebuilder:validation:Enum marker similar to the pattern used for TLSProtocolVersion to enforce only supported curves: X25519, P-256, P-384, P-521 (as supported by Go 1.21+ crypto/tls).

🤖 Prompt for AI Agents
In `@openapi/generated_openapi/zz_generated.openapi.go` around lines 12447 -
12461, Add a kubebuilder enum validation for the Curves field so only supported
TLS curve identifiers are accepted: add a comment marker like
+kubebuilder:validation:Enum=X25519;P-256;P-384;P-521 immediately above the
Curves []string field in the struct in config/v1/types_tlssecurityprofile.go
(mirror the pattern used for TLSProtocolVersion), then re-run
controller-gen/openapi generation to update
openapi/generated_openapi/zz_generated.openapi.go so the "curves" schema
includes the enum restriction.

Comment on lines 70 to 72
// When set to "Legacy" (the default), components attempt to honor the configured TLS profile
// but may fall back to their individual defaults if conflicts arise. This mode is intended for
// clusters that need to maintain compatibility with existing configurations during migration.
Copy link
Member

@joelanford joelanford Jan 29, 2026

Choose a reason for hiding this comment

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

I thought Legacy was going to essentially mean "only the externally exposed API server components", and Strict will mean "ALL cluster components with the exception of Kubelet-related and Ingress-related servers"?

I also think we should update GoDoc for the TLSSecurityProfile field, which currently says "for externally exposed servers". With TLSAdherence in the mix, what the profile is for depends on the TLSAdherence value.

But that should doc change should also only apply when the feature gate is enabled. I think @JoelSpeed said there's a way to do that?

Copy link
Member

Choose a reason for hiding this comment

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

I also wonder if we should improve the naming of the enums to more accurately describe what they do? For example:

  • LegacyExternalAPIServerComponentsOnly
  • StrictAllComponents

Or something along those lines?

Copy link
Author

Choose a reason for hiding this comment

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

I think these names are far better. Going with LegacyExternalAPIServerComponentsOnly and StrictAllComponents

Comment on lines 171 to 178
// curves is used to specify the elliptic curves that are used during
// the TLS handshake. Operators may remove entries their operands do
// not support. For example, to use X25519 and P-256 (yaml):
//
// curves:
// - X25519
// - P-256
Curves []string `json:"curves,omitempty"`
Copy link
Member

@joelanford joelanford Jan 29, 2026

Choose a reason for hiding this comment

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

Based on my read of openshift/enhancements#1894, it seems like very few components currently handle TLS curve configuration.

And I don't think we will be able to promote this full set of API changes unless components handle all of MinTLSVersion, CipherSuites, and Curves.

I am worried that the upstream's lack of curves support might take some time and would therefore block the rest of the feature around honoring the min TLS and cipher suites configuration.

Should we remove Curves from this PR or configure it to be present with a separate feature gate?

Copy link
Author

Choose a reason for hiding this comment

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

Yeah that should not be here. It has since been removed. This PR applies solely to the adherence fate.

//
// curves:
// - X25519
// - P-256
Copy link
Member

Choose a reason for hiding this comment

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

If/when we do add Curves field, it needs to be introduced behind a feature gate.

Copy link
Member

@joelanford joelanford left a comment

Choose a reason for hiding this comment

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

Curves should be removed or included behind a feature gate. My understanding is that we can't add a field to the Default CRD without first going through TechPreviewNoUpgrade.

@everettraven
Copy link
Contributor

Adding to @joelanford 's comment - I'd prefer we keep the curves field entirely separate here to keep this well scoped. IIRC there is already a PR that is looking to add the curves field.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml`:
- Around line 295-318: The CRD docs claim tlsAdherence defaults to
"LegacyExternalAPIServerComponentsOnly" but the schema lacks a default; add the
kubebuilder default tag to the APIServer Go field (the tlsAdherence field on the
APIServer type) as +kubebuilder:default=LegacyExternalAPIServerComponentsOnly so
the generated CRD includes the default, and run codegen to update the YAML; also
ensure operators consuming the APIServer resource handle omitted/empty
tlsAdherence by treating it as Legacy until the default is live. Additionally,
add x-kubernetes-list-type: atomic to the curves list (to match ciphers) in the
generated CRD so both lists have consistent list-type semantics.
🧹 Nitpick comments (1)
payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml (1)

352-364: Consider marking curves as an atomic list for consistency with ciphers.

ciphers is explicitly atomic; curves would benefit from the same list-type to avoid merge ambiguity in SSA. Prefer adding +listType=atomic on the Go field and regenerating manifests.

♻️ Suggested manifest shape
       curves:
         description: |-
           curves is used to specify the elliptic curves that are used during
           the TLS handshake.  Operators may remove entries their operands do
           not support.  For example, to use X25519 and P-256 (yaml):

             curves:
               - X25519
               - P-256
         items:
           type: string
         type: array
+        x-kubernetes-list-type: atomic

//
// When omitted, the default value is "LegacyExternalAPIServerComponentsOnly".
// +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.

Comment on lines +275 to +277
// 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.
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?

Copy link
Member

Choose a reason for hiding this comment

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

How did these changes get here? Maybe need to rebase and push?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Review effort 3/5 size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants