Skip to content

[Feature Request]: Align Customer-Managed-Key implementations (CMK) accross modules as much as possible #1484

@AlexanderSehr

Description

@AlexanderSehr

Description

Ideally, all our modules should use the same interface for customer managed keys. For example input parameters such as:

@description('Optional. Enable service encryption.')
param enableEncryption bool = true

@description('Optional. The resource ID of a key vault to reference a customer managed key for encryption from.')
param cMKKeyVaultResourceId string = ''

@description('Optional. The name of the customer managed key to use for encryption.')
param cMKKeyName string = ''

@description('Conditional. User assigned identity to use when fetching the customer managed key. If not provided, a system-assigned identity can be used - but must be given access to the referenced key vault first.')
param cMKUserAssignedIdentityResourceId string = ''

@description('Optional. The version of the customer managed key to reference for encryption. If not provided, the latest key version is used.')
param cMKKeyVersion string = ''

And also the implementation inside the module should ideally be similar. Note however, this cannot always be achieved as each provider has a different interpretation, and e.g. identities sometimes require a resource ID, sometimes a client ID, properties are in different locations, versions are required/not, etc. However, if we can shield the consumer as much as possible, the user experience will be a lot better.

  1. As a first step, we should agree on an interface (e.g. the parameter above)
  2. Then we should decide on some fundamental inside the module. E.g. how to not deploy encryption, how to do it with Azure-manged keys, and how to do it with customer-manged keys. For example
    // Note this is just a mockup
     encryption: enableEncryption && !empty(cMKKeyName) ? {
       // Customer-managed key
       keySource: 'Microsoft.KeyVault'
       keyVaultProperties: {
         identityClientId: !empty(cMKUserAssignedIdentityResourceId ) ? cmkUserAssignedIdentity.properties.clientId : null
         keyVaultUri: cmkKeyVault.properties.vaultUri 
         keyName: cMKKeyName
         keyVersion: cMKKeyVersion
       }
     } : enableEncryption ? {
       // Service-managed key
       keySource: 'Microsoft.CognitiveServices/accounts'
     } : null

Further, we can use the following snippet to lift the burder for users to specify key versions:

resource cMKKeyVaultKey 'Microsoft.KeyVault/vaults/keys@2021-10-01' existing = if (!empty(cMKKeyVaultResourceId) && !empty(cMKKeyName)) {
  name: '${last(split(cMKKeyVaultResourceId, '/'))}/${cMKKeyName}'
  scope: resourceGroup(split(cMKKeyVaultResourceId, '/')[2], split(cMKKeyVaultResourceId, '/')[4])
}

# Allows the use of
keyUrl: !empty(cMKKeyVersion) ? '${cMKKeyVaultKey.properties.keyUri}/${cMKKeyVersion}' : cMKKeyVaultKey.properties.keyUriWithVersion

Metadata

Metadata

Assignees

Labels

[cat] modulescategory: modules[prio] mediumimportance of the issue: medium priorityenhancementNew feature or request

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions