Skip to content

Commit 2ab8c63

Browse files
committed
tls: wire signer certs to read PKI config via SignerKeyParams
Introduce SignerKeyParams, a WritableAsset with zero dependencies that reads install-config.yaml directly from disk and extracts the effective PKI configuration via EffectiveSignerPKIConfig(). When no install-config is present, Load() returns (false, nil) so the asset store falls back to the state file between multi-step invocations (e.g. create manifests followed by create cluster, where install-config.yaml is consumed after the first step). In the agent flow where neither file nor state exists, Generate() leaves PKIConfig nil (RSA-2048). Signers that previously had zero dependencies now depend on SignerKeyParams instead of InstallConfig, avoiding validation that would reject configs valid in the agent flow. Signers that already depended on InstallConfig use EffectiveSignerPKIConfig() to resolve the effective PKI config including feature gate defaults. With TechPreview enabled and no explicit pki config, all signer certs are generated with RSA-4096 (the current DefaultPKIProfile default). Assisted-by: Claude Code (Opus 4.6)
1 parent ed2ed81 commit 2ab8c63

13 files changed

Lines changed: 159 additions & 47 deletions

pkg/asset/ignition/machine/arbiter_ignition_customizations_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,10 @@ func TestArbiterIgnitionCustomizationsGenerate(t *testing.T) {
8585

8686
for _, tc := range cases {
8787
t.Run(tc.name, func(t *testing.T) {
88+
rootCAParents := asset.Parents{}
89+
rootCAParents.Add(&tls.SignerKeyParams{})
8890
rootCA := &tls.RootCA{}
89-
err := rootCA.Generate(context.Background(), nil)
91+
err := rootCA.Generate(context.Background(), rootCAParents)
9092
assert.NoError(t, err, "unexpected error generating root CA")
9193

9294
parents := asset.Parents{}

pkg/asset/ignition/machine/arbiter_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,10 @@ func TestArbiterGenerate(t *testing.T) {
7070
}
7171
for _, tc := range testCases {
7272
t.Run(tc.description, func(t *testing.T) {
73+
rootCAParents := asset.Parents{}
74+
rootCAParents.Add(&tls.SignerKeyParams{})
7375
rootCA := &tls.RootCA{}
74-
err := rootCA.Generate(context.Background(), nil)
76+
err := rootCA.Generate(context.Background(), rootCAParents)
7577
assert.NoError(t, err, "unexpected error generating root CA")
7678

7779
parents := asset.Parents{}

pkg/asset/ignition/machine/master_ignition_customizations_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@ func TestMasterIgnitionCustomizationsGenerate(t *testing.T) {
4848
},
4949
})
5050

51+
rootCAParents := asset.Parents{}
52+
rootCAParents.Add(&tls.SignerKeyParams{})
5153
rootCA := &tls.RootCA{}
52-
err := rootCA.Generate(context.Background(), nil)
54+
err := rootCA.Generate(context.Background(), rootCAParents)
5355
assert.NoError(t, err, "unexpected error generating root CA")
5456

5557
parents := asset.Parents{}

pkg/asset/ignition/machine/master_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ func TestMasterGenerate(t *testing.T) {
3838
},
3939
})
4040

41+
rootCAParents := asset.Parents{}
42+
rootCAParents.Add(&tls.SignerKeyParams{})
4143
rootCA := &tls.RootCA{}
42-
err := rootCA.Generate(context.Background(), nil)
44+
err := rootCA.Generate(context.Background(), rootCAParents)
4345
assert.NoError(t, err, "unexpected error generating root CA")
4446

4547
parents := asset.Parents{}

pkg/asset/ignition/machine/worker_ignition_customizations_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@ func TestWorkerIgnitionCustomizationsGenerate(t *testing.T) {
4848
},
4949
})
5050

51+
rootCAParents := asset.Parents{}
52+
rootCAParents.Add(&tls.SignerKeyParams{})
5153
rootCA := &tls.RootCA{}
52-
err := rootCA.Generate(context.Background(), nil)
54+
err := rootCA.Generate(context.Background(), rootCAParents)
5355
assert.NoError(t, err, "unexpected error generating root CA")
5456

5557
parents := asset.Parents{}

pkg/asset/ignition/machine/worker_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ func TestWorkerGenerate(t *testing.T) {
2828
},
2929
})
3030

