Skip to content

Commit 9b69e5f

Browse files
Merge pull request openshift#2836 from flavianmissi/update-vault-kms-plugin-validation
CNTRLPLANE-3361: update vault kms plugin validation
2 parents 49ae21b + 2ca5bc5 commit 9b69e5f

14 files changed

Lines changed: 356 additions & 106 deletions

config/v1/tests/apiservers.config.openshift.io/KMSEncryption.yaml

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,14 @@ featureGates:
55
- KMSEncryption
66
tests:
77
onCreate:
8-
- name: Should be able to create with KMS type without kms config
8+
- name: Should reject KMS encryption type without kms config
99
initial: |
1010
apiVersion: config.openshift.io/v1
1111
kind: APIServer
1212
spec:
1313
encryption:
1414
type: KMS
15-
expected: |
16-
apiVersion: config.openshift.io/v1
17-
kind: APIServer
18-
spec:
19-
audit:
20-
profile: Default
21-
encryption:
22-
type: KMS
15+
expectedError: "kms config is required when encryption type is KMS"
2316
- name: Should be able to create with aescbc encryption
2417
initial: |
2518
apiVersion: config.openshift.io/v1
@@ -65,3 +58,23 @@ tests:
6558
profile: Default
6659
encryption:
6760
type: identity
61+
62+
- name: Should reject kms config when encryption type is not KMS
63+
initial: |
64+
apiVersion: config.openshift.io/v1
65+
kind: APIServer
66+
spec:
67+
encryption:
68+
type: aescbc
69+
kms:
70+
type: Vault
71+
vault:
72+
kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
73+
vaultAddress: https://vault.example.com:8200
74+
authentication:
75+
type: AppRole
76+
appRole:
77+
secret:
78+
name: vault-approle
79+
transitKey: my-key
80+
expectedError: "kms config is required when encryption type is KMS, and forbidden otherwise"

config/v1/tests/apiservers.config.openshift.io/VaultKMS.yaml

