OCPBUGS-105321: pki: switch to ECDSA defaults and thread PKI profile to leaf certs - #10743
OCPBUGS-105321: pki: switch to ECDSA defaults and thread PKI profile to leaf certs#10743sanchezl wants to merge 7 commits into
Conversation
|
Pipeline controller notification For optional jobs, comment This repository is configured in: LGTM mode |
📝 WalkthroughWalkthroughConfigurable PKI now flows from effective profiles through ChangesConfigurable PKI integration
Estimated code review effort: 4 (Complex) | ~60 minutes 🚥 Pre-merge checks | ✅ 14 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (14 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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.12.2)Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions Comment |
|
Skipping CI for Draft Pull Request. |
|
/test all |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
06ad91c to
9f4aa80
Compare
|
/test all |
|
/pipeline required |
|
Scheduling required tests: Scheduling tests matching the |
9f4aa80 to
65df21c
Compare
|
/test all |
|
/pipeline required |
|
Scheduling required tests: Scheduling tests matching the |
|
/payload-job periodic-ci-openshift-release-main-nightly-5.0-e2e-aws-ovn-upgrade-fips-rhcos9-techpreview |
|
/payload-job periodic-ci-openshift-release-main-nightly-5.0-e2e-aws-ovn-upgrade-fips-rhcos9-10-techpreview |
|
/payload-job e2e-metal-ipi-ovn-upgrade-rhcos9-techpreview |
|
@sanchezl: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/f047f400-914e-11f1-8e35-4bb42ad1a5c4-0 |
|
@sanchezl: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/f1dfab00-914e-11f1-83c2-8d141c46cd05-0 |
|
/payload-job e2e-metal-ipi-ovn-upgrade-rhcos9-10-techpreview |
|
@sanchezl: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/f3b02540-914e-11f1-86a2-b0b4d2ce1f86-0 |
|
/payload-job periodic-ci-openshift-release-main-nightly-5.0-e2e-aws-ovn-fips |
|
@sanchezl: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/f554fba0-914e-11f1-82cf-c1f8829a801b-0 |
|
/payload-job periodic-ci-openshift-release-main-ci-5.0-e2e-aws-ovn-techpreview |
|
@sanchezl: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/f745a810-914e-11f1-9a6b-7a95cb0904d2-0 |
|
/payload-job periodic-ci-openshift-release-main-nightly-5.0-e2e-aws-ovn-single-node-techpreview |
|
@sanchezl: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/f8b11ef0-914e-11f1-90de-25ab253cf8e2-0 |
|
/payload-job periodic-ci-openshift-openshift-tests-private-release-5.0-amd64-nightly-aws-usgov-ipi-custom-dns-mini-perm-tp-f7 |
|
/payload-job periodic-ci-openshift-openshift-tests-private-release-5.0-amd64-nightly-aws-c2s-ipi-disc-priv-fips-f28-tp-longduration-cloud |
|
/payload-job periodic-ci-openshift-openshift-tests-private-release-5.0-amd64-nightly-vsphere-short-cert-rotation-f7 |
|
@sanchezl: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/c8ef7c00-9290-11f1-94d0-692d5cbb577d-0 |
|
@sanchezl: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/ce51a880-9290-11f1-8534-9d3be7d1c4e2-0 |
|
@sanchezl: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/c1165c10-9290-11f1-925b-81da9ff1cfcf-0 |
|
@sanchezl: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/c365ca50-9290-11f1-9b7e-dc981939baf2-0 |
|
@sanchezl: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/bd6b7c80-9290-11f1-8dd1-93b85b95cdd7-0 |
|
@sanchezl: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/d09f4200-9290-11f1-9196-c620fcae606f-0 |
|
@sanchezl: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/c4dc16a0-9290-11f1-8f47-a0fd447535ac-0 |
New imports from the existing library-go module needed for the PKI profile resolution code path.
…eProfile Replace the local DefaultPKIProfile() with library-go's version (ECDSA P-256 defaults, ECDSA P-384 signers). Add EffectiveProfile() which returns a never-nil PKIProfile and a bool indicating whether ConfigurablePKI is enabled. Keep EffectiveSignerPKIConfig() as a deprecated shim, updated to return ECDSA P-384 when the feature gate is on.
…abled Replace the PKIConfig field with a full configv1alpha1.PKIProfile and a ConfigurablePKIEnabled bool. Load() now calls EffectiveProfile(). Generate() remains a no-op for the agent flow (no install-config on disk). All signer assets switch to the new fields. The PKI manifest asset now depends on SignerKeyParams instead of InstallConfig directly.
SelfSignedCertKey.Generate() and SignedCertKey.Generate() now accept a KeyPairGenerator parameter. When nil, the existing legacy path runs unchanged. When non-nil, cert generation delegates to library-go: NewSigningCertificate for CAs, and NewServerCertificate / NewClientCertificate / NewPeerCertificate for leaf certs based on a new CertType field on CertCfg.
Add a ConfigurablePKIEnabled guard to every signer and leaf cert asset. When the feature gate is off, the legacy code path runs unchanged (explicit KeyUsages, RSA-2048 leaves). When on, each asset resolves a KeyPairGenerator from the PKI profile and delegates to library-go.
JournalCertKey needs both ServerAuth and ClientAuth — use CertificateTypePeer in the library-go path. AdminKubeConfigClientCertKey: drop the legacy ServerAuth ExtKeyUsage in the library-go path — it's a pure client cert (verified working on a live TechPreview cluster with ClientAuth only). Remove the unused LegacyPKIConfig() method from SignerKeyParams. Unskip TestSelfSignedCertKeyGenerateWithKeyGen with real test cases.
b7623bc to
132e614
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
|
/retest |
|
/pipeline required |
|
Scheduling tests matching the |
There was a problem hiding this comment.
♻️ Duplicate comments (2)
pkg/asset/tls/certkey.go (2)
214-222: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winGuard
tlsCfg.Certsbefore indexing.Line 218 still indexes
tlsCfg.Certs[0]without a length check. An emptyCertsslice panics the installer instead of returning an error.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/asset/tls/certkey.go` around lines 214 - 222, Guard tlsCfg.Certs before the tlsCfg.Certs[0] access in the certificate encoding flow, returning an appropriate error when the slice is empty instead of allowing a panic. Preserve the appendParent branch and existing EncodeCertificates error handling for valid certificate inputs.
377-403: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winBounds-check
kg.Bits, and verify the generator types are value types.Two points:
- Line 382 narrows
kg.Bits(anint) toint32. A value abovemath.MaxInt32wraps and can yield a negativeRSAKeySizethat flows into key generation. Reject out-of-range values.- The type switch matches
libcrypto.RSAKeyPairGeneratorandlibcrypto.ECDSAKeyPairGeneratoras value types. If the resolver returns pointers, both cases miss and every non-CA self-signed certificate fails with "unsupported KeyPairGenerator type".🛡️ Proposed bounds check
case libcrypto.RSAKeyPairGenerator: + if kg.Bits <= 0 || kg.Bits > math.MaxInt32 { + return PrivateKeyParams{}, fmt.Errorf("invalid RSA key size: %d", kg.Bits) + } return PrivateKeyParams{ Algorithm: types.KeyAlgorithmRSA, RSAKeySize: int32(kg.Bits), }, nilAdd
mathto the standard library import group.🔎 Verification script for generator types
#!/bin/bash # Confirm whether library-go generators are value or pointer types, and how callers construct them. fd -t f -e go . vendor/github.com/openshift/library-go/pkg/crypto --exec rg -n -B 2 -A 12 'RSAKeyPairGenerator|ECDSAKeyPairGenerator' rg -n --type=go -C 3 'RSAKeyPairGenerator\{|ECDSAKeyPairGenerator\{' pkg🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/asset/tls/certkey.go` around lines 377 - 403, Update keyGenToParams to reject RSA generators whose Bits value is outside the int32 range before converting it to RSAKeySize, using the math bounds as needed. Verify how callers construct the generators, then support the pointer forms of RSAKeyPairGenerator and ECDSAKeyPairGenerator in the type switch if the resolver returns pointers, while preserving existing value-type handling and unsupported-type errors.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@pkg/asset/tls/certkey.go`:
- Around line 214-222: Guard tlsCfg.Certs before the tlsCfg.Certs[0] access in
the certificate encoding flow, returning an appropriate error when the slice is
empty instead of allowing a panic. Preserve the appendParent branch and existing
EncodeCertificates error handling for valid certificate inputs.
- Around line 377-403: Update keyGenToParams to reject RSA generators whose Bits
value is outside the int32 range before converting it to RSAKeySize, using the
math bounds as needed. Verify how callers construct the generators, then support
the pointer forms of RSAKeyPairGenerator and ECDSAKeyPairGenerator in the type
switch if the resolver returns pointers, while preserving existing value-type
handling and unsupported-type errors.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Central YAML (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: 55788cae-309e-4271-bb94-1d3c1e51f030
⛔ Files ignored due to path filters (5)
vendor/github.com/openshift/library-go/pkg/pki/profile.gois excluded by!vendor/**,!**/vendor/**vendor/github.com/openshift/library-go/pkg/pki/provider.gois excluded by!vendor/**,!**/vendor/**vendor/github.com/openshift/library-go/pkg/pki/resolve.gois excluded by!vendor/**,!**/vendor/**vendor/github.com/openshift/library-go/pkg/pki/types.gois excluded by!vendor/**,!**/vendor/**vendor/modules.txtis excluded by!vendor/**,!**/vendor/**
📒 Files selected for processing (20)
go.modpkg/asset/imagebased/configimage/ingressoperatorsigner.gopkg/asset/manifests/pki.gopkg/asset/manifests/pki_test.gopkg/asset/tls/adminkubeconfig.gopkg/asset/tls/aggregator.gopkg/asset/tls/apiserver.gopkg/asset/tls/certkey.gopkg/asset/tls/certkey_test.gopkg/asset/tls/certnames.gopkg/asset/tls/iricertkey.gopkg/asset/tls/journalcertkey.gopkg/asset/tls/kubecontrolplane.gopkg/asset/tls/kubelet.gopkg/asset/tls/mcscertkey.gopkg/asset/tls/root.gopkg/asset/tls/signerkey_params.gopkg/asset/tls/tls.gopkg/types/pki/defaults.gopkg/types/pki/defaults_test.go
🚧 Files skipped from review as they are similar to previous changes (18)
- pkg/asset/tls/tls.go
- pkg/asset/tls/certnames.go
- pkg/asset/tls/signerkey_params.go
- pkg/asset/tls/journalcertkey.go
- pkg/asset/tls/iricertkey.go
- pkg/asset/manifests/pki_test.go
- pkg/asset/tls/aggregator.go
- pkg/types/pki/defaults_test.go
- pkg/asset/tls/root.go
- pkg/asset/tls/kubelet.go
- pkg/asset/manifests/pki.go
- pkg/asset/tls/apiserver.go
- pkg/asset/tls/certkey_test.go
- pkg/asset/tls/mcscertkey.go
- pkg/asset/tls/kubecontrolplane.go
- pkg/asset/imagebased/configimage/ingressoperatorsigner.go
- pkg/types/pki/defaults.go
- pkg/asset/tls/adminkubeconfig.go
|
/pipeline required |
|
Scheduling tests matching the |
|
/test e2e-aws-ovn-pki-default-techpreview |
|
/payoad-job periodic-ci-openshift-openshift-tests-private-release-5.0-multi-nightly-aws-eusc-ipi-fips-tp-arm-f7 |
|
/retest required |
|
/retest-required |
|
/test e2e-aws-ovn |
|
@sanchezl: The following tests failed, say
Full PR test history. Your PR dashboard. DetailsInstructions 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. |
Why
When ConfigurablePKI is enabled, the installer's
DefaultPKIProfile()returns a hardcoded RSA-4096 placeholder instead of library-go's defaults (ECDSA P-256 / P-384). Leaf certs also ignore the PKI profile entirely and always generate RSA-2048. This diverges from what day-2 operators (CKAO, CKMO) expect when they read the PKI CR for certificate rotation.What
DefaultPKIProfile()with library-go's versionSignerKeyParamsto carry a fullPKIProfile+ConfigurablePKIEnabledResolveCertificateConfigWhy this is safe
Zero blast radius for default installs. Every cert asset has a clear feature-gate guard:
When the feature gate is off (all production installs today), the existing hand-rolled crypto runs unchanged. The new library-go path only executes under TechPreview/CustomNoUpgrade with ConfigurablePKI explicitly enabled.
Agent flow preserved.
SignerKeyParamsremains zero-dependency —agent create certificatescontinues to work without install-config on disk, generating RSA-2048 certs via the legacy path. This pattern was established in PR #10595 after review by zaneb, tthvo, and andfasano (see PR #10595 discussion).Easy to cull. When ConfigurablePKI is promoted to always-on, the legacy branches and the old
GenerateSignedCertificate()/PrivateKey()functions can be deleted in one sweep. No behavioral dependencies between the two paths.Design decisions from prior PRs
This PR builds on the stacked PRs #10594 and #10595 (both merged). Key decisions inherited:
SignerKeyParams(PR CNTRLPLANE-2012: Wire signer certs to read PKI config via SignerKeyParams #10595, zaneb's review): avoids pulling InstallConfig validation into agent flowsAssetBase.LoadFromFile(PR CNTRLPLANE-2012: Wire signer certs to read PKI config via SignerKeyParams #10595, tthvo's feedback): strict YAML parsing without platform validationSignerKeyParamsinManifestsandagentManifestsTargetfor multi-step state persistenceagentCertificatesTarget(PR CNTRLPLANE-2012: Wire signer certs to read PKI config via SignerKeyParams #10595, zaneb): "install-config is not an input to this command"Commit walkthrough
The commits are ordered to build incrementally:
vendor: bump library-go— vendor-only, no functional changespki: replace local DefaultPKIProfile with library-go—pkg/types/pki/defaults.goonly, smallpki: extend SignerKeyParams—signerkey_params.go+ all signer asset dependency updatestls: add resolveKeyGen helpers— single new file, 24 linestls: add library-go code path to SelfSignedCertKey and SignedCertKey— core engine change incertkey.gotls: wire feature-gate branches— bulk mechanical change, same pattern in every cert assettls: fix cert types for library-go path— JournalCertKey → Peer (serves HTTPS and authenticates curl client with same cert), AdminKubeConfigClientCertKey → Client only (drops legacy ServerAuth — verified on live cluster including localhost-recovery), dead code removalCommit 6 is the largest but entirely mechanical — each asset follows the same pattern from commit 5. Review one asset (e.g.,
root.go) and spot-check the rest.Test plan
hack/build.sh)agent create certificatesintegration test passes without install-configSummary by CodeRabbit