Skip to content

Commit cd4a8df

Browse files
committed
Update concepts-data-encryption.md
1 parent fab718f commit cd4a8df

File tree

1 file changed

+351
-3
lines changed

1 file changed

+351
-3
lines changed

articles/postgresql/flexible-server/concepts-data-encryption.md

Lines changed: 351 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ The DEKs, encrypted with the KEKs, are stored separately. Only an entity with ac
5050

5151
Azure Active Directory [user- assigned managed identity](../../active-directory/managed-identities-azure-resources/overview.md) will be used to connect and retrieve customer-managed key. Follow this [tutorial](../../active-directory/managed-identities-azure-resources/qs-configure-portal-windows-vm.md) to create identity.
5252

53-
For a PostgreSQL server to use customer-managed keys stored in Key Vault for encryption of the DEK, a Key Vault administrator gives the following access rights to the server:
53+
54+
For a PostgreSQL server to use customer-managed keys stored in Key Vault for encryption of the DEK, a Key Vault administrator gives the following **access rights** to the managed identity created above:
5455

5556
- **get**: For retrieving, the public part and properties of the key in the key Vault.
5657

@@ -61,6 +62,9 @@ For a PostgreSQL server to use customer-managed keys stored in Key Vault for enc
6162
- **unwrapKey**: To be able to decrypt the DEK. Azure Database for PostgreSQL needs the decrypted DEK to encrypt/decrypt the data
6263

6364
The key vault administrator can also [enable logging of Key Vault audit events](../../key-vault/general/howto-logging.md?tabs=azure-cli), so they can be audited later.
65+
> [!IMPORTANT]
66+
> Not providing above access rights to the Key Vault to managed identity for access to KeyVault may result in failure to fetch encryption key and subsequent failed setup of the Customer Managed Key (CMK) feature.
67+
6468

6569
When the server is configured to use the customer-managed key stored in the key Vault, the server sends the DEK to the key Vault for encryptions. Key Vault returns the encrypted DEK stored in the user database. Similarly, when needed, the server sends the protected DEK to the key Vault for decryption. Auditors can use Azure Monitor to review Key Vault audit event logs, if logging is enabled.
6670

@@ -72,7 +76,7 @@ The following are requirements for configuring Key Vault:
7276

7377
- The key Vault must be set with 90 days for 'Days to retain deleted vaults'. If the existing key Vault has been configured with a lower number, you'll need to create a new key vault as it can't be modified after creation.
7478