Lines changed: 182 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,145 @@ tests:
209209
name: vault-approle
210210
transitKey: my-encryption-key
211211
212+
# RFC 3986 unreserved character tests
213+
- name: Should accept transitMount with period character
214+
initial: |
215+
apiVersion: config.openshift.io/v1
216+
kind: APIServer
217+
spec:
218+
encryption:
219+
type: KMS
220+
kms:
221+
type: Vault
222+
vault:
223+
kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
224+
vaultAddress: https://vault.example.com:8200
225+
authentication:
226+
type: AppRole
227+
appRole:
228+
secret:
229+
name: vault-approle
230+
transitMount: transit.v1
231+
transitKey: my-key
232+
expected: |
233+
apiVersion: config.openshift.io/v1
234+
kind: APIServer
235+
spec:
236+
audit:
237+
profile: Default
238+
encryption:
239+
type: KMS
240+
kms:
241+
type: Vault
242+
vault:
243+
kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
244+
vaultAddress: https://vault.example.com:8200
245+
authentication:
246+
type: AppRole
247+
appRole:
248+
secret:
249+
name: vault-approle
250+
transitMount: transit.v1
251+
transitKey: my-key
252+
253+
- name: Should accept transitMount with tilde character
254+
initial: |
255+
apiVersion: config.openshift.io/v1
256+
kind: APIServer
257+
spec:
258+
encryption:
259+
type: KMS
260+
kms:
261+
type: Vault
262+
vault:
263+
kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
264+
vaultAddress: https://vault.example.com:8200
265+
authentication:
266+
type: AppRole
267+
appRole:
268+
secret:
269+
name: vault-approle
270+
transitMount: transit~backup
271+
transitKey: my-key
272+
expected: |
273+
apiVersion: config.openshift.io/v1
274+
kind: APIServer
275+
spec:
276+
audit:
277+
profile: Default
278+
encryption:
279+
type: KMS
280+
kms:
281+
type: Vault
282+
vault:
283+
kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
284+
vaultAddress: https://vault.example.com:8200
285+
authentication:
286+
type: AppRole
287+
appRole:
288+
secret:
289+
name: vault-approle
290+
transitMount: transit~backup
291+
transitKey: my-key
292+
293+
- name: Should accept transitKey with period character
294+
initial: |
295+
apiVersion: config.openshift.io/v1
296+
kind: APIServer
297+
spec:
298+
encryption:
299+
type: KMS
300+
kms:
301+
type: Vault
302+
vault:
303+
kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
304+
vaultAddress: https://vault.example.com:8200
305+
authentication:
306+
type: AppRole
307+
appRole:
308+
secret:
309+
name: vault-approle
310+
transitKey: encryption.key.v1
311+
expected: |
312+
apiVersion: config.openshift.io/v1
313+
kind: APIServer
314+
spec:
315+
audit:
316+
profile: Default
317+
encryption:
318+
type: KMS
319+
kms:
320+
type: Vault
321+
vault:
322+
kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
323+
vaultAddress: https://vault.example.com:8200
324+
authentication:
325+
type: AppRole
326+
appRole:
327+
secret:
328+
name: vault-approle
329+
transitKey: encryption.key.v1
330+
331+
- name: Should reject transitKey with tilde character
332+
initial: |
333+
apiVersion: config.openshift.io/v1
334+
kind: APIServer
335+
spec:
336+
encryption:
337+
type: KMS
338+
kms:
339+
type: Vault
340+
vault:
341+
kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
342+
vaultAddress: https://vault.example.com:8200
343+
authentication:
344+
type: AppRole
345+
appRole:
346+
secret:
347+
name: vault-approle
348+
transitKey: key~backup
349+
expectedError: "transitKey must only contain alphanumeric characters, hyphens, periods, and underscores"
350+
212351
# Type validation - vault field must be set when type is Vault
213352
- name: Should reject KMS type Vault without vault config
214353
initial: |
@@ -632,7 +771,7 @@ tests:
632771
name: vault-approle
633772
transitMount: my transit
634773
transitKey: my-key
635-
expectedError: "transitMount cannot contain spaces"
774+
expectedError: "transitMount must only contain RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward slashes"
636775

637776
- name: Should reject transitMount containing consecutive forward slashes
638777
initial: |
@@ -674,7 +813,7 @@ tests:
674813
secret:
675814
name: vault-approle
676815
transitKey: my encryption key
677-
expectedError: "transitKey cannot contain spaces"
816+
expectedError: "transitKey must only contain alphanumeric characters, hyphens, periods, and underscores"
678817

679818
- name: Should reject transitKey containing forward slashes
680819
initial: |
@@ -696,6 +835,47 @@ tests:
696835
transitKey: my/key
697836
expectedError: "transitKey cannot contain forward slashes"
698837

838+
- name: Should reject transitMount with special characters
839+
initial: |
840+
apiVersion: config.openshift.io/v1
841+
kind: APIServer
842+
spec:
843+
encryption:
844+
type: KMS
845+
kms:
846+
type: Vault
847+
vault:
848+
kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
849+
vaultAddress: https://vault.example.com:8200
850+
authentication:
851+
type: AppRole
852+
appRole:
853+
secret:
854+
name: vault-approle
855+
transitMount: transit@test
856+
transitKey: my-key
857+
expectedError: "transitMount must only contain RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward slashes"
858+
859+
- name: Should reject transitKey with special characters
860+
initial: |
861+
apiVersion: config.openshift.io/v1
862+
kind: APIServer
863+
spec:
864+
encryption:
865+
type: KMS
866+
kms:
867+
type: Vault
868+
vault:
869+
kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
870+
vaultAddress: https://vault.example.com:8200
871+
authentication:
872+
type: AppRole
873+
appRole:
874+
secret:
875+
name: vault-approle
876+
transitKey: my@key
877+
expectedError: "transitKey must only contain alphanumeric characters, hyphens, periods, and underscores"
878+
699879
# serverName validation tests
700880
- name: Should reject invalid serverName
701881
initial: |