31+
rootCAParents := asset.Parents{}
32+
rootCAParents.Add(&tls.SignerKeyParams{})
3133
rootCA := &tls.RootCA{}
32-
err := rootCA.Generate(context.Background(), nil)
34+
err := rootCA.Generate(context.Background(), rootCAParents)
3335
assert.NoError(t, err, "unexpected error generating root CA")
3436

3537
parents := asset.Parents{}

pkg/asset/tls/adminkubeconfig.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,28 @@ type AdminKubeConfigSignerCertKey struct {
1515

1616
var _ asset.WritableAsset = (*AdminKubeConfigSignerCertKey)(nil)
1717

18-
// Dependencies returns no dependencies. Configurable PKI requires
18+
// Dependencies returns SignerKeyParams. Configurable PKI requires
1919
// reading the PKI config from InstallConfig, but adding InstallConfig
2020
// as a dependency here would break codepaths that generate signer certs
2121
// without an install-config on disk (e.g. agent create certificates,
22-
// node-joiner). A follow-up commit introduces an intermediate asset
23-
// that reads the config directly from disk without triggering
24-
// InstallConfig validation.
22+
// node-joiner). SignerKeyParams reads the config directly from disk
23+
// without triggering InstallConfig validation.
2524
func (c *AdminKubeConfigSignerCertKey) Dependencies() []asset.Asset {
26-
return []asset.Asset{}
25+
return []asset.Asset{&SignerKeyParams{}}
2726
}
2827

2928
// Generate generates the root-ca key and cert pair.
3029
func (c *AdminKubeConfigSignerCertKey) Generate(ctx context.Context, parents asset.Parents) error {
30+
signerKeyParams := &SignerKeyParams{}
31+
parents.Get(signerKeyParams)
3132
cfg := &CertCfg{
3233
Subject: pkix.Name{CommonName: "admin-kubeconfig-signer", OrganizationalUnit: []string{"openshift"}},
3334
// KeyUsages is set by GenerateSelfSignedCertificate based on the key algorithm.
3435
Validity: ValidityTenYears(),
3536
IsCA: true,
3637
}
3738

38-
return c.SelfSignedCertKey.Generate(ctx, cfg, "admin-kubeconfig-signer", nil)
39+
return c.SelfSignedCertKey.Generate(ctx, cfg, "admin-kubeconfig-signer", signerKeyParams.PKIConfig)
3940
}
4041

4142
// Load reads the asset files from disk.

pkg/asset/tls/aggregator.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/openshift/installer/pkg/asset"
99
"github.com/openshift/installer/pkg/asset/installconfig"
10+
pkidefaults "github.com/openshift/installer/pkg/types/pki"
1011
)
1112

1213
// AggregatorCA is the asset that generates the aggregator-ca key/cert pair.
@@ -38,7 +39,7 @@ func (a *AggregatorCA) Generate(ctx context.Context, dependencies asset.Parents)
3839
IsCA: true,
3940
}
4041

41-
return a.SelfSignedCertKey.Generate(ctx, cfg, "aggregator-ca", nil)
42+
return a.SelfSignedCertKey.Generate(ctx, cfg, "aggregator-ca", pkidefaults.EffectiveSignerPKIConfig(installConfig.Config))
4243
}
4344

4445
// Name returns the human-friendly name of the asset.
@@ -108,7 +109,7 @@ func (c *AggregatorSignerCertKey) Generate(ctx context.Context, parents asset.Pa
108109
IsCA: true,
109110
}
110111

111-
return c.SelfSignedCertKey.Generate(ctx, cfg, "aggregator-signer", nil)
112+
return c.SelfSignedCertKey.Generate(ctx, cfg, "aggregator-signer", pkidefaults.EffectiveSignerPKIConfig(installConfig.Config))
112113
}
113114

