Skip to content

Commit cce80d8

Browse files
committed
update
1 parent 4c57b0f commit cce80d8

File tree

1 file changed

+301
-0
lines changed

1 file changed

+301
-0
lines changed

articles/key-vault/secrets/tutorial-rotation-dual.md

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,307 @@ ms.custom: devx-track-azurepowershell, devx-track-azurecli
1515

1616
The best way to authenticate to Azure services is by using a [managed identity](../general/authentication.md), but there are some scenarios where that isn't an option. In those cases, access keys or passwords are used. You should rotate access keys and passwords frequently.
1717

18+
This tutorial shows how to automate the periodic rotation of secrets for databases and services that use two sets of authentication credentials. Specifically, this tutorial shows how to rotate Azure Storage account keys stored in Azure Key Vault as secrets. You'll use a function triggered by Azure Event Grid notification.
19+
20+
> [!NOTE]
21+
> For Storage account services, using Microsoft Entra ID to authorize requests is recommended. For more information, see [Authorize access to blobs using Microsoft Entra ID](../../storage/blobs/authorize-access-azure-active-directory.md). There are services that require storage account connection strings with access keys. For that scenario, we recommend this solution.
22+
23+
Here's the rotation solution described in this tutorial:
24+
25+
![Diagram that shows the rotation solution.](../media/secrets/rotation-dual/rotation-diagram.png)
26+
27+
In this solution, Azure Key Vault stores storage account individual access keys as versions of the same secret, alternating between the primary and secondary key in subsequent versions. When one access key is stored in the latest version of the secret, the alternate key is regenerated and added to Key Vault as the new latest version of the secret. The solution provides the application's entire rotation cycle to refresh to the newest regenerated key.
28+
29+
1. Thirty days before the expiration date of a secret, Key Vault publishes the near expiry event to Event Grid.
30+
1. Event Grid checks the event subscriptions and uses HTTP POST to call the function app endpoint that's subscribed to the event.
31+
1. The function app identifies the alternate key (not the latest one) and calls the storage account to regenerate it.
32+
1. The function app adds the new regenerated key to Azure Key Vault as the new version of the secret.
33+
34+
## Prerequisites
35+
* An Azure subscription. [Create one for free.](https://azure.microsoft.com/free/?WT.mc_id=A261C142F)
36+
* Azure [Cloud Shell](https://shell.azure.com/). This tutorial is using portal Cloud Shell with PowerShell env
37+
* Azure Key Vault.
38+
* Two Azure storage accounts.
39+
40+
> [!NOTE]
41+
> Rotation of shared storage account key revokes account level shared access signature (SAS) generated based on that key. After storage account key rotation, you must regenerate account-level SAS tokens to avoid disruptions to applications.
42+
43+
You can use this deployment link if you don't have an existing key vault and existing storage accounts:
44+
45+
[![Link that's labelled Deploy to Azure.](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/deploytoazure.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure-Samples%2FKeyVault-Rotation-StorageAccountKey-PowerShell%2Fmaster%2FARM-Templates%2FInitial-Setup%2Fazuredeploy.json)
46+
47+
1. Under **Resource group**, select **Create new**. Name the group **vault rotation** and then select **OK**.
48+
1. Select **Review + create**.
49+
1. Select **Create**.
50+
51+
![Screenshot that shows how to create a resource group.](../media/secrets/rotation-dual/dual-rotation-1.png)
52+
53+
You'll now have a key vault and two storage accounts. You can verify this setup in the Azure CLI or Azure PowerShell by running this command:
54+
# [Azure CLI](#tab/azure-cli)
55+
```azurecli
56+
az resource list -o table -g vaultrotation
57+
```
58+
# [Azure PowerShell](#tab/azurepowershell)
59+
60+
```azurepowershell
61+
Get-AzResource -Name 'vaultrotation*' | Format-Table
62+
```
63+
---
64+
65+
The result will look something like this output:
66+
67+
```console
68+
Name ResourceGroup Location Type Status
69+
----------------------- -------------------- ---------- --------------------------------- --------
70+
vaultrotation-kv vaultrotation westus Microsoft.KeyVault/vaults
71+
vaultrotationstorage vaultrotation westus Microsoft.Storage/storageAccounts
72+
vaultrotationstorage2 vaultrotation westus Microsoft.Storage/storageAccounts
73+
```
74+
75+
## Create and deploy the key rotation function
76+
77+
Next, you'll create a function app with a system-managed identity, in addition to other required components. You'll also deploy the rotation function for the storage account keys.
78+
79+
The function app rotation function requires the following components and configuration:
80+
- An Azure App Service plan
81+
- A storage account to manage function app triggers
82+
- An access policy to access secrets in Key Vault
83+
- The Storage Account Key Operator Service role assigned to the function app so it can access storage account access keys
84+
- A key rotation function with an event trigger and an HTTP trigger (on-demand rotation)
85+
- An Event Grid event subscription for the **SecretNearExpiry** event
86+
87+
1. Select the Azure template deployment link:
88+
89+
[![Azure template deployment link.](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/deploytoazure.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure-Samples%2FKeyVault-Rotation-StorageAccountKey-PowerShell%2Fmaster%2FARM-Templates%2FFunction%2Fazuredeploy.json)
90+
91+
1. In the **Resource group** list, select **vaultrotation**.
92+
1. In the **Storage Account RG** box, enter the name of the resource group in which your storage account is located. Keep the default value **[resourceGroup().name]** if your storage account is already located in the same resource group where you'll deploy the key rotation function.
93+
1. In the **Storage Account Name** box, enter the name of the storage account that contains the access keys to rotate. Keep the default value **[concat(resourceGroup().name, 'storage')]** if you use storage account created in [Prerequisites](#prerequisites).
94+
1. In the **Key Vault RG** box, enter the name of resource group in which your key vault is located. Keep the default value **[resourceGroup().name]** if your key vault already exists in the same resource group where you'll deploy the key rotation function.
95+
1. In the **Key Vault Name** box, enter the name of the key vault. Keep the default value **[concat(resourceGroup().name, '-kv')]** if you use key vault created in [Prerequisites](#prerequisites).
96+
1. In the **App Service Plan Type** box, select hosting plan. **Premium Plan** is needed only when your key vault is behind firewall.
97+
1. In the **Function App Name** box, enter the name of the function app.
98+
1. In the **Secret Name** box, enter the name of the secret where you'll store access keys.
99+
1. In the **Repo URL** box, enter the GitHub location of the function code. In this tutorial, you can use **https://github.com/Azure-Samples/KeyVault-Rotation-StorageAccountKey-PowerShell.git** .
100+
1. Select **Review + create**.
101+
1. Select **Create**.
102+
103+
![Screenshot that shows how to create and deploy function.](../media/secrets/rotation-dual/dual-rotation-2.png)
104+
105+
After you complete the preceding steps, you'll have a storage account, a server farm, a function app, and Application Insights. When the deployment is complete, you'll see this page:
106+
107+
![Screenshot that shows the Your deployment is complete page.](../media/secrets/rotation-dual/dual-rotation-3.png)
108+
> [!NOTE]
109+
> If you encounter a failure, you can select **Redeploy** to finish the deployment of the components.
110+
111+
You can find deployment templates and code for the rotation function in [Azure Samples](https://github.com/Azure-Samples/KeyVault-Rotation-StorageAccountKey-PowerShell).
112+
113+
### Add the storage account access keys to Key Vault secrets
114+
115+
First, set your access policy to grant **manage secrets** permissions to your user principal:
116+
# [Azure CLI](#tab/azure-cli)
117+
```azurecli
118+
az keyvault set-policy --upn <email-address-of-user> --name vaultrotation-kv --secret-permissions set delete get list
119+
```
120+
# [Azure PowerShell](#tab/azurepowershell)
121+
122+
```azurepowershell
123+
Set-AzKeyVaultAccessPolicy -UserPrincipalName <email-address-of-user> --name vaultrotation-kv -PermissionsToSecrets set,delete,get,list
124+
```
125+
---
126+
127+
You can now create a new secret with a storage account access key as its value. You'll also need the storage account resource ID, secret validity period, and key ID to add to the secret so the rotation function can regenerate the key in the storage account.
128+
129+
Determine the storage account resource ID. You can find this value in the `id` property.
130+
131+
# [Azure CLI](#tab/azure-cli)
132+
```azurecli
133+
az storage account show -n vaultrotationstorage
134+
```
135+
# [Azure PowerShell](#tab/azurepowershell)
136+
137+
```azurepowershell
138+
Get-AzStorageAccount -Name vaultrotationstorage -ResourceGroupName vaultrotation | Select-Object -Property *
139+
```
140+
---
141+
142+
List the storage account access keys so you can get the key values:
143+
# [Azure CLI](#tab/azure-cli)
144+
```azurecli
145+
az storage account keys list -n vaultrotationstorage
146+
```
147+
# [Azure PowerShell](#tab/azurepowershell)
148+
149+
```azurepowershell
150+
Get-AzStorageAccountKey -Name vaultrotationstorage -ResourceGroupName vaultrotation
151+
```
152+
---
153+
154+
Add secret to key vault with validity period for 60 days, storage account resource ID, and for demonstration purpose to trigger rotation immediately set expiration date to tomorrow. Run this command, using your retrieved values for `key1Value` and `storageAccountResourceId`:
155+
156+
# [Azure CLI](#tab/azure-cli)
157+
```azurecli
158+
$tomorrowDate = (get-date).AddDays(+1).ToString("yyyy-MM-ddTHH:mm:ssZ")
159+
az keyvault secret set --name storageKey --vault-name vaultrotation-kv --value <key1Value> --tags "CredentialId=key1" "ProviderAddress=<storageAccountResourceId>" "ValidityPeriodDays=60" --expires $tomorrowDate
160+
```
161+
# [Azure PowerShell](#tab/azurepowershell)
162+
163+
```azurepowershell
164+
$tomorrowDate = (Get-Date).AddDays(+1).ToString('yyy-MM-ddTHH:mm:ssZ')
165+
$secretValue = ConvertTo-SecureString -String '<key1Value>' -AsPlainText -Force
166+
$tags = @{
167+
CredentialId='key1'
168+
ProviderAddress='<storageAccountResourceId>'
169+
ValidityPeriodDays='60'
170+
}
171+
Set-AzKeyVaultSecret -Name storageKey -VaultName vaultrotation-kv -SecretValue $secretValue -Tag $tags -Expires $tomorrowDate
172+
```
173+
---
174+
175+
This secret will trigger `SecretNearExpiry` event within several minutes. This event will in turn trigger the function to rotate the secret with expiration set to 60 days. In that configuration, 'SecretNearExpiry' event would be triggered every 30 days (30 days before expiry) and rotation function will alternate rotation between key1 and key2.
176+
177+
You can verify that access keys have regenerated by retrieving the storage account key and the Key Vault secret and compare them.
178+
179+
Use this command to get the secret information:
180+
# [Azure CLI](#tab/azure-cli)
181+
```azurecli
182+
az keyvault secret show --vault-name vaultrotation-kv --name storageKey
183+
```
184+
# [Azure PowerShell](#tab/azurepowershell)
185+
186+
```azurepowershell
187+
Get-AzKeyVaultSecret -VaultName vaultrotation-kv -Name storageKey -AsPlainText
188+
```
189+
---
190+
191+
Notice that `CredentialId` is updated to the alternate `keyName` and that `value` is regenerated:
192+
193+
![Screenshot that shows the output of the A Z keyvault secret show command for the first storage account.](../media/secrets/rotation-dual/dual-rotation-4.png)
194+
195+
Retrieve the access keys to compare the values:
196+
# [Azure CLI](#tab/azure-cli)
197+
```azurecli
198+
az storage account keys list -n vaultrotationstorage
199+
```
200+
# [Azure PowerShell](#tab/azurepowershell)
201+
202+
```azurepowershell
203+
Get-AzStorageAccountKey -Name vaultrotationstorage -ResourceGroupName vaultrotation
204+
```
205+
---
206+
207+
Notice that `value` of the key is same as secret in key vault:
208+
209+
![Screenshot that shows the output of the A Z storage account keys list command for the first storage account.](../media/secrets/rotation-dual/dual-rotation-5.png)
210+
211+
## Use existing rotation function for multiple storage accounts
212+
213+
You can reuse the same function app to rotate keys for multiple storage accounts.
214+
215+
To add storage account keys to an existing function for rotation, you need:
216+
- The Storage Account Key Operator Service role assigned to function app so it can access storage account access keys.
217+
- An Event Grid event subscription for the **SecretNearExpiry** event.
218+
219+
1. Select the Azure template deployment link:
220+
221+
[![Azure template deployment link.](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/deploytoazure.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure-Samples%2FKeyVault-Rotation-StorageAccountKey-PowerShell%2Fmaster%2FARM-Templates%2FAdd-Event-Subscriptions%2Fazuredeploy.json)
222+
223+
1. In the **Resource group** list, select **vaultrotation**.
224+
1. In the **Storage Account RG** box, enter the name of the resource group in which your storage account is located. Keep the default value **[resourceGroup().name]** if your storage account is already located in the same resource group where you'll deploy the key rotation function.
225+
1. In the **Storage Account Name** box, enter the name of the storage account that contains the access keys to rotate.
226+
1. In the **Key Vault RG** box, enter the name of resource group in which your key vault is located. Keep the default value **[resourceGroup().name]** if your key vault already exists in the same resource group where you'll deploy the key rotation function.
227+
1. In the **Key Vault Name** box, enter the name of the key vault.
228+
1. In the **Function App Name** box, enter the name of the function app.
229+
1. In the **Secret Name** box, enter the name of the secret where you'll store access keys.
230+
1. Select **Review + create**.
231+
1. Select **Create**.
232+
233+
![Screenshot that shows how to create an additional storage account.](../media/secrets/rotation-dual/dual-rotation-7.png)
234+
235+
### Add storage account access key to Key Vault secrets
236+
237+
Determine the storage account resource ID. You can find this value in the `id` property.
238+
# [Azure CLI](#tab/azure-cli)
239+
```azurecli
240+
az storage account show -n vaultrotationstorage2
241+
```
242+
# [Azure PowerShell](#tab/azurepowershell)
243+
244+
```azurepowershell
245+
Get-AzStorageAccount -Name vaultrotationstorage -ResourceGroupName vaultrotation | Select-Object -Property *
246+
```
247+
---
248+
249+
List the storage account access keys so you can get the key2 value:
250+
# [Azure CLI](#tab/azure-cli)
251+
```azurecli
252+
az storage account keys list -n vaultrotationstorage2
253+
```
254+
# [Azure PowerShell](#tab/azurepowershell)
255+
256+
```azurepowershell
257+
Get-AzStorageAccountKey -Name vaultrotationstorage2 -ResourceGroupName vaultrotation
258+
```
259+
---
260+
261+
Add secret to key vault with validity period for 60 days, storage account resource ID, and for demonstration purpose to trigger rotation immediately set expiration date to tomorrow. Run this command, using your retrieved values for `key2Value` and `storageAccountResourceId`:
262+
263+
# [Azure CLI](#tab/azure-cli)
264+
```azurecli
265+
$tomorrowDate = (Get-Date).AddDays(+1).ToString('yyyy-MM-ddTHH:mm:ssZ')
266+
az keyvault secret set --name storageKey2 --vault-name vaultrotation-kv --value <key2Value> --tags "CredentialId=key2" "ProviderAddress=<storageAccountResourceId>" "ValidityPeriodDays=60" --expires $tomorrowDate
267+
```
268+
# [Azure PowerShell](#tab/azurepowershell)
269+
270+
```azurepowershell
271+
$tomorrowDate = (get-date).AddDays(+1).ToString("yyyy-MM-ddTHH:mm:ssZ")
272+
$secretValue = ConvertTo-SecureString -String '<key1Value>' -AsPlainText -Force
273+
$tags = @{
274+
CredentialId='key2';
275+
ProviderAddress='<storageAccountResourceId>';
276+
ValidityPeriodDays='60'
277+
}
278+
Set-AzKeyVaultSecret -Name storageKey2 -VaultName vaultrotation-kv -SecretValue $secretValue -Tag $tags -Expires $tomorrowDate
279+
```
280+
---
281+
282+
Use this command to get the secret information:
283+
# [Azure CLI](#tab/azure-cli)
284+
```azurecli
285+
az keyvault secret show --vault-name vaultrotation-kv --name storageKey2
286+
```
287+
# [Azure PowerShell](#tab/azurepowershell)
288+
289+
```azurepowershell
290+
Get-AzKeyVaultSecret -VaultName vaultrotation-kv -Name storageKey2 -AsPlainText
291+
```
292+
---
293+
294+
Notice that `CredentialId` is updated to the alternate `keyName` and that `value` is regenerated:
295+
296+
![Screenshot that shows the output of the A Z keyvault secret show command for the second storage account.](../media/secrets/rotation-dual/dual-rotation-8.png)
297+
298+
Retrieve the access keys to compare the values:
299+
# [Azure CLI](#tab/azure-cli)
300+
```azurecli
301+
az storage account keys list -n vaultrotationstorage
302+
```
303+
# [Azure PowerShell](#tab/azurepowershell)
304+
305+
```azurepowershell
306+
Get-AzStorageAccountKey -Name vaultrotationstorage -ResourceGroupName vaultrotation
307+
```
308+
---
309+
310+
Notice that `value` of the key is same as secret in key vault:
311+
312+
![Screenshot that shows the output of the A Z storage account keys list command for the second storage account.](../media/secrets/rotation-dual/dual-rotation-9.png)
313+
314+
## Disable rotation for secret
315+
316+
You can disable rotation of a secret simply by deleting the Event Grid subscription for that secret. Use the Azure PowerShell [Remove-AzEventGridSubscription](/powershell/module/az.eventgrid/remove-azeventgridsubscription) cmdlet or Azure CLI [az event grid event--subscription delete](/cli/azure/eventgrid/event-subscription?#az-eventgrid-event-subscription-delete) command.
317+
318+
18319
## Key Vault rotation functions for two sets of credentials
19320

20321
Rotation functions template for two sets of credentials and several ready to use functions:

0 commit comments

Comments
 (0)