config/v1/types_apiserver.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ type APIServerNamedServingCert struct {
209209
}
210210

211211
// APIServerEncryption is used to encrypt sensitive resources on the cluster.
212+
// +openshift:validation:FeatureGateAwareXValidation:featureGate=KMSEncryption,rule="has(self.type) && self.type == 'KMS' ? has(self.kms) : !has(self.kms)",message="kms config is required when encryption type is KMS, and forbidden otherwise"
212213
// +union
213214
type APIServerEncryption struct {
214215
// type defines what encryption type should be used to encrypt resources at the datastore layer.

config/v1/types_kmsencryption.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,7 @@ const (
114114
type VaultAppRoleAuthentication struct {
115115
// secret references a secret in the openshift-config namespace containing
116116
// the AppRole credentials used to authenticate with Vault.
117-
// The secret must contain two keys: "roleID" for the AppRole Role ID and "secretID" for the AppRole Secret ID.
118-
//
119-
// The namespace for the secret is openshift-config.
117+
// The secret must contain two keys: "role-id" for the AppRole Role ID and "secret-id" for the AppRole Secret ID.
120118
//
121119
// +required
122120
Secret VaultSecretReference `json:"secret,omitzero"`
@@ -194,33 +192,35 @@ type VaultKMSPluginConfig struct {
194192
Authentication VaultAuthentication `json:"authentication,omitzero"`
195193

196194
// transitMount specifies the mount path of the Vault Transit engine.
197-
// The value must be between 1 and 1024 characters when specified.
198195
//
199196
// When omitted, this means the user has no opinion and the platform is left
200197
// to choose a reasonable default. These defaults are subject to change over time.
201198
// The current default is "transit".
202199
//
203-
// The mount path cannot start or end with a forward slash, cannot contain spaces,
204-
// and cannot contain consecutive forward slashes.
200+
// The transit mount must be between 1 and 1024 characters when specified, cannot start or
201+
// end with a forward slash, cannot contain consecutive forward slashes, and must only contain
202+
// RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward
203+
// slashes as path separators.
205204
//
206205
// +kubebuilder:validation:MinLength=1
207206
// +kubebuilder:validation:MaxLength=1024
208207
// +kubebuilder:validation:XValidation:rule="!self.startsWith('/')",message="transitMount cannot start with a forward slash"
209208
// +kubebuilder:validation:XValidation:rule="!self.endsWith('/')",message="transitMount cannot end with a forward slash"
210-
// +kubebuilder:validation:XValidation:rule="!self.contains(' ')",message="transitMount cannot contain spaces"
211209
// +kubebuilder:validation:XValidation:rule="!self.contains('//')",message="transitMount cannot contain consecutive forward slashes"
210+
// +kubebuilder:validation:XValidation:rule="self.matches('^[a-zA-Z0-9._~/-]+$')",message="transitMount must only contain RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward slashes"
212211
// +optional
213212
TransitMount string `json:"transitMount,omitempty"`
214213

215214
// transitKey specifies the name of the encryption key in Vault's Transit engine.
216215
// This key is used to encrypt and decrypt data.
217216
//
218-
// The key name must be between 1 and 512 characters and cannot contain spaces or forward slashes.
217+
// The transit key must be between 1 and 512 characters, cannot contain forward slashes,
218+
// and must only contain alphanumeric characters, hyphens, periods, and underscores.
219219
//
220220
// +kubebuilder:validation:MinLength=1
221221
// +kubebuilder:validation:MaxLength=512
222-
// +kubebuilder:validation:XValidation:rule="!self.contains(' ')",message="transitKey cannot contain spaces"
223222
// +kubebuilder:validation:XValidation:rule="!self.contains('/')",message="transitKey cannot contain forward slashes"
223+
// +kubebuilder:validation:XValidation:rule="self.matches('^[a-zA-Z0-9._-]+$')",message="transitKey must only contain alphanumeric characters, hyphens, periods, and underscores"
224224
// +required
225225
TransitKey string `json:"transitKey,omitempty"`
226226
}

config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,7 @@ spec:
196196
description: |-
197197
secret references a secret in the openshift-config namespace containing
198198
the AppRole credentials used to authenticate with Vault.
199-
The secret must contain two keys: "roleID" for the AppRole Role ID and "secretID" for the AppRole Secret ID.
200-
201-
The namespace for the secret is openshift-config.
199+
The secret must contain two keys: "role-id" for the AppRole Role ID and "secret-id" for the AppRole Secret ID.
202200
properties:
203201
name:
204202
description: |-
@@ -336,26 +334,29 @@ spec:
336334
transitKey specifies the name of the encryption key in Vault's Transit engine.
337335
This key is used to encrypt and decrypt data.
338336
339-
The key name must be between 1 and 512 characters and cannot contain spaces or forward slashes.
337+
The transit key must be between 1 and 512 characters, cannot contain forward slashes,
338+
and must only contain alphanumeric characters, hyphens, periods, and underscores.
340339
maxLength: 512
341340
minLength: 1
342341
type: string
343342
x-kubernetes-validations:
344-
- message: transitKey cannot contain spaces
345-
rule: '!self.contains('' '')'
346343
- message: transitKey cannot contain forward slashes
347344
rule: '!self.contains(''/'')'
345+
- message: transitKey must only contain alphanumeric characters,
346+
hyphens, periods, and underscores
347+
rule: self.matches('^[a-zA-Z0-9._-]+$')
348348
transitMount:
349349
description: |-
350350
transitMount specifies the mount path of the Vault Transit engine.
351-
The value must be between 1 and 1024 characters when specified.
352351
353352
When omitted, this means the user has no opinion and the platform is left
354353
to choose a reasonable default. These defaults are subject to change over time.
355354
The current default is "transit".
356355
357-
The mount path cannot start or end with a forward slash, cannot contain spaces,
358-
and cannot contain consecutive forward slashes.
356+
The transit mount must be between 1 and 1024 characters when specified, cannot start or
357+
end with a forward slash, cannot contain consecutive forward slashes, and must only contain
358+
RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward
359+
slashes as path separators.
359360
maxLength: 1024
360361
minLength: 1
361362
type: string
@@ -364,11 +365,13 @@ spec:
364365
rule: '!self.startsWith(''/'')'
365366
- message: transitMount cannot end with a forward slash
366367
rule: '!self.endsWith(''/'')'
367-
- message: transitMount cannot contain spaces
368-
rule: '!self.contains('' '')'
369368
- message: transitMount cannot contain consecutive forward
370369
slashes
371370
rule: '!self.contains(''//'')'
371+
- message: transitMount must only contain RFC 3986 unreserved
372+
characters (alphanumeric, hyphen, period, underscore,
373+
tilde) and forward slashes
374+
rule: self.matches('^[a-zA-Z0-9._~/-]+$')
372375
vaultAddress:
373376
description: |-
374377
vaultAddress specifies the address of the HashiCorp Vault instance.
@@ -452,6 +455,11 @@ spec:
452455
- KMS
453456
type: string
454457
type: object
458+
x-kubernetes-validations:
459+
- message: kms config is required when encryption type is KMS, and
460+
forbidden otherwise
461+
rule: 'has(self.type) && self.type == ''KMS'' ? has(self.kms) :
462+
!has(self.kms)'
455463
servingCerts:
456464
description: |-
457465
servingCert is the TLS cert info for serving secure traffic. If not specified, operator managed certificates

0 commit comments

Comments
 (0)