From fa8dbea6eb8a3b2ad136e97f1c4b6c4c8b9caf61 Mon Sep 17 00:00:00 2001 From: Flavian Missi Date: Thu, 7 May 2026 15:02:38 +0200 Subject: [PATCH 1/3] update vault kms plugin api validation the new validation more closely aligns with vault's own validation. --- config/v1/types_apiserver.go | 1 + config/v1/types_kmsencryption.go | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/config/v1/types_apiserver.go b/config/v1/types_apiserver.go index b92a04ed06b..77a69b23242 100644 --- a/config/v1/types_apiserver.go +++ b/config/v1/types_apiserver.go @@ -209,6 +209,7 @@ type APIServerNamedServingCert struct { } // APIServerEncryption is used to encrypt sensitive resources on the cluster. +// +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" // +union type APIServerEncryption struct { // type defines what encryption type should be used to encrypt resources at the datastore layer. diff --git a/config/v1/types_kmsencryption.go b/config/v1/types_kmsencryption.go index 7ab8f782bb7..6c24abf36ab 100644 --- a/config/v1/types_kmsencryption.go +++ b/config/v1/types_kmsencryption.go @@ -114,9 +114,7 @@ const ( type VaultAppRoleAuthentication struct { // secret references a secret in the openshift-config namespace containing // the AppRole credentials used to authenticate with Vault. - // The secret must contain two keys: "roleID" for the AppRole Role ID and "secretID" for the AppRole Secret ID. - // - // The namespace for the secret is openshift-config. + // The secret must contain two keys: "role-id" for the AppRole Role ID and "secret-id" for the AppRole Secret ID. // // +required Secret VaultSecretReference `json:"secret,omitzero"` @@ -194,33 +192,35 @@ type VaultKMSConfig struct { Authentication VaultAuthentication `json:"authentication,omitzero"` // transitMount specifies the mount path of the Vault Transit engine. - // The value must be between 1 and 1024 characters when specified. // // When omitted, this means the user has no opinion and the platform is left // to choose a reasonable default. These defaults are subject to change over time. // The current default is "transit". // - // The mount path cannot start or end with a forward slash, cannot contain spaces, - // and cannot contain consecutive forward slashes. + // The transit mount must be between 1 and 1024 characters when specified, cannot start or + // end with a forward slash, cannot contain consecutive forward slashes, and must only contain + // RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward + // slashes as path separators. // // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=1024 // +kubebuilder:validation:XValidation:rule="!self.startsWith('/')",message="transitMount cannot start with a forward slash" // +kubebuilder:validation:XValidation:rule="!self.endsWith('/')",message="transitMount cannot end with a forward slash" - // +kubebuilder:validation:XValidation:rule="!self.contains(' ')",message="transitMount cannot contain spaces" // +kubebuilder:validation:XValidation:rule="!self.contains('//')",message="transitMount cannot contain consecutive forward slashes" + // +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" // +optional TransitMount string `json:"transitMount,omitempty"` // transitKey specifies the name of the encryption key in Vault's Transit engine. // This key is used to encrypt and decrypt data. // - // The key name must be between 1 and 512 characters and cannot contain spaces or forward slashes. + // The transit key must be between 1 and 512 characters, cannot contain forward slashes, + // and must only contain alphanumeric characters, hyphens, periods, and underscores. // // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=512 - // +kubebuilder:validation:XValidation:rule="!self.contains(' ')",message="transitKey cannot contain spaces" // +kubebuilder:validation:XValidation:rule="!self.contains('/')",message="transitKey cannot contain forward slashes" + // +kubebuilder:validation:XValidation:rule="self.matches('^[a-zA-Z0-9._-]+$')",message="transitKey must only contain alphanumeric characters, hyphens, periods, and underscores" // +required TransitKey string `json:"transitKey,omitempty"` } From dc3d3163d2fb8d5c83ed35b6763086aa8cfbb42e Mon Sep 17 00:00:00 2001 From: Flavian Missi Date: Thu, 7 May 2026 15:04:36 +0200 Subject: [PATCH 2/3] regenerate files --- ...tor_01_apiservers-CustomNoUpgrade.crd.yaml | 30 ++++++++++++------- ...01_apiservers-DevPreviewNoUpgrade.crd.yaml | 30 ++++++++++++------- ...1_apiservers-TechPreviewNoUpgrade.crd.yaml | 30 ++++++++++++------- .../KMSEncryption.yaml | 30 ++++++++++++------- .../v1/zz_generated.swagger_doc_generated.go | 6 ++-- .../generated_openapi/zz_generated.openapi.go | 6 ++-- openapi/openapi.json | 6 ++-- ...tor_01_apiservers-CustomNoUpgrade.crd.yaml | 30 ++++++++++++------- ...01_apiservers-DevPreviewNoUpgrade.crd.yaml | 30 ++++++++++++------- ...1_apiservers-TechPreviewNoUpgrade.crd.yaml | 30 ++++++++++++------- 10 files changed, 142 insertions(+), 86 deletions(-) diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml index 003fef92bef..816617c118b 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml @@ -196,9 +196,7 @@ spec: description: |- secret references a secret in the openshift-config namespace containing the AppRole credentials used to authenticate with Vault. - The secret must contain two keys: "roleID" for the AppRole Role ID and "secretID" for the AppRole Secret ID. - - The namespace for the secret is openshift-config. + The secret must contain two keys: "role-id" for the AppRole Role ID and "secret-id" for the AppRole Secret ID. properties: name: description: |- @@ -336,26 +334,29 @@ spec: transitKey specifies the name of the encryption key in Vault's Transit engine. This key is used to encrypt and decrypt data. - The key name must be between 1 and 512 characters and cannot contain spaces or forward slashes. + The transit key must be between 1 and 512 characters, cannot contain forward slashes, + and must only contain alphanumeric characters, hyphens, periods, and underscores. maxLength: 512 minLength: 1 type: string x-kubernetes-validations: - - message: transitKey cannot contain spaces - rule: '!self.contains('' '')' - message: transitKey cannot contain forward slashes rule: '!self.contains(''/'')' + - message: transitKey must only contain alphanumeric characters, + hyphens, periods, and underscores + rule: self.matches('^[a-zA-Z0-9._-]+$') transitMount: description: |- transitMount specifies the mount path of the Vault Transit engine. - The value must be between 1 and 1024 characters when specified. When omitted, this means the user has no opinion and the platform is left to choose a reasonable default. These defaults are subject to change over time. The current default is "transit". - The mount path cannot start or end with a forward slash, cannot contain spaces, - and cannot contain consecutive forward slashes. + The transit mount must be between 1 and 1024 characters when specified, cannot start or + end with a forward slash, cannot contain consecutive forward slashes, and must only contain + RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward + slashes as path separators. maxLength: 1024 minLength: 1 type: string @@ -364,11 +365,13 @@ spec: rule: '!self.startsWith(''/'')' - message: transitMount cannot end with a forward slash rule: '!self.endsWith(''/'')' - - message: transitMount cannot contain spaces - rule: '!self.contains('' '')' - message: transitMount cannot contain consecutive forward slashes rule: '!self.contains(''//'')' + - message: transitMount must only contain RFC 3986 unreserved + characters (alphanumeric, hyphen, period, underscore, + tilde) and forward slashes + rule: self.matches('^[a-zA-Z0-9._~/-]+$') vaultAddress: description: |- vaultAddress specifies the address of the HashiCorp Vault instance. @@ -452,6 +455,11 @@ spec: - KMS type: string type: object + x-kubernetes-validations: + - message: kms config is required when encryption type is KMS, and + forbidden otherwise + rule: 'has(self.type) && self.type == ''KMS'' ? has(self.kms) : + !has(self.kms)' servingCerts: description: |- servingCert is the TLS cert info for serving secure traffic. If not specified, operator managed certificates diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml index 8a70a13a312..69647dc6e7a 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml @@ -196,9 +196,7 @@ spec: description: |- secret references a secret in the openshift-config namespace containing the AppRole credentials used to authenticate with Vault. - The secret must contain two keys: "roleID" for the AppRole Role ID and "secretID" for the AppRole Secret ID. - - The namespace for the secret is openshift-config. + The secret must contain two keys: "role-id" for the AppRole Role ID and "secret-id" for the AppRole Secret ID. properties: name: description: |- @@ -336,26 +334,29 @@ spec: transitKey specifies the name of the encryption key in Vault's Transit engine. This key is used to encrypt and decrypt data. - The key name must be between 1 and 512 characters and cannot contain spaces or forward slashes. + The transit key must be between 1 and 512 characters, cannot contain forward slashes, + and must only contain alphanumeric characters, hyphens, periods, and underscores. maxLength: 512 minLength: 1 type: string x-kubernetes-validations: - - message: transitKey cannot contain spaces - rule: '!self.contains('' '')' - message: transitKey cannot contain forward slashes rule: '!self.contains(''/'')' + - message: transitKey must only contain alphanumeric characters, + hyphens, periods, and underscores + rule: self.matches('^[a-zA-Z0-9._-]+$') transitMount: description: |- transitMount specifies the mount path of the Vault Transit engine. - The value must be between 1 and 1024 characters when specified. When omitted, this means the user has no opinion and the platform is left to choose a reasonable default. These defaults are subject to change over time. The current default is "transit". - The mount path cannot start or end with a forward slash, cannot contain spaces, - and cannot contain consecutive forward slashes. + The transit mount must be between 1 and 1024 characters when specified, cannot start or + end with a forward slash, cannot contain consecutive forward slashes, and must only contain + RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward + slashes as path separators. maxLength: 1024 minLength: 1 type: string @@ -364,11 +365,13 @@ spec: rule: '!self.startsWith(''/'')' - message: transitMount cannot end with a forward slash rule: '!self.endsWith(''/'')' - - message: transitMount cannot contain spaces - rule: '!self.contains('' '')' - message: transitMount cannot contain consecutive forward slashes rule: '!self.contains(''//'')' + - message: transitMount must only contain RFC 3986 unreserved + characters (alphanumeric, hyphen, period, underscore, + tilde) and forward slashes + rule: self.matches('^[a-zA-Z0-9._~/-]+$') vaultAddress: description: |- vaultAddress specifies the address of the HashiCorp Vault instance. @@ -452,6 +455,11 @@ spec: - KMS type: string type: object + x-kubernetes-validations: + - message: kms config is required when encryption type is KMS, and + forbidden otherwise + rule: 'has(self.type) && self.type == ''KMS'' ? has(self.kms) : + !has(self.kms)' servingCerts: description: |- servingCert is the TLS cert info for serving secure traffic. If not specified, operator managed certificates diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml index 9cfd4f62176..dd9d44ea021 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml @@ -196,9 +196,7 @@ spec: description: |- secret references a secret in the openshift-config namespace containing the AppRole credentials used to authenticate with Vault. - The secret must contain two keys: "roleID" for the AppRole Role ID and "secretID" for the AppRole Secret ID. - - The namespace for the secret is openshift-config. + The secret must contain two keys: "role-id" for the AppRole Role ID and "secret-id" for the AppRole Secret ID. properties: name: description: |- @@ -336,26 +334,29 @@ spec: transitKey specifies the name of the encryption key in Vault's Transit engine. This key is used to encrypt and decrypt data. - The key name must be between 1 and 512 characters and cannot contain spaces or forward slashes. + The transit key must be between 1 and 512 characters, cannot contain forward slashes, + and must only contain alphanumeric characters, hyphens, periods, and underscores. maxLength: 512 minLength: 1 type: string x-kubernetes-validations: - - message: transitKey cannot contain spaces - rule: '!self.contains('' '')' - message: transitKey cannot contain forward slashes rule: '!self.contains(''/'')' + - message: transitKey must only contain alphanumeric characters, + hyphens, periods, and underscores + rule: self.matches('^[a-zA-Z0-9._-]+$') transitMount: description: |- transitMount specifies the mount path of the Vault Transit engine. - The value must be between 1 and 1024 characters when specified. When omitted, this means the user has no opinion and the platform is left to choose a reasonable default. These defaults are subject to change over time. The current default is "transit". - The mount path cannot start or end with a forward slash, cannot contain spaces, - and cannot contain consecutive forward slashes. + The transit mount must be between 1 and 1024 characters when specified, cannot start or + end with a forward slash, cannot contain consecutive forward slashes, and must only contain + RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward + slashes as path separators. maxLength: 1024 minLength: 1 type: string @@ -364,11 +365,13 @@ spec: rule: '!self.startsWith(''/'')' - message: transitMount cannot end with a forward slash rule: '!self.endsWith(''/'')' - - message: transitMount cannot contain spaces - rule: '!self.contains('' '')' - message: transitMount cannot contain consecutive forward slashes rule: '!self.contains(''//'')' + - message: transitMount must only contain RFC 3986 unreserved + characters (alphanumeric, hyphen, period, underscore, + tilde) and forward slashes + rule: self.matches('^[a-zA-Z0-9._~/-]+$') vaultAddress: description: |- vaultAddress specifies the address of the HashiCorp Vault instance. @@ -452,6 +455,11 @@ spec: - KMS type: string type: object + x-kubernetes-validations: + - message: kms config is required when encryption type is KMS, and + forbidden otherwise + rule: 'has(self.type) && self.type == ''KMS'' ? has(self.kms) : + !has(self.kms)' servingCerts: description: |- servingCert is the TLS cert info for serving secure traffic. If not specified, operator managed certificates diff --git a/config/v1/zz_generated.featuregated-crd-manifests/apiservers.config.openshift.io/KMSEncryption.yaml b/config/v1/zz_generated.featuregated-crd-manifests/apiservers.config.openshift.io/KMSEncryption.yaml index 7598c617642..60513640f05 100644 --- a/config/v1/zz_generated.featuregated-crd-manifests/apiservers.config.openshift.io/KMSEncryption.yaml +++ b/config/v1/zz_generated.featuregated-crd-manifests/apiservers.config.openshift.io/KMSEncryption.yaml @@ -196,9 +196,7 @@ spec: description: |- secret references a secret in the openshift-config namespace containing the AppRole credentials used to authenticate with Vault. - The secret must contain two keys: "roleID" for the AppRole Role ID and "secretID" for the AppRole Secret ID. - - The namespace for the secret is openshift-config. + The secret must contain two keys: "role-id" for the AppRole Role ID and "secret-id" for the AppRole Secret ID. properties: name: description: |- @@ -336,26 +334,29 @@ spec: transitKey specifies the name of the encryption key in Vault's Transit engine. This key is used to encrypt and decrypt data. - The key name must be between 1 and 512 characters and cannot contain spaces or forward slashes. + The transit key must be between 1 and 512 characters, cannot contain forward slashes, + and must only contain alphanumeric characters, hyphens, periods, and underscores. maxLength: 512 minLength: 1 type: string x-kubernetes-validations: - - message: transitKey cannot contain spaces - rule: '!self.contains('' '')' - message: transitKey cannot contain forward slashes rule: '!self.contains(''/'')' + - message: transitKey must only contain alphanumeric characters, + hyphens, periods, and underscores + rule: self.matches('^[a-zA-Z0-9._-]+$') transitMount: description: |- transitMount specifies the mount path of the Vault Transit engine. - The value must be between 1 and 1024 characters when specified. When omitted, this means the user has no opinion and the platform is left to choose a reasonable default. These defaults are subject to change over time. The current default is "transit". - The mount path cannot start or end with a forward slash, cannot contain spaces, - and cannot contain consecutive forward slashes. + The transit mount must be between 1 and 1024 characters when specified, cannot start or + end with a forward slash, cannot contain consecutive forward slashes, and must only contain + RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward + slashes as path separators. maxLength: 1024 minLength: 1 type: string @@ -364,11 +365,13 @@ spec: rule: '!self.startsWith(''/'')' - message: transitMount cannot end with a forward slash rule: '!self.endsWith(''/'')' - - message: transitMount cannot contain spaces - rule: '!self.contains('' '')' - message: transitMount cannot contain consecutive forward slashes rule: '!self.contains(''//'')' + - message: transitMount must only contain RFC 3986 unreserved + characters (alphanumeric, hyphen, period, underscore, + tilde) and forward slashes + rule: self.matches('^[a-zA-Z0-9._~/-]+$') vaultAddress: description: |- vaultAddress specifies the address of the HashiCorp Vault instance. @@ -452,6 +455,11 @@ spec: - KMS type: string type: object + x-kubernetes-validations: + - message: kms config is required when encryption type is KMS, and + forbidden otherwise + rule: 'has(self.type) && self.type == ''KMS'' ? has(self.kms) : + !has(self.kms)' servingCerts: description: |- servingCert is the TLS cert info for serving secure traffic. If not specified, operator managed certificates diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index b72f5bdb38e..0b4f3ff38c7 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -2341,7 +2341,7 @@ func (KMSConfig) SwaggerDoc() map[string]string { var map_VaultAppRoleAuthentication = map[string]string{ "": "VaultAppRoleAuthentication defines the configuration for AppRole authentication with Vault.", - "secret": "secret references a secret in the openshift-config namespace containing the AppRole credentials used to authenticate with Vault. The secret must contain two keys: \"roleID\" for the AppRole Role ID and \"secretID\" for the AppRole Secret ID.\n\nThe namespace for the secret is openshift-config.", + "secret": "secret references a secret in the openshift-config namespace containing the AppRole credentials used to authenticate with Vault. The secret must contain two keys: \"role-id\" for the AppRole Role ID and \"secret-id\" for the AppRole Secret ID.", } func (VaultAppRoleAuthentication) SwaggerDoc() map[string]string { @@ -2374,8 +2374,8 @@ var map_VaultKMSConfig = map[string]string{ "vaultNamespace": "vaultNamespace specifies the Vault namespace where the Transit secrets engine is mounted. This is only applicable for Vault Enterprise installations. When this field is not set, no namespace is used.\n\nThe value must be between 1 and 4096 characters. The namespace cannot end with a forward slash, cannot contain spaces, and cannot be one of the reserved strings: root, sys, audit, auth, cubbyhole, or identity.", "tls": "tls contains the TLS configuration for connecting to the Vault server. When this field is not set, system default TLS settings are used.", "authentication": "authentication defines the authentication method used to authenticate with Vault.", - "transitMount": "transitMount specifies the mount path of the Vault Transit engine. The value must be between 1 and 1024 characters when specified.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose a reasonable default. These defaults are subject to change over time. The current default is \"transit\".\n\nThe mount path cannot start or end with a forward slash, cannot contain spaces, and cannot contain consecutive forward slashes.", - "transitKey": "transitKey specifies the name of the encryption key in Vault's Transit engine. This key is used to encrypt and decrypt data.\n\nThe key name must be between 1 and 512 characters and cannot contain spaces or forward slashes.", + "transitMount": "transitMount specifies the mount path of the Vault Transit engine.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose a reasonable default. These defaults are subject to change over time. The current default is \"transit\".\n\nThe transit mount must be between 1 and 1024 characters when specified, cannot start or end with a forward slash, cannot contain consecutive forward slashes, and must only contain RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward slashes as path separators.", + "transitKey": "transitKey specifies the name of the encryption key in Vault's Transit engine. This key is used to encrypt and decrypt data.\n\nThe transit key must be between 1 and 512 characters, cannot contain forward slashes, and must only contain alphanumeric characters, hyphens, periods, and underscores.", } func (VaultKMSConfig) SwaggerDoc() map[string]string { diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 2aa177bbfc1..cb60cd91802 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -22380,7 +22380,7 @@ func schema_openshift_api_config_v1_VaultAppRoleAuthentication(ref common.Refere Properties: map[string]spec.Schema{ "secret": { SchemaProps: spec.SchemaProps{ - Description: "secret references a secret in the openshift-config namespace containing the AppRole credentials used to authenticate with Vault. The secret must contain two keys: \"roleID\" for the AppRole Role ID and \"secretID\" for the AppRole Secret ID.\n\nThe namespace for the secret is openshift-config.", + Description: "secret references a secret in the openshift-config namespace containing the AppRole credentials used to authenticate with Vault. The secret must contain two keys: \"role-id\" for the AppRole Role ID and \"secret-id\" for the AppRole Secret ID.", Default: map[string]interface{}{}, Ref: ref("github.com/openshift/api/config/v1.VaultSecretReference"), }, @@ -22501,14 +22501,14 @@ func schema_openshift_api_config_v1_VaultKMSConfig(ref common.ReferenceCallback) }, "transitMount": { SchemaProps: spec.SchemaProps{ - Description: "transitMount specifies the mount path of the Vault Transit engine. The value must be between 1 and 1024 characters when specified.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose a reasonable default. These defaults are subject to change over time. The current default is \"transit\".\n\nThe mount path cannot start or end with a forward slash, cannot contain spaces, and cannot contain consecutive forward slashes.", + Description: "transitMount specifies the mount path of the Vault Transit engine.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose a reasonable default. These defaults are subject to change over time. The current default is \"transit\".\n\nThe transit mount must be between 1 and 1024 characters when specified, cannot start or end with a forward slash, cannot contain consecutive forward slashes, and must only contain RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward slashes as path separators.", Type: []string{"string"}, Format: "", }, }, "transitKey": { SchemaProps: spec.SchemaProps{ - Description: "transitKey specifies the name of the encryption key in Vault's Transit engine. This key is used to encrypt and decrypt data.\n\nThe key name must be between 1 and 512 characters and cannot contain spaces or forward slashes.", + Description: "transitKey specifies the name of the encryption key in Vault's Transit engine. This key is used to encrypt and decrypt data.\n\nThe transit key must be between 1 and 512 characters, cannot contain forward slashes, and must only contain alphanumeric characters, hyphens, periods, and underscores.", Type: []string{"string"}, Format: "", }, diff --git a/openapi/openapi.json b/openapi/openapi.json index 5311926e17c..754bad43565 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -23703,7 +23703,7 @@ ], "properties": { "secret": { - "description": "secret references a secret in the openshift-config namespace containing the AppRole credentials used to authenticate with Vault. The secret must contain two keys: \"roleID\" for the AppRole Role ID and \"secretID\" for the AppRole Secret ID.\n\nThe namespace for the secret is openshift-config.", + "description": "secret references a secret in the openshift-config namespace containing the AppRole credentials used to authenticate with Vault. The secret must contain two keys: \"role-id\" for the AppRole Role ID and \"secret-id\" for the AppRole Secret ID.", "default": {}, "$ref": "#/definitions/com.github.openshift.api.config.v1.VaultSecretReference" } @@ -23773,11 +23773,11 @@ "$ref": "#/definitions/com.github.openshift.api.config.v1.VaultTLSConfig" }, "transitKey": { - "description": "transitKey specifies the name of the encryption key in Vault's Transit engine. This key is used to encrypt and decrypt data.\n\nThe key name must be between 1 and 512 characters and cannot contain spaces or forward slashes.", + "description": "transitKey specifies the name of the encryption key in Vault's Transit engine. This key is used to encrypt and decrypt data.\n\nThe transit key must be between 1 and 512 characters, cannot contain forward slashes, and must only contain alphanumeric characters, hyphens, periods, and underscores.", "type": "string" }, "transitMount": { - "description": "transitMount specifies the mount path of the Vault Transit engine. The value must be between 1 and 1024 characters when specified.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose a reasonable default. These defaults are subject to change over time. The current default is \"transit\".\n\nThe mount path cannot start or end with a forward slash, cannot contain spaces, and cannot contain consecutive forward slashes.", + "description": "transitMount specifies the mount path of the Vault Transit engine.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose a reasonable default. These defaults are subject to change over time. The current default is \"transit\".\n\nThe transit mount must be between 1 and 1024 characters when specified, cannot start or end with a forward slash, cannot contain consecutive forward slashes, and must only contain RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward slashes as path separators.", "type": "string" }, "vaultAddress": { diff --git a/payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml index 003fef92bef..816617c118b 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml @@ -196,9 +196,7 @@ spec: description: |- secret references a secret in the openshift-config namespace containing the AppRole credentials used to authenticate with Vault. - The secret must contain two keys: "roleID" for the AppRole Role ID and "secretID" for the AppRole Secret ID. - - The namespace for the secret is openshift-config. + The secret must contain two keys: "role-id" for the AppRole Role ID and "secret-id" for the AppRole Secret ID. properties: name: description: |- @@ -336,26 +334,29 @@ spec: transitKey specifies the name of the encryption key in Vault's Transit engine. This key is used to encrypt and decrypt data. - The key name must be between 1 and 512 characters and cannot contain spaces or forward slashes. + The transit key must be between 1 and 512 characters, cannot contain forward slashes, + and must only contain alphanumeric characters, hyphens, periods, and underscores. maxLength: 512 minLength: 1 type: string x-kubernetes-validations: - - message: transitKey cannot contain spaces - rule: '!self.contains('' '')' - message: transitKey cannot contain forward slashes rule: '!self.contains(''/'')' + - message: transitKey must only contain alphanumeric characters, + hyphens, periods, and underscores + rule: self.matches('^[a-zA-Z0-9._-]+$') transitMount: description: |- transitMount specifies the mount path of the Vault Transit engine. - The value must be between 1 and 1024 characters when specified. When omitted, this means the user has no opinion and the platform is left to choose a reasonable default. These defaults are subject to change over time. The current default is "transit". - The mount path cannot start or end with a forward slash, cannot contain spaces, - and cannot contain consecutive forward slashes. + The transit mount must be between 1 and 1024 characters when specified, cannot start or + end with a forward slash, cannot contain consecutive forward slashes, and must only contain + RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward + slashes as path separators. maxLength: 1024 minLength: 1 type: string @@ -364,11 +365,13 @@ spec: rule: '!self.startsWith(''/'')' - message: transitMount cannot end with a forward slash rule: '!self.endsWith(''/'')' - - message: transitMount cannot contain spaces - rule: '!self.contains('' '')' - message: transitMount cannot contain consecutive forward slashes rule: '!self.contains(''//'')' + - message: transitMount must only contain RFC 3986 unreserved + characters (alphanumeric, hyphen, period, underscore, + tilde) and forward slashes + rule: self.matches('^[a-zA-Z0-9._~/-]+$') vaultAddress: description: |- vaultAddress specifies the address of the HashiCorp Vault instance. @@ -452,6 +455,11 @@ spec: - KMS type: string type: object + x-kubernetes-validations: + - message: kms config is required when encryption type is KMS, and + forbidden otherwise + rule: 'has(self.type) && self.type == ''KMS'' ? has(self.kms) : + !has(self.kms)' servingCerts: description: |- servingCert is the TLS cert info for serving secure traffic. If not specified, operator managed certificates diff --git a/payload-manifests/crds/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml index 8a70a13a312..69647dc6e7a 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml @@ -196,9 +196,7 @@ spec: description: |- secret references a secret in the openshift-config namespace containing the AppRole credentials used to authenticate with Vault. - The secret must contain two keys: "roleID" for the AppRole Role ID and "secretID" for the AppRole Secret ID. - - The namespace for the secret is openshift-config. + The secret must contain two keys: "role-id" for the AppRole Role ID and "secret-id" for the AppRole Secret ID. properties: name: description: |- @@ -336,26 +334,29 @@ spec: transitKey specifies the name of the encryption key in Vault's Transit engine. This key is used to encrypt and decrypt data. - The key name must be between 1 and 512 characters and cannot contain spaces or forward slashes. + The transit key must be between 1 and 512 characters, cannot contain forward slashes, + and must only contain alphanumeric characters, hyphens, periods, and underscores. maxLength: 512 minLength: 1 type: string x-kubernetes-validations: - - message: transitKey cannot contain spaces - rule: '!self.contains('' '')' - message: transitKey cannot contain forward slashes rule: '!self.contains(''/'')' + - message: transitKey must only contain alphanumeric characters, + hyphens, periods, and underscores + rule: self.matches('^[a-zA-Z0-9._-]+$') transitMount: description: |- transitMount specifies the mount path of the Vault Transit engine. - The value must be between 1 and 1024 characters when specified. When omitted, this means the user has no opinion and the platform is left to choose a reasonable default. These defaults are subject to change over time. The current default is "transit". - The mount path cannot start or end with a forward slash, cannot contain spaces, - and cannot contain consecutive forward slashes. + The transit mount must be between 1 and 1024 characters when specified, cannot start or + end with a forward slash, cannot contain consecutive forward slashes, and must only contain + RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward + slashes as path separators. maxLength: 1024 minLength: 1 type: string @@ -364,11 +365,13 @@ spec: rule: '!self.startsWith(''/'')' - message: transitMount cannot end with a forward slash rule: '!self.endsWith(''/'')' - - message: transitMount cannot contain spaces - rule: '!self.contains('' '')' - message: transitMount cannot contain consecutive forward slashes rule: '!self.contains(''//'')' + - message: transitMount must only contain RFC 3986 unreserved + characters (alphanumeric, hyphen, period, underscore, + tilde) and forward slashes + rule: self.matches('^[a-zA-Z0-9._~/-]+$') vaultAddress: description: |- vaultAddress specifies the address of the HashiCorp Vault instance. @@ -452,6 +455,11 @@ spec: - KMS type: string type: object + x-kubernetes-validations: + - message: kms config is required when encryption type is KMS, and + forbidden otherwise + rule: 'has(self.type) && self.type == ''KMS'' ? has(self.kms) : + !has(self.kms)' servingCerts: description: |- servingCert is the TLS cert info for serving secure traffic. If not specified, operator managed certificates diff --git a/payload-manifests/crds/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml index 9cfd4f62176..dd9d44ea021 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml @@ -196,9 +196,7 @@ spec: description: |- secret references a secret in the openshift-config namespace containing the AppRole credentials used to authenticate with Vault. - The secret must contain two keys: "roleID" for the AppRole Role ID and "secretID" for the AppRole Secret ID. - - The namespace for the secret is openshift-config. + The secret must contain two keys: "role-id" for the AppRole Role ID and "secret-id" for the AppRole Secret ID. properties: name: description: |- @@ -336,26 +334,29 @@ spec: transitKey specifies the name of the encryption key in Vault's Transit engine. This key is used to encrypt and decrypt data. - The key name must be between 1 and 512 characters and cannot contain spaces or forward slashes. + The transit key must be between 1 and 512 characters, cannot contain forward slashes, + and must only contain alphanumeric characters, hyphens, periods, and underscores. maxLength: 512 minLength: 1 type: string x-kubernetes-validations: - - message: transitKey cannot contain spaces - rule: '!self.contains('' '')' - message: transitKey cannot contain forward slashes rule: '!self.contains(''/'')' + - message: transitKey must only contain alphanumeric characters, + hyphens, periods, and underscores + rule: self.matches('^[a-zA-Z0-9._-]+$') transitMount: description: |- transitMount specifies the mount path of the Vault Transit engine. - The value must be between 1 and 1024 characters when specified. When omitted, this means the user has no opinion and the platform is left to choose a reasonable default. These defaults are subject to change over time. The current default is "transit". - The mount path cannot start or end with a forward slash, cannot contain spaces, - and cannot contain consecutive forward slashes. + The transit mount must be between 1 and 1024 characters when specified, cannot start or + end with a forward slash, cannot contain consecutive forward slashes, and must only contain + RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward + slashes as path separators. maxLength: 1024 minLength: 1 type: string @@ -364,11 +365,13 @@ spec: rule: '!self.startsWith(''/'')' - message: transitMount cannot end with a forward slash rule: '!self.endsWith(''/'')' - - message: transitMount cannot contain spaces - rule: '!self.contains('' '')' - message: transitMount cannot contain consecutive forward slashes rule: '!self.contains(''//'')' + - message: transitMount must only contain RFC 3986 unreserved + characters (alphanumeric, hyphen, period, underscore, + tilde) and forward slashes + rule: self.matches('^[a-zA-Z0-9._~/-]+$') vaultAddress: description: |- vaultAddress specifies the address of the HashiCorp Vault instance. @@ -452,6 +455,11 @@ spec: - KMS type: string type: object + x-kubernetes-validations: + - message: kms config is required when encryption type is KMS, and + forbidden otherwise + rule: 'has(self.type) && self.type == ''KMS'' ? has(self.kms) : + !has(self.kms)' servingCerts: description: |- servingCert is the TLS cert info for serving secure traffic. If not specified, operator managed certificates From 2ca5bc5a8f5191b206caf8c7583ce8f7d02a0122 Mon Sep 17 00:00:00 2001 From: Flavian Missi Date: Thu, 7 May 2026 15:04:57 +0200 Subject: [PATCH 3/3] update vault kms plugin api tests --- .../KMSEncryption.yaml | 31 ++- .../VaultKMS.yaml | 184 +++++++++++++++++- 2 files changed, 204 insertions(+), 11 deletions(-) diff --git a/config/v1/tests/apiservers.config.openshift.io/KMSEncryption.yaml b/config/v1/tests/apiservers.config.openshift.io/KMSEncryption.yaml index 4d7310fb023..25a9afb6206 100644 --- a/config/v1/tests/apiservers.config.openshift.io/KMSEncryption.yaml +++ b/config/v1/tests/apiservers.config.openshift.io/KMSEncryption.yaml @@ -5,21 +5,14 @@ featureGates: - KMSEncryption tests: onCreate: - - name: Should be able to create with KMS type without kms config + - name: Should reject KMS encryption type without kms config initial: | apiVersion: config.openshift.io/v1 kind: APIServer spec: encryption: type: KMS - expected: | - apiVersion: config.openshift.io/v1 - kind: APIServer - spec: - audit: - profile: Default - encryption: - type: KMS + expectedError: "kms config is required when encryption type is KMS" - name: Should be able to create with aescbc encryption initial: | apiVersion: config.openshift.io/v1 @@ -65,3 +58,23 @@ tests: profile: Default encryption: type: identity + + - name: Should reject kms config when encryption type is not KMS + initial: | + apiVersion: config.openshift.io/v1 + kind: APIServer + spec: + encryption: + type: aescbc + kms: + type: Vault + vault: + kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + vaultAddress: https://vault.example.com:8200 + authentication: + type: AppRole + appRole: + secret: + name: vault-approle + transitKey: my-key + expectedError: "kms config is required when encryption type is KMS, and forbidden otherwise" diff --git a/config/v1/tests/apiservers.config.openshift.io/VaultKMS.yaml b/config/v1/tests/apiservers.config.openshift.io/VaultKMS.yaml index 61073d646af..34d37142fef 100644 --- a/config/v1/tests/apiservers.config.openshift.io/VaultKMS.yaml +++ b/config/v1/tests/apiservers.config.openshift.io/VaultKMS.yaml @@ -209,6 +209,145 @@ tests: name: vault-approle transitKey: my-encryption-key + # RFC 3986 unreserved character tests + - name: Should accept transitMount with period character + initial: | + apiVersion: config.openshift.io/v1 + kind: APIServer + spec: + encryption: + type: KMS + kms: + type: Vault + vault: + kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + vaultAddress: https://vault.example.com:8200 + authentication: + type: AppRole + appRole: + secret: + name: vault-approle + transitMount: transit.v1 + transitKey: my-key + expected: | + apiVersion: config.openshift.io/v1 + kind: APIServer + spec: + audit: + profile: Default + encryption: + type: KMS + kms: + type: Vault + vault: + kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + vaultAddress: https://vault.example.com:8200 + authentication: + type: AppRole + appRole: + secret: + name: vault-approle + transitMount: transit.v1 + transitKey: my-key + + - name: Should accept transitMount with tilde character + initial: | + apiVersion: config.openshift.io/v1 + kind: APIServer + spec: + encryption: + type: KMS + kms: + type: Vault + vault: + kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + vaultAddress: https://vault.example.com:8200 + authentication: + type: AppRole + appRole: + secret: + name: vault-approle + transitMount: transit~backup + transitKey: my-key + expected: | + apiVersion: config.openshift.io/v1 + kind: APIServer + spec: + audit: + profile: Default + encryption: + type: KMS + kms: + type: Vault + vault: + kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + vaultAddress: https://vault.example.com:8200 + authentication: + type: AppRole + appRole: + secret: + name: vault-approle + transitMount: transit~backup + transitKey: my-key + + - name: Should accept transitKey with period character + initial: | + apiVersion: config.openshift.io/v1 + kind: APIServer + spec: + encryption: + type: KMS + kms: + type: Vault + vault: + kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + vaultAddress: https://vault.example.com:8200 + authentication: + type: AppRole + appRole: + secret: + name: vault-approle + transitKey: encryption.key.v1 + expected: | + apiVersion: config.openshift.io/v1 + kind: APIServer + spec: + audit: + profile: Default + encryption: + type: KMS + kms: + type: Vault + vault: + kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + vaultAddress: https://vault.example.com:8200 + authentication: + type: AppRole + appRole: + secret: + name: vault-approle + transitKey: encryption.key.v1 + + - name: Should reject transitKey with tilde character + initial: | + apiVersion: config.openshift.io/v1 + kind: APIServer + spec: + encryption: + type: KMS + kms: + type: Vault + vault: + kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + vaultAddress: https://vault.example.com:8200 + authentication: + type: AppRole + appRole: + secret: + name: vault-approle + transitKey: key~backup + expectedError: "transitKey must only contain alphanumeric characters, hyphens, periods, and underscores" + # Type validation - vault field must be set when type is Vault - name: Should reject KMS type Vault without vault config initial: | @@ -632,7 +771,7 @@ tests: name: vault-approle transitMount: my transit transitKey: my-key - expectedError: "transitMount cannot contain spaces" + expectedError: "transitMount must only contain RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward slashes" - name: Should reject transitMount containing consecutive forward slashes initial: | @@ -674,7 +813,7 @@ tests: secret: name: vault-approle transitKey: my encryption key - expectedError: "transitKey cannot contain spaces" + expectedError: "transitKey must only contain alphanumeric characters, hyphens, periods, and underscores" - name: Should reject transitKey containing forward slashes initial: | @@ -696,6 +835,47 @@ tests: transitKey: my/key expectedError: "transitKey cannot contain forward slashes" + - name: Should reject transitMount with special characters + initial: | + apiVersion: config.openshift.io/v1 + kind: APIServer + spec: + encryption: + type: KMS + kms: + type: Vault + vault: + kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + vaultAddress: https://vault.example.com:8200 + authentication: + type: AppRole + appRole: + secret: + name: vault-approle + transitMount: transit@test + transitKey: my-key + expectedError: "transitMount must only contain RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward slashes" + + - name: Should reject transitKey with special characters + initial: | + apiVersion: config.openshift.io/v1 + kind: APIServer + spec: + encryption: + type: KMS + kms: + type: Vault + vault: + kmsPluginImage: registry.example.com/vault-plugin@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + vaultAddress: https://vault.example.com:8200 + authentication: + type: AppRole + appRole: + secret: + name: vault-approle + transitKey: my@key + expectedError: "transitKey must only contain alphanumeric characters, hyphens, periods, and underscores" + # serverName validation tests - name: Should reject invalid serverName initial: |