114115
// Name returns the human-friendly name of the asset.

pkg/asset/tls/apiserver.go

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
"github.com/openshift/installer/pkg/asset"
1212
"github.com/openshift/installer/pkg/asset/installconfig"
13+
pkidefaults "github.com/openshift/installer/pkg/types/pki"
1314
)
1415

1516
// KubeAPIServerToKubeletSignerCertKey is a key/cert pair that signs the kube-apiserver to kubelet client certs.
@@ -35,7 +36,7 @@ func (c *KubeAPIServerToKubeletSignerCertKey) Generate(ctx context.Context, pare
3536
IsCA: true,
3637
}
3738

38-
return c.SelfSignedCertKey.Generate(ctx, cfg, "kube-apiserver-to-kubelet-signer", nil)
39+
return c.SelfSignedCertKey.Generate(ctx, cfg, "kube-apiserver-to-kubelet-signer", pkidefaults.EffectiveSignerPKIConfig(installConfig.Config))
3940
}
4041

4142
// Name returns the human-friendly name of the asset.
@@ -116,27 +117,28 @@ type KubeAPIServerLocalhostSignerCertKey struct {
116117

117118
var _ asset.WritableAsset = (*KubeAPIServerLocalhostSignerCertKey)(nil)
118119

119-
// Dependencies returns no dependencies. Configurable PKI requires
120+
// Dependencies returns SignerKeyParams. Configurable PKI requires
120121
// reading the PKI config from InstallConfig, but adding InstallConfig
121122
// as a dependency here would break codepaths that generate signer certs
122123
// without an install-config on disk (e.g. agent create certificates,
123-
// node-joiner). A follow-up commit introduces an intermediate asset
124-
// that reads the config directly from disk without triggering
125-
// InstallConfig validation.
124+
// node-joiner). SignerKeyParams reads the config directly from disk
125+
// without triggering InstallConfig validation.
126126
func (c *KubeAPIServerLocalhostSignerCertKey) Dependencies() []asset.Asset {
127-
return []asset.Asset{}
127+
return []asset.Asset{&SignerKeyParams{}}
128128
}
129129

130130
// Generate generates the root-ca key and cert pair.
131131
func (c *KubeAPIServerLocalhostSignerCertKey) Generate(ctx context.Context, parents asset.Parents) error {
132+
signerKeyParams := &SignerKeyParams{}
133+
parents.Get(signerKeyParams)
132134
cfg := &CertCfg{
133135
Subject: pkix.Name{CommonName: "kube-apiserver-localhost-signer", OrganizationalUnit: []string{"openshift"}},
134136
// KeyUsages is set by GenerateSelfSignedCertificate based on the key algorithm.
135137
Validity: ValidityTenYears(),
136138
IsCA: true,
137139
}
138140

139-
return c.SelfSignedCertKey.Generate(ctx, cfg, "kube-apiserver-localhost-signer", nil)
141+
return c.SelfSignedCertKey.Generate(ctx, cfg, "kube-apiserver-localhost-signer", signerKeyParams.PKIConfig)
140142
}
141143

142144
// Load reads the asset files from disk.
@@ -226,27 +228,28 @@ type KubeAPIServerServiceNetworkSignerCertKey struct {
226228

227229
var _ asset.WritableAsset = (*KubeAPIServerServiceNetworkSignerCertKey)(nil)
228230

229-
// Dependencies returns no dependencies. Configurable PKI requires
231+
// Dependencies returns SignerKeyParams. Configurable PKI requires
230232
// reading the PKI config from InstallConfig, but adding InstallConfig
231233
// as a dependency here would break codepaths that generate signer certs
232234
// without an install-config on disk (e.g. agent create certificates,
233-
// node-joiner). A follow-up commit introduces an intermediate asset
234-
// that reads the config directly from disk without triggering
235-
// InstallConfig validation.
235+
// node-joiner). SignerKeyParams reads the config directly from disk
236+
// without triggering InstallConfig validation.
236237
func (c *KubeAPIServerServiceNetworkSignerCertKey) Dependencies() []asset.Asset {
237-
return []asset.Asset{}
238+
return []asset.Asset{&SignerKeyParams{}}
238239
}
239240

240241
// Generate generates the root-ca key and cert pair.
241242
func (c *KubeAPIServerServiceNetworkSignerCertKey) Generate(ctx context.Context, parents asset.Parents) error {
243+
signerKeyParams := &SignerKeyParams{}
244+
parents.Get(signerKeyParams)
242245
cfg := &CertCfg{
243246
Subject: pkix.Name{CommonName: "kube-apiserver-service-network-signer", OrganizationalUnit: []string{"openshift"}},
244247
// KeyUsages is set by GenerateSelfSignedCertificate based on the key algorithm.
245248
Validity: ValidityTenYears(),
246249
IsCA: true,
247250
}
248251

249-
return c.SelfSignedCertKey.Generate(ctx, cfg, "kube-apiserver-service-network-signer", nil)
252+
return c.SelfSignedCertKey.Generate(ctx, cfg, "kube-apiserver-service-network-signer", signerKeyParams.PKIConfig)
250253
}
251254

252255
// Load reads the asset files from disk.
@@ -345,27 +348,28 @@ type KubeAPIServerLBSignerCertKey struct {
345348

346349
var _ asset.WritableAsset = (*KubeAPIServerLBSignerCertKey)(nil)
347350

348-
// Dependencies returns no dependencies. Configurable PKI requires
351+
// Dependencies returns SignerKeyParams. Configurable PKI requires
349352
// reading the PKI config from InstallConfig, but adding InstallConfig
350353
// as a dependency here would break codepaths that generate signer certs
351354
// without an install-config on disk (e.g. agent create certificates,
352-
// node-joiner). A follow-up commit introduces an intermediate asset
353-
// that reads the config directly from disk without triggering
354-
// InstallConfig validation.
355+
// node-joiner). SignerKeyParams reads the config directly from disk
356+
// without triggering InstallConfig validation.
355357
func (c *KubeAPIServerLBSignerCertKey) Dependencies() []asset.Asset {
356-
return []asset.Asset{}
358+
return []asset.Asset{&SignerKeyParams{}}
357359
}
358360

359361
// Generate generates the root-ca key and cert pair.
360362
func (c *KubeAPIServerLBSignerCertKey) Generate(ctx context.Context, parents asset.Parents) error {
363+
signerKeyParams := &SignerKeyParams{}
364+
parents.Get(signerKeyParams)
361365
cfg := &CertCfg{
362366
Subject: pkix.Name{CommonName: "kube-apiserver-lb-signer", OrganizationalUnit: []string{"openshift"}},
363367
// KeyUsages is set by GenerateSelfSignedCertificate based on the key algorithm.
364368
Validity: ValidityTenYears(),
365369
IsCA: true,
366370
}
367371

368-
return c.SelfSignedCertKey.Generate(ctx, cfg, "kube-apiserver-lb-signer", nil)
372+
return c.SelfSignedCertKey.Generate(ctx, cfg, "kube-apiserver-lb-signer", signerKeyParams.PKIConfig)
369373
}
370374

371375
// Load reads the asset files from disk.

pkg/asset/tls/kubecontrolplane.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/openshift/installer/pkg/asset"
99
"github.com/openshift/installer/pkg/asset/installconfig"
10+
pkidefaults "github.com/openshift/installer/pkg/types/pki"
1011
)
1112

1213
// KubeControlPlaneSignerCertKey is a key/cert pair that signs the kube control-plane client certs.
@@ -32,7 +33,7 @@ func (c *KubeControlPlaneSignerCertKey) Generate(ctx context.Context, parents as
3233
IsCA: true,
3334
}
3435

35-
return c.SelfSignedCertKey.Generate(ctx, cfg, "kube-control-plane-signer", nil)
36+
return c.SelfSignedCertKey.Generate(ctx, cfg, "kube-control-plane-signer", pkidefaults.EffectiveSignerPKIConfig(installConfig.Config))
3637
}
3738

3839
// Name returns the human-friendly name of the asset.

0 commit comments

Comments
 (0)