75-
- Enable the soft-delete feature on the key Vault, to protect from data loss if an accidental key (or Key Vault) deletion happens. Soft-deleted resources are retained for 90 days unless the user recovers or purges them in the meantime. The recover and purge actions have their own permissions associated with a Key Vault access policy. The soft-delete feature is off by default, but you can enable it through PowerShell or the Azure CLI (note that you can't enable it through the Azure portal).
79+
- **Enable the soft-delete feature on the key Vault**, to protect from data loss if an accidental key (or Key Vault) deletion happens. Soft-deleted resources are retained for 90 days unless the user recovers or purges them in the meantime. The recover and purge actions have their own permissions associated with a Key Vault access policy. The soft-delete feature is off by default, but you can enable it through PowerShell or the Azure CLI (note that you can't enable it through the Azure portal).
7680

7781
- Enable Purge protection to enforce a mandatory retention period for deleted vaults and vault objects
7882

@@ -115,7 +119,7 @@ Here are recommendations for configuring a customer-managed key:
115119

116120
It might happen that someone with sufficient access rights to Key Vault accidentally disables server access to the key by:
117121

118-
- Revoking the Key Vault's list, get, wrapKey, and unwrapKey permissions from the identity used to retrieve key in KeyVault.
122+
- Revoking the Key Vault's **list**, **get**, **wrapKey**, and **unwrapKey** permissions from the identity used to retrieve key in KeyVault.
119123

120124
- Deleting the key.
121125

@@ -238,6 +242,9 @@ Follow the steps below to update CMK on CMK enabled Flexible Server using Azure
238242

239243
### CLI
240244

245+
The Azure command-line interface (Azure CLI) is a set of commands used to create and manage Azure resources. The Azure CLI is available across Azure services and is designed to get you working quickly with Azure, with an emphasis on automation.
246+
247+
241248
Prerequisites:
242249
- You must have an Azure subscription and be an administrator on that subscription.
243250
- Key Vault with key in region where Postgres Flex Server will be created. Follow this [tutorial](../../key-vault/general/quick-create-portal.md) to create Key Vault and generate key.
@@ -251,6 +258,347 @@ Follow the steps below to change\rotate key or identity after creation of server
251258
```azurecli-interactive
252259
az postgres flexible-server update --resource-group <resource_group> --name <server_name> --key $newKeyIdentifier --identity <identity_name>
253260
```
261+
262+
### Azure Resource Manager (ARM)
263+
ARM templates are a form of infrastructure as code, a concept where you define the infrastructure you need to be deployed.
264+
Using ARM templates in managing your Azure environment has many benefits, as declarative syntax removes the requirement of writing complicated deployment scripts to handle multiple deployment scenarios. For more on ARM templates see this [doc](../../azure-resource-manager/templates/overview.md)
265+
266+
Prerequisites:
267+
- You must have an Azure subscription and be an administrator on that subscription.
268+
- Key Vault with key in region where Postgres Flex Server will be created. Follow this [tutorial](../../key-vault/general/quick-create-portal.md) to create Key Vault and generate key.
269+
270+
Following is an example Azure ARM template that creates server with Customer MANAGED kEY (CMK) based encryption as defined in *dataEncryptionData* section of ARM template
271+
```json
272+
{
273+
"$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
274+
"contentVersion": "1.0.0.0",
275+
"parameters":
276+
{
277+
"administratorLogin":
278+
{
279+
"type": "string"
280+
},
281+
"administratorLoginPassword":
282+
{
283+
"type": "securestring"
284+
},
285+
"target":
286+
{
287+
"type": "string"
288+
},
289+
"name":
290+
{
291+
"type": "string"
292+
},
293+
"serverEdition":
294+
{
295+
"type": "string",
296+
"defaultValue": "GeneralPurpose"
297+
},
298+
"storageSizeGB":
299+
{
300+
"type": "int",
301+
"defaultValue": 128
302+
},
303+
"haEnabled":
304+
{
305+
"type": "string",
306+
"defaultValue": "Disabled"
307+
},
308+
"availabilityZone":
309+
{
310+
"type": "string",
311+
"defaultValue": "1"
312+
},
313+
"standbyAvailabilityZone":
314+
{
315+
"type": "string",
316+
"defaultValue": "2"
317+
},
318+
"version":
319+
{
320+
"type": "string"
321+
},
322+
"tags":
323+
{
324+
"type": "object",
325+
"defaultValue":
326+
{}
327+
},
328+
"firewallRules":
329+
{
330+
"type": "object",
331+
"defaultValue":
332+
{}
333+
},
334+
"backupRetentionDays":
335+
{
336+
"type": "int"
337+
},
338+
"geoRedundantBackup":
339+
{
340+
"type": "string"
341+
},
342+
"vmName":
343+
{
344+
"type": "string",
345+
"defaultValue": "Standard_D4s_v3"
346+
},
347+
"vnetData":
348+
{
349+
"type": "object",
350+
"metadata":
351+
{
352+
"description": "Vnet data is an object which contains all parameters pertaining to vnet and subnet"
353+
},
354+
"defaultValue":
355+
{
356+
"virtualNetworkName": "",
357+
"subnetName": "",
358+
"privateDnsZoneName": "",
359+
"Network":
360+
{}
361+
}
362+
},
363+
"userAssignedIdentitity":
364+
{
365+
"type": "string",
366+
"defaultValue": "postgresflexi"
367+
},
368+
"managedIdentityType":
369+
{
370+
"type": "string",
371+
"defaultValue": "UserAssigned"
372+
},
373+
"identityData":
374+
{
375+
"type": "object",
376+
"defaultValue":
377+
{}
378+
},
379+
"dataEncryptionData":
380+
{
381+
"type": "object",
382+
"defaultValue":
383+
{}
384+
},
385+
"apiVersion":
386+
{
387+
"type": "string",
388+
"defaultValue": "2021-06-01"
389+
},
390+
"aadEnabled":
391+
{
392+
"type": "bool",
393+
"defaultValue": false
394+
},
395+
"aadData":
396+
{
397+
"type": "object",
398+
"defaultValue":
399+
{}
400+
},
401+
"authConfig":
402+
{
403+
"type": "object",
404+
"defaultValue":
405+
{}
406+
},
407+
"azSubscriptionId":
408+
{
409+
"type": "string",
410+
"metadata":
411+
{
412+
"description": "User subscription id"
413+
}
414+
},
415+
"resource_group":
416+
{
417+
"type": "string"
418+
},
419+
"cmkKeyvault":
420+
{
421+
"type": "string"
422+
},
423+
"cmkUri":
424+
{
425+
"type": "string"
426+
},
427+
"dataEncryptionType":
428+
{
429+
"type": "string"
430+
}
431+
},
432+
"variables":
433+
{
434+
"firewallRules": "[parameters('firewallRules').rules]",
435+
"identityData":
436+
{
437+
"type": "UserAssigned",
438+
"UserAssignedIdentities":
439+
{
440+
"[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentitity'))]":
441+
{}
442+
}
443+
},
444+
"Network":
445+
{
446+
"DelegatedSubnetResourceId": "[concat('/subscriptions/', parameters('azSubscriptionId'), '/resourceGroups/', parameters('resource_group'), '/providers/Microsoft.Network/virtualNetworks/', parameters('vnetData').virtualNetworkName, '/subnets/', parameters('vnetData').subnetName)]",
447+
"PrivateDnsZoneResourceId": "[concat('/subscriptions/', parameters('azSubscriptionId'), '/resourceGroups/', parameters('resource_group'), '/providers/Microsoft.Network/privateDnsZones/', parameters('vnetData').privateDnsZoneName)]",
448+
"PrivateDnsZoneArmResourceId": "[concat('/subscriptions/', parameters('azSubscriptionId'), '/resourceGroups/', parameters('resource_group'), '/providers/Microsoft.Network/privateDnsZones/', parameters('vnetData').privateDnsZoneName)]"
449+
},
450+
"dataEncryptionData":
451+
{
452+
"type": "[parameters('dataEncryptionType')]",
453+
"primaryUserAssignedIdentityId": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentitity'))]",
454+
"primaryKeyUri": "[parameters('cmkUri')]"
455+
}
456+
},
457+
"resources":
458+
[
459+
{
460+
"apiVersion": "[parameters('apiVersion')]",
461+
"location": "[parameters('target')]",
462+
"name": "[parameters('name')]",
463+
"identity": "[if(empty(variables('identityData')), json('null'), variables('identityData'))]",
464+
"properties":
465+
{
466+
"version": "[parameters('version')]",
467+
"administratorLogin": "[parameters('administratorLogin')]",
468+
"administratorLoginPassword": "[parameters('administratorLoginPassword')]",
469+
"Network": "[variables('Network')]",
470+
"availabilityZone": "[parameters('availabilityZone')]",
471+
"Storage":
472+
{
473+
"StorageSizeGB": "[parameters('storageSizeGB')]"
474+
},
475+
"Backup":
476+
{
477+
"backupRetentionDays": "[parameters('backupRetentionDays')]",
478+
"geoRedundantBackup": "[parameters('geoRedundantBackup')]"
479+
},
480+
"highAvailability":
481+
{
482+
"mode": "[parameters('haEnabled')]",
483+
"standbyAvailabilityZone": "[parameters('standbyAvailabilityZone')]"
484+
},
485+
"dataencryption": "[if(empty(variables('dataEncryptionData')), json('null'), variables('dataEncryptionData'))]",
486+
"authConfig": "[if(empty(parameters('authConfig')), json('null'), parameters('authConfig'))]"
487+
},
488+
"sku":
489+
{
490+
"name": "[parameters('vmName')]",
491+
"tier": "[parameters('serverEdition')]"
492+
},
493+
"tags": "[parameters('tags')]",
494+
"type": "Microsoft.DBforPostgreSQL/flexibleServers"
495+
},
496+
{
497+
"condition": "[parameters('aadEnabled')]",
498+
"type": "Microsoft.Resources/deployments",
499+
"apiVersion": "2018-05-01",
500+
"name": "addAdmins",
501+
"dependsOn":
502+
[
503+
"[concat('Microsoft.DBforPostgreSQL/flexibleServers/', parameters('name'))]"
504+
],
505+
"properties":
506+
{
507+
"mode": "Incremental",
508+
"template":
509+
{
510+
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
511+
"contentVersion": "1.0.0.0",
512+
"resources":
513+
[
514+
{
515+
"type": "Microsoft.DBforPostgreSQL/flexibleServers/administrators",
516+
"name": "[concat(parameters('name'),'/', parameters('aadData').adminSid)]",
517+
"apiVersion": "[parameters('apiVersion')]",
518+
"properties":
519+
{
520+
"tenantId": "[parameters('aadData').tenantId]",
521+
"principalName": "[parameters('aadData').principalName]",
522+
"principalType": "[parameters('aadData').principalType]"
523+
}
524+
}
525+
]
526+
}
527+
}
528+
},
529+
{
530+
"condition": "[greater(length(variables('firewallRules')), 0)]",
531+
"type": "Microsoft.Resources/deployments",
532+
"apiVersion": "2019-08-01",
533+
"name": "[concat('firewallRules-', copyIndex())]",
534+
"copy":
535+
{
536+
"count": "[if(greater(length(variables('firewallRules')), 0), length(variables('firewallRules')), 1)]",
537+
"mode": "Serial",
538+
"name": "firewallRulesIterator"
539+
},
540+
"dependsOn":
541+
[
542+
"[concat('Microsoft.DBforPostgreSQL/flexibleServers/', parameters('name'))]",
543+
"Microsoft.Resources/deployments/addAdmins"
544+
],
545+
"properties":
546+
{
547+
"mode": "Incremental",
548+
"template":
549+
{
550+
"$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
551+
"contentVersion": "1.0.0.0",
552+
"resources":
553+
[
554+
{
555+
"type": "Microsoft.DBforPostgreSQL/flexibleServers/firewallRules",
556+
"name": "[concat(parameters('name'),'/',variables('firewallRules')[copyIndex()].name)]",
557+
"apiVersion": "[parameters('apiVersion')]",
558+
"properties":
559+
{
560+
"StartIpAddress": "[variables('firewallRules')[copyIndex()].startIPAddress]",
561+
"EndIpAddress": "[variables('firewallRules')[copyIndex()].endIPAddress]"
562+
}
563+
}
564+
]
565+
}
566+
}
567+
},
568+
{
569+
"type": "Microsoft.DBforPostgreSQL/flexibleServers/configurations",
570+
"apiVersion": "2022-12-01",
571+
"name": "[concat(parameters('name'), '/shared_preload_libraries')]",
572+
"dependsOn":
573+
[
574+
"[resourceId('Microsoft.DBforPostgreSQL/flexibleServers', parameters('name'))]"
575+
],
576+
"properties":
577+
{
578+
"value": "pgaudit",
579+
"source": "user-override"
580+
}
581+
},
582+
{
583+
"type": "Microsoft.DBforPostgreSQL/flexibleServers/configurations",
584+
"apiVersion": "2022-12-01",
585+
"name": "[concat(parameters('name'), '/pgaudit.log')]",
586+
"dependsOn":
587+
[
588+
"[resourceId('Microsoft.DBforPostgreSQL/flexibleServers', parameters('name'))]"
589+
],
590+
"properties":
591+
{
592+
"value": "all",
593+
"source": "user-override"
594+
}
595+
}
596+
]
597+
}
598+
```
599+
600+
601+
254602
## Limitations
255603

256604
The following are current limitations for configuring the customer-managed key in Flexible Server:

0 commit comments

Comments
 (0)