Skip to content

Conversation

@sanchezl
Copy link
Contributor

  • Add PKI API to config.openshift.io/v1alpha1
  • make update

@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

@coderabbitai
Copy link

coderabbitai bot commented Jan 12, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


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

@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jan 12, 2026
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 12, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 12, 2026

Hello @sanchezl! 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.

@openshift-ci openshift-ci bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Jan 12, 2026
@sanchezl
Copy link
Contributor Author

/test required

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 12, 2026

@sanchezl: The specified target(s) for /test were not found.
The following commands are available to trigger required jobs:

/test build
/test e2e-aws-ovn
/test e2e-aws-ovn-hypershift
/test e2e-aws-ovn-hypershift-conformance
/test e2e-aws-ovn-techpreview
/test e2e-aws-serial-1of2
/test e2e-aws-serial-2of2
/test e2e-aws-serial-techpreview-1of2
/test e2e-aws-serial-techpreview-2of2
/test e2e-azure
/test e2e-gcp
/test e2e-upgrade
/test e2e-upgrade-out-of-change
/test images
/test integration
/test lint
/test minor-e2e-upgrade-minor
/test minor-images
/test okd-scos-images
/test unit
/test verify
/test verify-client-go
/test verify-crd-schema
/test verify-crdify
/test verify-deps
/test verify-feature-promotion

The following commands are available to trigger optional jobs:

/test okd-scos-e2e-aws-ovn

Use /test all to run the following jobs that were automatically triggered:

pull-ci-openshift-api-master-build
pull-ci-openshift-api-master-images
pull-ci-openshift-api-master-integration
pull-ci-openshift-api-master-lint
pull-ci-openshift-api-master-minor-images
pull-ci-openshift-api-master-okd-scos-images
pull-ci-openshift-api-master-unit
pull-ci-openshift-api-master-verify
pull-ci-openshift-api-master-verify-client-go
pull-ci-openshift-api-master-verify-crd-schema
pull-ci-openshift-api-master-verify-crdify
pull-ci-openshift-api-master-verify-deps
pull-ci-openshift-api-master-verify-feature-promotion
Details

In response to this:

/test required

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 12, 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 joelspeed 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

@sanchezl
Copy link
Contributor Author

/test unit
/test verify
/test verify-client-go
/test verify-crd-schema
/test verify-crdify
/test verify-deps
/test verify-feature-promotion

@sanchezl sanchezl changed the title pki config CNTRLPLANE-1752: Add PKI API to config.openshift.io/v1alpha1 Jan 13, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jan 13, 2026
@openshift-ci-robot
Copy link

openshift-ci-robot commented Jan 13, 2026

@sanchezl: This pull request references CNTRLPLANE-1752 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the sub-task to target the "4.22.0" version, but no target version was set.

Details

In response to this:

  • Add PKI API to config.openshift.io/v1alpha1
  • make update

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@sanchezl
Copy link
Contributor Author

/retest-required

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 13, 2026

@sanchezl: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/verify d09d621 link true /test verify

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

// +kubebuilder:validation:XValidation:rule="self.type == 'Unmanaged' ? (!has(self.defaults) && !has(self.categories) && !has(self.overrides)) : true",message="defaults, categories, and overrides must not be set when type is Unmanaged"
// +kubebuilder:validation:XValidation:rule="self.type == 'Default' ? (!has(self.defaults) && !has(self.categories) && !has(self.overrides)) : true",message="defaults, categories, and overrides must not be set when type is Default"
// +union
type PKIManagementPolicy struct {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I want to note that I am not using a discriminated union pattern here, instead it is more of a "parameterized" union pattern (at at least a kind of parameterized union where its all fields or none).

This configuration models a "predefined behavior vs. customization" choice pattern, rather than mutually exclusive options with different configuration requirements (like platform-specific settings).

If we add more predefined behaviors (e.g., type: FIPS, type: CNSACompliant), they would be additional enum values with no configuration fields. They represent different default behaviors, not different configuration structures.

If we need to extend what's configurable (e.g., adding certificate lifetime configuration), we'd add fields to PKIProfile and/or CertificateConfig. These fields would apply regardless of which predefined behavior or custom configuration is in use.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure I'm following why this is a better approach than a discriminated union pattern.

Discriminated unions are a common pattern in OpenShift APIs (so our users will be used to them) and they allow for discriminators with no associated configuration fields.

If we add more predefined behaviors (e.g., type: FIPS, type: CNSACompliant), they would be additional enum values with no configuration fields. They represent different default behaviors, not different configuration structures.

If we need to extend what's configurable (e.g., adding certificate lifetime configuration), we'd add fields to PKIProfile and/or CertificateConfig. These fields would apply regardless of which predefined behavior or custom configuration is in use.

It sounds like if we added any additional pre-defined behaviors any new configuration options we add would be not configurable by end-users with these pre-defined behaviors.

To me, this reads that the only time we anticipate ever being able to configure something is when type is set to Custom - in which case an end-user must supply some kind of configuration.

Is this accurate?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right. This is a pick a predefined policy, or supply your own. There would be no such thing as a pre-defined policy with options. I think this is distinct from "there are different kinds of policies with different kinds of fields".

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is distinct from "there are different kinds of policies with different kinds of fields".

Is it though? I read this as there being different kinds of policies with different kinds of fields, just that most of the policies have no fields.

IMO, something like:

type: Custom
custom:
  defaults: ...
  categories: ...
  overrides: ...

is more intuitive that the fields are only applicable when the type is custom than something like:

type: Custom
defaults: ...
categories: ...
overrides: ...

I think becomes even more true when we've used this discriminated union approach for quite some time for OpenShift APIs and is one that users are going to be familiar with.

We try to aim for consistency, where possible, in how we structure our APIs to keep the experience consistent and familiar for our users - I'm not sold on breaking that consistency here yet.

Copy link
Contributor

Choose a reason for hiding this comment

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

The currently proposed approach also lends itself to an ever growing list of CEL validations to maintain instead of having one to prevent setting custom values when the type field is not Custom.

Comment on lines +34 to +39
// certificateManagement specifies how PKI configuration is managed for internally-generated certificates.
// This controls the certificate generation approach for all OpenShift components that create
// certificates internally, including certificate authorities, serving certificates, and client certificates.
//
// +required
CertificateManagement PKICertificateManagement `json:"certificateManagement,omitzero"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we envision this API being expanded to do more than certificate management in the future?

Comment on lines +53 to +68
// - Unmanaged: Components use their existing hardcoded certificate generation behavior, exactly as if this feature did not exist.
// Each component generates certificates using whatever parameters it was using before this feature.
// While most components use RSA 2048, some may use different parameters.
// Use of this mode might prevent upgrading to the next major OpenShift release.
// + Default when upgrading from a version without this feature to ensure zero behavior change.
//
// - Default: Use OpenShift-recommended best practices for certificate generation.
// The specific parameters may evolve across OpenShift releases to adopt improved cryptographic standards.
// In the initial release, this matches Unmanaged behavior for each component.
// In future releases, this may adopt ECDSA or larger RSA keys based on industry best practices.
// Recommended for most customers who want to benefit from security improvements automatically.
// + Default when installing a fresh cluster.
//
// - Custom: Administrator explicitly configures cryptographic parameters.
// Use the custom field to specify certificate generation parameters.
// + Recommended for customers with specific compliance requirements or organizational PKI policies.
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of using the list notation, we generally try to use formats like:

// When set to Unmanaged, ....
//
// When set to Default, ...
//
// When set to Custom, ...

This helps us to avoid any weirdness in formatting of the generated documentation when using list notations.

Comment on lines +53 to +57
// - Unmanaged: Components use their existing hardcoded certificate generation behavior, exactly as if this feature did not exist.
// Each component generates certificates using whatever parameters it was using before this feature.
// While most components use RSA 2048, some may use different parameters.
// Use of this mode might prevent upgrading to the next major OpenShift release.
// + Default when upgrading from a version without this feature to ensure zero behavior change.
Copy link
Contributor

Choose a reason for hiding this comment

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

Reading the description of Unmanaged I'm wondering if Unmanaged is the right terminology here.

I'm struggling a bit with naming suggestions, but something along the lines of ComponentDefaults seems more appropriate here since this is targeted at a mode where individual components of the platform are using their own defaults.

What do you think?

Comment on lines +59 to +64
// - Default: Use OpenShift-recommended best practices for certificate generation.
// The specific parameters may evolve across OpenShift releases to adopt improved cryptographic standards.
// In the initial release, this matches Unmanaged behavior for each component.
// In future releases, this may adopt ECDSA or larger RSA keys based on industry best practices.
// Recommended for most customers who want to benefit from security improvements automatically.
// + Default when installing a fresh cluster.
Copy link
Contributor

Choose a reason for hiding this comment

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

Following the same logic of there being a couple layers of "default" behavior, maybe naming this something like PlatformDefault makes more sense as applying the default broadly across all components in the "platform"?

Comment on lines +70 to +75
// + When upgrading from a version without this feature:
// + - The PKI resource is created with mode: Unmanaged to ensure zero behavior change.
//
// + When installing a fresh cluster:
// + - If no PKI configuration is provided in install-config.yaml, mode: Default is used.
// + - If PKI configuration is provided in install-config.yaml, mode: Custom is used with the specified configuration.
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need to include semantics about upgrading vs installing from a fresh cluster as part of the API documentation.

It reads to me as more suited towards developer documentation as opposed to end-user documentation. The GoDoc is used as our user-facing documentation for APIs.

// + - If PKI configuration is provided in install-config.yaml, mode: Custom is used with the specified configuration.
//
// +required
// +kubebuilder:validation:Enum=Unmanaged;Default;Custom
Copy link
Contributor

Choose a reason for hiding this comment

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

We generally recommend putting the enum marker on the type alias. It is effectively the same, but if the type alias is ever used in another API somewhere it will not automatically add the enum constraint unless the marker is on the type alias.

Copy link
Contributor

Choose a reason for hiding this comment

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

This comment applies to all enum constraint markers in this PR.

// defaults specifies the default certificate configuration
// for all certificates unless overridden by category or specific
// certificate configuration.
// If not specified, uses platform defaults (typically RSA 2048).
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this the actual platform defaults that may be subject to change over time, or are these the component-specific defaults?

I know they are currently one and the same, but IIUC they may not be in the future.


type CategoryCertificateConfig struct {
// category identifies the certificate category.
// Valid values are "SignerCertificate", "ServingCertificate", and "ClientCertificate".
Copy link
Contributor

Choose a reason for hiding this comment

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

What does each of these values mean when set?


// CertificateOverride allows configuration of certificate parameters for specific named certificates.
//
// +kubebuilder:validation:XValidation:rule=`self.certificateName in ['admin-kubeconfig-signer','kubelet-bootstrap-kubeconfig-signer','kube-apiserver-localhost-signer','kube-apiserver-service-network-signer','kube-apiserver-lb-signer','root-ca','kube-apiserver-to-kubelet-signer','kube-control-plane-signer','aggregator-signer','kubelet-signer','aggregator-ca','etcd-signer','etcd-metrics-signer','service-ca','csr-signer-ca','kube-apiserver-localhost-server','kube-apiserver-service-network-server','kube-apiserver-lb-server','kube-apiserver-internal-lb-server','machine-config-server','ironic-server','etcd-peer-server','etcd-server','etcd-metrics-server','admin-kubeconfig-client','kubelet-client','kube-apiserver-to-kubelet-client','kube-control-plane-kube-controller-manager-client','kube-control-plane-kube-scheduler-client','aggregator-client','apiserver-proxy-client','journal-gatewayd-client']`,message="certificateName must be a well-known certificate name"
Copy link
Contributor

Choose a reason for hiding this comment

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

If we have a known list of values that we want to enforce, we should use an enum instead of a CEL expression. CEL expressions should only be used when necessary, and the OpenAPI schema used for CRDs already has a way to enforce enum constraints.

// Valid values are 2048, 3072, and 4096.
// +required
// +kubebuilder:validation:Enum=2048;3072;4096
// +kubebuilder:validation:Minimum=2048
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think the minimum marker is required here when setting the enum constraint. I don't recall whether or not the linter picks this up for integer types though 🤔

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

Labels

do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants