|
| 1 | +--- |
| 2 | +title: Configure customer-managed keys (CMK) for the FHIR service in Azure Health Data Services |
| 3 | +description: Use customer-managed keys (CMK) to encrypt data in the FHIR service. Create and manage CMK in Azure Key Vault and update the encryption key with a managed identity. |
| 4 | +author: expekesheth |
| 5 | +ms.service: healthcare-apis |
| 6 | +ms.subservice: fhir |
| 7 | +ms.topic: how-to |
| 8 | +ms.date: 11/20/2023 |
| 9 | +ms.author: kesheth |
| 10 | +--- |
| 11 | + |
| 12 | +# Configure customer-managed keys for the FHIR service |
| 13 | + |
| 14 | +By using customer-managed keys (CMK), you can protect and control access to your organization's data with keys that you create and manage. You use [Azure Key Vault](../../key-vault/index.yml) to create and manage CMK and then use the keys to encrypt the data stored by the FHIR® service. |
| 15 | + |
| 16 | +Customer-managed keys enable you to: |
| 17 | + |
| 18 | +- Create your own encryption keys and store them in a key vault, or use the [Azure Key Vault API](/rest/api/keyvault/) to generate keys. |
| 19 | + |
| 20 | +- Maintain full control and responsibility for the key lifecycle, including key rotation. |
| 21 | + |
| 22 | +## Prerequisites |
| 23 | +- Make sure you're familiar with [best practices for customer-managed keys](customer-managed-keys.md). |
| 24 | + |
| 25 | +- Verify you're assigned the [Azure Contributor](../../role-based-access-control/role-assignments-steps.md) RBAC role, which lets you create and modify Azure resources. |
| 26 | + |
| 27 | +- Add a key for the FHIR service in Azure Key Vault. For steps, see [Add a key in Azure Key Vault](../../key-vault/keys/quick-create-portal.md#add-a-key-to-key-vault). Customer-managed keys must meet these requirements: |
| 28 | + |
| 29 | + - The key is versioned. |
| 30 | + |
| 31 | + - The key type is **RSA**. |
| 32 | + |
| 33 | + - The key is **2048-bit** or **3072-bit**. |
| 34 | + |
| 35 | + - The key vault is located in the same region as a created resource, but can be in different Azure subscriptions or tenants. |
| 36 | + |
| 37 | + - The combined length for the key vault name and key name can't exceed **94 characters**. |
| 38 | + |
| 39 | + - When using a key vault with a firewall to disable public access, the option to **Allow trusted Microsoft services to bypass this firewall** must be enabled. |
| 40 | + |
| 41 | + - To prevent losing the encryption key for the FHIR service, the key vault or managed HSM must have **soft delete** and **purge protection** enabled. These features allow you to recover deleted keys for a certain time (default 90 days) and block permanent deletion until that time is over. |
| 42 | + |
| 43 | +> [!NOTE] |
| 44 | +>>The FHIR service supports attaching one identity type (either a system-assigned or user-assigned identity). Changing the identity type might impact background jobs such as export and import if the identity type is already mapped. |
| 45 | + |
| 46 | +## Update the FHIR service with the encryption key |
| 47 | + |
| 48 | +After you add the key, you need to update the FHIR service with the key URL. |
| 49 | + |
| 50 | +1. In the key vault, select **Keys**. |
| 51 | + |
| 52 | +2. Select the key for the FHIR service. |
| 53 | + |
| 54 | +:::image type="content" source="media/configure-customer-managed-keys/key-vault-list.png" alt-text="Screenshot of the Keys page and the key to use with the FHIR service." lightbox="media/configure-customer-managed-keys/key-vault-list.png"::: |
| 55 | + |
| 56 | +3. Select the key version. |
| 57 | + |
| 58 | +4. Copy the **Key Identifier**. You need the key URL when you update the key by using an ARM template. |
| 59 | + |
| 60 | +:::image type="content" source="media/configure-customer-managed-keys/key-vault-url.png" alt-text="Screenshot showing the key version details and the copy action for the Key Identifier." lightbox="media/configure-customer-managed-keys/key-vault-url.png"::: |
| 61 | + |
| 62 | +You update the key for the FHIR service by using the Azure portal or an ARM template. During the update, you choose whether to use a system-assigned or user-assigned managed identity. For a system-assigned managed identity, make sure to assign the **Key Vault Crypto Service Encryption User** role. For more information, see [Assign Azure roles using the Azure portal](/azure/role-based-access-control/role-assignments-portal). |
| 63 | + |
| 64 | +### Update the key by using the Azure portal |
| 65 | + |
| 66 | +1. In the Azure portal, go to the FHIR service and then select **Encryption** from the left pane. |
| 67 | + |
| 68 | +1. Select **Customer-managed key** for the Encryption type. |
| 69 | + |
| 70 | +1. Select a key vault and key or enter the Key URI for the key that was created previously. |
| 71 | + |
| 72 | +1. Select an identity type, either System-assigned or User-assigned, that matches the type of managed identity configured previously. |
| 73 | + |
| 74 | +1. Select **Save** to update the FHIR service to use the customer-managed key. |
| 75 | + |
| 76 | +:::image type="content" source="media/configure-customer-managed-keys/configure-encryption-portal.png" alt-text="Screenshot of the Encryption view, showing the selection of the Customer-managed key option, key vault settings, identity type settings, and Save button." lightbox="media/configure-customer-managed-keys/configure-encryption-portal.png"::: |
| 77 | + |
| 78 | +### Update the key by using an ARM template |
| 79 | + |
| 80 | + Use the Azure portal to **Deploy a custom template** and use one of the ARM templates to update the key. For more information, see [Create and deploy ARM templates by using the Azure portal](../../azure-resource-manager/templates/quickstart-create-templates-use-the-portal.md). |
| 81 | + |
| 82 | +#### ARM template for a system-assigned managed identity |
| 83 | + |
| 84 | +``` json |
| 85 | +{ |
| 86 | + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", |
| 87 | + "contentVersion": "1.0.0.0", |
| 88 | + "parameters": { |
| 89 | + "workspaceName": { |
| 90 | + "type": "String" |
| 91 | + }, |
| 92 | + "fhirServiceName": { |
| 93 | + "type": "String" |
| 94 | + }, |
| 95 | + "keyEncryptionKeyUrl": { |
| 96 | + "type": "String" |
| 97 | + }, |
| 98 | + "region": { |
| 99 | + "defaultValue": "West US 3", |
| 100 | + "type": "String" |
| 101 | + } |
| 102 | + }, |
| 103 | + "resources": [ |
| 104 | + { |
| 105 | + "type": "Microsoft.HealthcareApis/workspaces/fhirservices", |
| 106 | + "apiVersion": "2023-06-01-preview", |
| 107 | + "name": "[concat(parameters('workspaceName'), '/', parameters('fhirServiceName'))]", |
| 108 | + "location": "[parameters('region')]", |
| 109 | + "identity": { |
| 110 | + "type": "SystemAssigned" |
| 111 | + }, |
| 112 | + "properties": { |
| 113 | + "encryption": { |
| 114 | + "customerManagedKeyEncryption": { |
| 115 | + "keyEncryptionKeyUrl": "[parameters('keyEncryptionKeyUrl')]" |
| 116 | + } |
| 117 | + } |
| 118 | + } |
| 119 | + } |
| 120 | + ] |
| 121 | +} |
| 122 | +``` |
| 123 | +#### ARM template for a user-assigned managed identity |
| 124 | + |
| 125 | +```json |
| 126 | +{ |
| 127 | + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", |
| 128 | + "contentVersion": "1.0.0.0", |
| 129 | + "parameters": { |
| 130 | + "workspaceName": { |
| 131 | + "type": "String" |
| 132 | + }, |
| 133 | + "fhirServiceName": { |
| 134 | + "type": "String" |
| 135 | + }, |
| 136 | + "keyVaultName": { |
| 137 | + "type": "String" |
| 138 | + }, |
| 139 | + "keyName": { |
| 140 | + "type": "String" |
| 141 | + }, |
| 142 | + "userAssignedIdentityName": { |
| 143 | + "type": "String" |
| 144 | + }, |
| 145 | + "roleAssignmentName": { |
| 146 | + "type": "String" |
| 147 | + }, |
| 148 | + "region": { |
| 149 | + "defaultValue": "West US 3", |
| 150 | + "type": "String" |
| 151 | + }, |
| 152 | + "tenantId": { |
| 153 | + "type": "String" |
| 154 | + } |
| 155 | + }, |
| 156 | + "resources": [ |
| 157 | + { |
| 158 | + "type": "Microsoft.KeyVault/vaults", |
| 159 | + "apiVersion": "2022-07-01", |
| 160 | + "name": "[parameters('keyVaultName')]", |
| 161 | + "location": "[parameters('region')]", |
| 162 | + "properties": { |
| 163 | + "accessPolicies": [], |
| 164 | + "enablePurgeProtection": true, |
| 165 | + "enableRbacAuthorization": true, |
| 166 | + "enableSoftDelete": true, |
| 167 | + "sku": { |
| 168 | + "family": "A", |
| 169 | + "name": "standard" |
| 170 | + }, |
| 171 | + "tenantId": "[parameters('tenantId')]" |
| 172 | + } |
| 173 | + }, |
| 174 | + { |
| 175 | + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", |
| 176 | + "apiVersion": "2023-01-31", |
| 177 | + "name": "[parameters('userAssignedIdentityName')]", |
| 178 | + "location": "[parameters('region')]" |
| 179 | + }, |
| 180 | + { |
| 181 | + "type": "Microsoft.KeyVault/vaults/keys", |
| 182 | + "apiVersion": "2022-07-01", |
| 183 | + "name": "[concat(parameters('keyVaultName'), '/', parameters('keyName'))]", |
| 184 | + "properties": { |
| 185 | + "attributes": { |
| 186 | + "enabled": true |
| 187 | + }, |
| 188 | + "curveName": "P-256", |
| 189 | + "keyOps": [ "unwrapKey","wrapKey" ], |
| 190 | + "keySize": 2048, |
| 191 | + "kty": "RSA" |
| 192 | + }, |
| 193 | + "dependsOn": [ |
| 194 | + "[resourceId('Microsoft.KeyVault/vaults/', parameters('keyVaultName'))]" |
| 195 | + ] |
| 196 | + }, |
| 197 | + { |
| 198 | + "type": "Microsoft.Authorization/roleAssignments", |
| 199 | + "apiVersion": "2021-04-01-preview", |
| 200 | + "name": "[guid(parameters('roleAssignmentName'))]", |
| 201 | + "properties": { |
| 202 | + "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', '14b46e9e-c2b7-41b4-b07b-48a6ebf60603')]", |
| 203 | + "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName'))).principalId]" |
| 204 | + }, |
| 205 | + "dependsOn": [ |
| 206 | + "[resourceId('Microsoft.KeyVault/vaults/keys', parameters('keyVaultName'), parameters('keyName'))]", |
| 207 | + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName'))]" |
| 208 | + ] |
| 209 | + }, |
| 210 | + { |
| 211 | + "type": "Microsoft.HealthcareApis/workspaces", |
| 212 | + "name": "[parameters('workspaceName')]", |
| 213 | + "apiVersion": "2022-05-15", |
| 214 | + "location": "[parameters('region')]" |
| 215 | + }, |
| 216 | + { |
| 217 | + "type": "Microsoft.HealthcareApis/workspaces/fhirservices", |
| 218 | + "apiVersion": "2023-06-01-preview", |
| 219 | + "name": "[concat(parameters('workspaceName'), '/', parameters('fhirServiceName'))]", |
| 220 | + "location": "[parameters('region')]", |
| 221 | + "dependsOn": [ |
| 222 | + "[resourceId('Microsoft.HealthcareApis/workspaces', parameters('workspaceName'))]", |
| 223 | + "[resourceId('Microsoft.Authorization/roleAssignments', guid(parameters('roleAssignmentName')))]" |
| 224 | + ], |
| 225 | + "identity": { |
| 226 | + "type": "userAssigned", |
| 227 | + "userAssignedIdentities": { |
| 228 | + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('userAssignedIdentityName'))]": {} |
| 229 | + } |
| 230 | + }, |
| 231 | + "properties": { |
| 232 | + "encryption": { |
| 233 | + "customerManagedKeyEncryption": { |
| 234 | + "keyEncryptionKeyUrl": "[reference(resourceId('Microsoft.KeyVault/vaults/keys', parameters('keyVaultName'), parameters('keyName'))).keyUriWithVersion]" |
| 235 | + } |
| 236 | + } |
| 237 | + } |
| 238 | + } |
| 239 | + ] |
| 240 | +} |
| 241 | +``` |
| 242 | + |
| 243 | +1. When prompted, select the values for the resource group, region, workspace, and FHIR service name. |
| 244 | + |
| 245 | + * If you're using a system-assigned managed identity, enter the **Key Identifier** you copied from the key vault in the **Key Encryption Key Url** field. |
| 246 | + * If you're using a user-assigned managed identity, enter the values for the key vault name, key name, user assigned identity name, and tenant ID. |
| 247 | + |
| 248 | +1. Select **Review + create** to deploy the updates to the key. |
| 249 | + |
| 250 | +:::image type="content" source="media/configure-customer-managed-keys/arm-deploy.png" alt-text="Screenshot of the deployment template with details, including Key Encryption Key URL filled in." lightbox="media/configure-customer-managed-keys/arm-deploy.png"::: |
| 251 | + |
| 252 | +## Configure a key when you create the FHIR service |
| 253 | + |
| 254 | +If you use a user-assigned managed identity with the FHIR service, you can configure customer-managed keys at the same time you create the FHIR service. |
| 255 | + |
| 256 | +1. On the **Create FHIR service** page, enter the **FHIR service name**. |
| 257 | + |
| 258 | +2. Choose **Next: Security**. |
| 259 | + |
| 260 | + :::image type="content" source="media/configure-customer-managed-keys/deploy-name.png" alt-text="Screenshot of the Create FHIR service view with the FHIR service name filled in." lightbox="media/configure-customer-managed-keys/deploy-name.png"::: |
| 261 | + |
| 262 | +3. On the **Security** tab, in the **Encryption section** select **Customer-managed key**. |
| 263 | + |
| 264 | +4. Choose **Select from key vault** or **Enter key URI** and then enter the key. |
| 265 | + |
| 266 | +5. Choose **Select an identity** to use the user-assigned managed identity. On the Select user assigned managed identity page, filter for and then select the managed identity. Choose **Add**. |
| 267 | + |
| 268 | +6. On the **Security** tab, choose **Review + create**. |
| 269 | + |
| 270 | + :::image type="content" source="media/configure-customer-managed-keys/deploy-security-tab.png" alt-text="Screenshot of the Security tab with the Customer-managed key option selected." lightbox="media/configure-customer-managed-keys/deploy-security-tab.png"::: |
| 271 | + |
| 272 | +7. On the **Review + create** tab, review the summary of the configuration options and the validation success message. Choose **Create** to deploy the FHIR service with customer-managed keys. |
| 273 | + |
| 274 | + :::image type="content" source="media/configure-customer-managed-keys/deploy-review.png" alt-text="Screenshot of the Review + create tab with the selected options and validation success message shown." lightbox="media/configure-customer-managed-keys/deploy-review.png"::: |
| 275 | + |
| 276 | +## Recover from lost key access |
| 277 | + |
| 278 | +For the FHIR service to operate properly, it must always have access to the key in the key vault. However, there are scenarios where the service could lose access to the key, including: |
| 279 | + |
| 280 | +- The key is disabled or deleted from the key vault. |
| 281 | + |
| 282 | +- The FHIR service system-assigned managed identity is disabled. |
| 283 | + |
| 284 | +- The FHIR service system-assigned managed identity loses access to the key vault. |
| 285 | + |
| 286 | +In any scenario where the FHIR service can't access the key, API requests return with `500` errors and the data is inaccessible until access to the key is restored. |
| 287 | + |
| 288 | +If key access is lost, ensure you updated the key and required resources so they're accessible by the FHIR service. |
| 289 | + |
| 290 | +## Resolve common errors |
| 291 | +Common errors that cause databases to become inaccessible are usually due to configuration issues. For more information, see [Common errors with customer-managed keys](/sql/relational-databases/security/encryption/troubleshoot-tde). |
| 292 | + |
| 293 | +[!INCLUDE [FHIR trademark statement](../includes/healthcare-apis-fhir-trademark.md)] |
0 commit comments