Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions api/hypershift/v1beta1/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,9 @@ type AzureNodePoolOSDisk struct {
// +kubebuilder:validation:XValidation:rule="!has(self.topology) || ((self.topology == 'Private' || self.topology == 'PublicAndPrivate') ? has(self.private) : !has(self.private))",message="private is required when topology is Private or PublicAndPrivate, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="!has(self.private) || self.private.type != 'PrivateLink' || self.azureAuthenticationConfig.azureAuthenticationConfigType != 'WorkloadIdentities' || has(self.azureAuthenticationConfig.workloadIdentities.controlPlaneOperator)",message="workloadIdentities.controlPlaneOperator is required when Private Link is configured with WorkloadIdentities authentication"
type AzurePlatformSpec struct {
// cloud is the cloud environment identifier, valid values could be found here: https://github.com/Azure/go-autorest/blob/4c0e21ca2bbb3251fe7853e6f9df6397f53dd419/autorest/azure/environments.go#L33
// cloud is the Azure cloud environment identifier.
//
// +kubebuilder:validation:Enum=AzurePublicCloud;AzureUSGovernmentCloud;AzureChinaCloud;AzureGermanCloud;AzureStackCloud
// +kubebuilder:validation:Enum=AzurePublicCloud;AzureUSGovernmentCloud;AzureChinaCloud;AzureGermanCloud;AzureBleuCloud;AzureStackCloud
// +kubebuilder:default="AzurePublicCloud"
// +optional
Cloud string `json:"cloud,omitempty"`
Expand Down Expand Up @@ -914,9 +914,10 @@ const (
AzureKeyVaultPrivate AzureKeyVaultAccessType = "Private"
)

// AzureKMSSpec defines metadata about the configuration of the Azure KMS Secret Encryption provider using Azure key vault
// AzureKMSSpec defines metadata about the configuration of the Azure KMS Secret Encryption provider using Azure Key Vault or Managed HSM.
//
// +kubebuilder:validation:XValidation:rule="!has(self.backupKey) || self.backupKey.keyVaultName == self.activeKey.keyVaultName",message="backupKey.keyVaultName must match activeKey.keyVaultName; both keys must reside in the same Key Vault"
// +kubebuilder:validation:XValidation:rule="(has(self.keyVaultType) ? self.keyVaultType : 'KeyVault') == (has(oldSelf.keyVaultType) ? oldSelf.keyVaultType : 'KeyVault')",message="keyVaultType is immutable"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

As a note, this rule is only enforceable if the parent field for this type - which appears to be optional - is not removed first.

If the parent field is removed, an end-user can re-apply a different configuration, circumventing this immutability constraint.

In order for true immutability, these types of rules need to be enforced at the highest parent field in the tree that is a required field.

I won't block on this as this has already merged previously, but we should at least make a note of needing to resolve this if we want true immutability here.

type AzureKMSSpec struct {
// activeKey defines the active key used to encrypt new secrets
//
Expand All @@ -935,6 +936,15 @@ type AzureKMSSpec struct {
// +required
KMS ManagedIdentity `json:"kms"`

// keyVaultType specifies whether activeKey and backupKey are hosted by Azure Key Vault or Azure Managed HSM.
// Valid values are "KeyVault" and "ManagedHSM".
// When set to "KeyVault", both keys are hosted by Azure Key Vault.
// When set to "ManagedHSM", both keys are hosted by Azure Managed HSM.
// The type is immutable; key rotation must remain within the same service.
// When omitted, the keys are treated as Key Vault keys.
// +optional
KeyVaultType AzureKMSKeyVaultType `json:"keyVaultType,omitempty"`

// keyVaultAccess specifies how the Key Vault should be accessed.
// When set to "Private", the control plane routes Key Vault traffic through
// the private router to reach the Key Vault's private endpoint in the customer VNet.
Expand All @@ -944,16 +954,28 @@ type AzureKMSSpec struct {
KeyVaultAccess AzureKeyVaultAccessType `json:"keyVaultAccess,omitempty"`
}

// AzureKMSKeyVaultType specifies the Azure service that hosts a KMS key.
// +kubebuilder:validation:Enum=KeyVault;ManagedHSM
type AzureKMSKeyVaultType string

const (
// AzureKMSKeyVaultTypeKeyVault indicates that the key is hosted by Azure Key Vault.
AzureKMSKeyVaultTypeKeyVault AzureKMSKeyVaultType = "KeyVault"
// AzureKMSKeyVaultTypeManagedHSM indicates that the key is hosted by Azure Managed HSM.
AzureKMSKeyVaultTypeManagedHSM AzureKMSKeyVaultType = "ManagedHSM"
)

// AzureKMSKey defines an Azure Key Vault or Managed HSM key used for KMS encryption.
type AzureKMSKey struct {
// keyVaultName is the name of the keyvault. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
// Your Microsoft Entra application used to create the cluster must be authorized to access this keyvault, e.g using the AzureCLI:
// keyVaultName is the name of the Key Vault or Managed HSM. Must match criteria specified at https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#vault-name-and-object-name
// Your Microsoft Entra application used to create the cluster must be authorized to access this resource, e.g using the AzureCLI:
// `az keyvault set-policy -n $KEYVAULT_NAME --key-permissions decrypt encrypt --spn <YOUR APPLICATION CLIENT ID>`
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=255
// +required
KeyVaultName string `json:"keyVaultName,omitempty"`

// keyName is the name of the keyvault key used for encrypt/decrypt
// keyName is the name of the key used for encrypt/decrypt.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=255
// +required
Expand Down
27 changes: 15 additions & 12 deletions api/hypershift/v1beta1/etcdbackup_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,14 +178,15 @@ type HCPEtcdBackupAzureBlob struct {
// +required
Credentials SecretReference `json:"credentials,omitzero"`

// encryptionKeyURL is the URL of the Azure Key Vault key used for encryption.
// Must be a valid Azure Key Vault key URL in the format
// "https://<vault-name>.vault.azure.net/keys/<key-name>[/<key-version>]".
// encryptionKeyURL is the URL of the Azure Key Vault or Managed HSM key used for encryption.
// Key Vault URLs are supported in Azure Public Cloud (vault.azure.net), Azure US Government Cloud (vault.usgovcloudapi.net), Azure China Cloud (vault.azure.cn), Azure German Cloud (vault.microsoftazure.de), and Azure Bleu Cloud (vault.sovcloud-api.fr).
// Managed HSM URLs are supported in Azure Public Cloud (managedhsm.azure.net), Azure US Government Cloud (managedhsm.usgovcloudapi.net), Azure China Cloud (managedhsm.azure.cn), Azure German Cloud (managedhsm.microsoftazure.de), and Azure Bleu Cloud (managedhsm.sovcloud-api.fr).
// Supporting another cloud requires adding its DNS suffix to this validation and the Azure endpoint resolver.
// This field is immutable once set and cannot be removed.
// +optional
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=210
// +kubebuilder:validation:XValidation:rule="self.matches('^https://[a-zA-Z0-9-]+\\\\.vault\\\\.azure\\\\.net/keys/[a-zA-Z0-9-]+(/[a-zA-Z0-9]+)?$')",message="encryptionKeyURL must be a valid Azure Key Vault HTTPS URL (https://<vault>.vault.azure.net/keys/<key-name>[/<key-version>])"
// +kubebuilder:validation:XValidation:rule="self.matches('^https://[a-zA-Z0-9-]+\\\\.(vault\\\\.(azure\\\\.net|usgovcloudapi\\\\.net|azure\\\\.cn|microsoftazure\\\\.de|sovcloud-api\\\\.fr)|managedhsm\\\\.(azure\\\\.net|usgovcloudapi\\\\.net|azure\\\\.cn|microsoftazure\\\\.de|sovcloud-api\\\\.fr))/keys/[a-zA-Z0-9-]+(/[a-zA-Z0-9]+)?$')",message="encryptionKeyURL must be a valid Azure Key Vault or Managed HSM HTTPS URL"
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="encryptionKeyURL is immutable"
EncryptionKeyURL string `json:"encryptionKeyURL,omitempty"`
}
Expand Down Expand Up @@ -249,13 +250,14 @@ type HCPEtcdBackupEncryptionMetadataAWS struct {
// HCPEtcdBackupEncryptionMetadataAzure contains Azure-specific encryption metadata.
// The values here reflect the encryption settings from the HCPEtcdBackupConfig input.
type HCPEtcdBackupEncryptionMetadataAzure struct {
// encryptionKeyURL is the URL of the Azure Key Vault key used for encryption of the backup.
// Must be a valid Azure Key Vault key URL in the format
// "https://<vault-name>.vault.azure.net/keys/<key-name>[/<key-version>]".
// encryptionKeyURL is the URL of the Azure Key Vault or Managed HSM key used for encryption of the backup.
// Key Vault URLs are supported in Azure Public Cloud (vault.azure.net), Azure US Government Cloud (vault.usgovcloudapi.net), Azure China Cloud (vault.azure.cn), Azure German Cloud (vault.microsoftazure.de), and Azure Bleu Cloud (vault.sovcloud-api.fr).
// Managed HSM URLs are supported in Azure Public Cloud (managedhsm.azure.net), Azure US Government Cloud (managedhsm.usgovcloudapi.net), Azure China Cloud (managedhsm.azure.cn), Azure German Cloud (managedhsm.microsoftazure.de), and Azure Bleu Cloud (managedhsm.sovcloud-api.fr).
// Supporting another cloud requires adding its DNS suffix to this validation and the Azure endpoint resolver.
// +required
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=210
// +kubebuilder:validation:XValidation:rule="self.matches('^https://[a-zA-Z0-9-]+\\\\.vault\\\\.azure\\\\.net/keys/[a-zA-Z0-9-]+(/[a-zA-Z0-9]+)?$')",message="encryptionKeyURL must be a valid Azure Key Vault HTTPS URL (https://<vault>.vault.azure.net/keys/<key-name>[/<key-version>])"
// +kubebuilder:validation:XValidation:rule="self.matches('^https://[a-zA-Z0-9-]+\\\\.(vault\\\\.(azure\\\\.net|usgovcloudapi\\\\.net|azure\\\\.cn|microsoftazure\\\\.de|sovcloud-api\\\\.fr)|managedhsm\\\\.(azure\\\\.net|usgovcloudapi\\\\.net|azure\\\\.cn|microsoftazure\\\\.de|sovcloud-api\\\\.fr))/keys/[a-zA-Z0-9-]+(/[a-zA-Z0-9]+)?$')",message="encryptionKeyURL must be a valid Azure Key Vault or Managed HSM HTTPS URL"
EncryptionKeyURL string `json:"encryptionKeyURL,omitempty"`
}

Expand Down Expand Up @@ -349,12 +351,13 @@ type HCPEtcdBackupConfigAWS struct {

// HCPEtcdBackupConfigAzure defines Azure-specific encryption settings for etcd backups.
type HCPEtcdBackupConfigAzure struct {
// encryptionKeyURL is the URL of the Azure Key Vault key to use for encrypting etcd backup artifacts.
// Must be a valid Azure Key Vault key URL in the format
// "https://<vault-name>.vault.azure.net/keys/<key-name>[/<key-version>]".
// encryptionKeyURL is the URL of the Azure Key Vault or Managed HSM key to use for encrypting etcd backup artifacts.
// Key Vault URLs are supported in Azure Public Cloud (vault.azure.net), Azure US Government Cloud (vault.usgovcloudapi.net), Azure China Cloud (vault.azure.cn), Azure German Cloud (vault.microsoftazure.de), and Azure Bleu Cloud (vault.sovcloud-api.fr).
// Managed HSM URLs are supported in Azure Public Cloud (managedhsm.azure.net), Azure US Government Cloud (managedhsm.usgovcloudapi.net), Azure China Cloud (managedhsm.azure.cn), Azure German Cloud (managedhsm.microsoftazure.de), and Azure Bleu Cloud (managedhsm.sovcloud-api.fr).
// Supporting another cloud requires adding its DNS suffix to this validation and the Azure endpoint resolver.
// +required
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=210
// +kubebuilder:validation:XValidation:rule="self.matches('^https://[a-zA-Z0-9-]+\\\\.vault\\\\.azure\\\\.net/keys/[a-zA-Z0-9-]+(/[a-zA-Z0-9]+)?$')",message="encryptionKeyURL must be a valid Azure Key Vault HTTPS URL (https://<vault>.vault.azure.net/keys/<key-name>[/<key-version>])"
// +kubebuilder:validation:XValidation:rule="self.matches('^https://[a-zA-Z0-9-]+\\\\.(vault\\\\.(azure\\\\.net|usgovcloudapi\\\\.net|azure\\\\.cn|microsoftazure\\\\.de|sovcloud-api\\\\.fr)|managedhsm\\\\.(azure\\\\.net|usgovcloudapi\\\\.net|azure\\\\.cn|microsoftazure\\\\.de|sovcloud-api\\\\.fr))/keys/[a-zA-Z0-9-]+(/[a-zA-Z0-9]+)?$')",message="encryptionKeyURL must be a valid Azure Key Vault or Managed HSM HTTPS URL"
EncryptionKeyURL string `json:"encryptionKeyURL,omitempty"`
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,18 @@ spec:
type: object
encryptionKeyURL:
description: |-
encryptionKeyURL is the URL of the Azure Key Vault key used for encryption.
Must be a valid Azure Key Vault key URL in the format
"https://<vault-name>.vault.azure.net/keys/<key-name>[/<key-version>]".
encryptionKeyURL is the URL of the Azure Key Vault or Managed HSM key used for encryption.
Key Vault URLs are supported in Azure Public Cloud (vault.azure.net), Azure US Government Cloud (vault.usgovcloudapi.net), Azure China Cloud (vault.azure.cn), Azure German Cloud (vault.microsoftazure.de), and Azure Bleu Cloud (vault.sovcloud-api.fr).
Managed HSM URLs are supported in Azure Public Cloud (managedhsm.azure.net), Azure US Government Cloud (managedhsm.usgovcloudapi.net), Azure China Cloud (managedhsm.azure.cn), Azure German Cloud (managedhsm.microsoftazure.de), and Azure Bleu Cloud (managedhsm.sovcloud-api.fr).
Supporting another cloud requires adding its DNS suffix to this validation and the Azure endpoint resolver.
This field is immutable once set and cannot be removed.
maxLength: 210
minLength: 1
type: string
x-kubernetes-validations:
- message: encryptionKeyURL must be a valid Azure Key Vault
HTTPS URL (https://<vault>.vault.azure.net/keys/<key-name>[/<key-version>])
rule: self.matches('^https://[a-zA-Z0-9-]+\\.vault\\.azure\\.net/keys/[a-zA-Z0-9-]+(/[a-zA-Z0-9]+)?$')
or Managed HSM HTTPS URL
rule: self.matches('^https://[a-zA-Z0-9-]+\\.(vault\\.(azure\\.net|usgovcloudapi\\.net|azure\\.cn|microsoftazure\\.de|sovcloud-api\\.fr)|managedhsm\\.(azure\\.net|usgovcloudapi\\.net|azure\\.cn|microsoftazure\\.de|sovcloud-api\\.fr))/keys/[a-zA-Z0-9-]+(/[a-zA-Z0-9]+)?$')
- message: encryptionKeyURL is immutable
rule: self == oldSelf
keyPrefix:
Expand Down Expand Up @@ -372,16 +373,17 @@ spec:
properties:
encryptionKeyURL:
description: |-
encryptionKeyURL is the URL of the Azure Key Vault key used for encryption of the backup.
Must be a valid Azure Key Vault key URL in the format
"https://<vault-name>.vault.azure.net/keys/<key-name>[/<key-version>]".
encryptionKeyURL is the URL of the Azure Key Vault or Managed HSM key used for encryption of the backup.
Key Vault URLs are supported in Azure Public Cloud (vault.azure.net), Azure US Government Cloud (vault.usgovcloudapi.net), Azure China Cloud (vault.azure.cn), Azure German Cloud (vault.microsoftazure.de), and Azure Bleu Cloud (vault.sovcloud-api.fr).
Managed HSM URLs are supported in Azure Public Cloud (managedhsm.azure.net), Azure US Government Cloud (managedhsm.usgovcloudapi.net), Azure China Cloud (managedhsm.azure.cn), Azure German Cloud (managedhsm.microsoftazure.de), and Azure Bleu Cloud (managedhsm.sovcloud-api.fr).
Supporting another cloud requires adding its DNS suffix to this validation and the Azure endpoint resolver.
maxLength: 210
minLength: 1
type: string
x-kubernetes-validations:
- message: encryptionKeyURL must be a valid Azure Key Vault
HTTPS URL (https://<vault>.vault.azure.net/keys/<key-name>[/<key-version>])
rule: self.matches('^https://[a-zA-Z0-9-]+\\.vault\\.azure\\.net/keys/[a-zA-Z0-9-]+(/[a-zA-Z0-9]+)?$')
or Managed HSM HTTPS URL
rule: self.matches('^https://[a-zA-Z0-9-]+\\.(vault\\.(azure\\.net|usgovcloudapi\\.net|azure\\.cn|microsoftazure\\.de|sovcloud-api\\.fr)|managedhsm\\.(azure\\.net|usgovcloudapi\\.net|azure\\.cn|microsoftazure\\.de|sovcloud-api\\.fr))/keys/[a-zA-Z0-9-]+(/[a-zA-Z0-9]+)?$')
required:
- encryptionKeyURL
type: object
Expand Down
Loading
Loading