Rotate your keys for enhanced security

Automate the rotation of keys in Azure

Afzal Muhammad

--

Automate the rotation of Azure storage account access key via Azure function and update the Azure key vault secret.

Overview

It is always recommended to authenticate Azure resources by using managed identity. However, there are certain circumstances where this is not an option. In those scenarios, access keys, secrets, or passwords are used for authentication. Automatically rotating keys, password, or secrets after given period of time is elapsed is a best practice and also an industry standard.

In this article, I would be talking about how you can implement periodic rotation of access keys or secrets. Here, I have used the use case of rotating access keys of Azure storage account. However, similar implementation can also be used in rotating keys or passwords of any other scenario such as SQL server login credentials.

Architecture

Below diagram shows the high-level architecture of this solution.

Architecture

Architectural workflow is as below:

  1. Thirty days before the expiration date of a secret, Key Vault publishes the near expiry event to Event Grid.
  2. Event Grid checks the event subscriptions and uses HTTP POST to call the function app endpoint that’s subscribed to the event.
  3. The function app identifies the alternate key (not the latest one) and calls the storage account to regenerate it.
  4. The function app adds the new regenerated key to Azure Key Vault as the new version of the secret.

Prerequisites

  • Key Vault
  • Storage Account
  • Function app
  • Event grid

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.

Create a Storage Account

Create an storage account in Azure portal or by running the following powershell command.

$rgName = "<resource-group>"
$accountName = "<storage-account>"

$account = New-AzStorageAccount -ResourceGroupName $rgName `
-Name $accountName `
-SkuName Standard_RAGRS `
-Location <location> `
-Kind StorageV2 `
-DnsEndpointType AzureDnsZone

Create a Key Vault

Provision key vault, if it is not provisioned in your environment already. You can create using Azure portal or running the following Powershell command as shown below.

New-AzResourceGroup -Name "myResourceGroup" -Location "EastUS"

New-AzKeyVault -Name "<your-unique-keyvault-name>" -ResourceGroupName "myResourceGroup" -Location "EastUS"

Create a secret

Once the key vault is created. Create a secret. Click on Secrets in the key vault left panel under Objects as shown below.

Provide secret name and value. Then click “Create”

Create Azure Function

In this solution, we will be creating azure function trigger that would respond to an event sent by an Event Grid source.

Create a function app with runtime stack to be PowerShell. In this article, I would be using PowerShell, however, other programming languages can also be used such as C#, Python, and etc.

Enable function app managed identity

Make sure System assigned managed identity for function app is enabled. This is important because storage account and key vault will authorize function app via the managed identity.

Configure application settings for function app

The function app settings values are used inside the code as environment variables. It is recommended to use environment variables and avoid hard coding values such as storage account name, key vault name, and so on.

Create the following application settings:

  • Azure Subscription
  • Key Vault name
  • Secret name
  • Storage account resource group name
  • Storage account name

Click Function App → Settings →Configuration. In the Application settings tab click “New application setting”. Provide Name and value, then click “OK”

Click “Save” when done.

Specify the following as below. if you change the names of the environment variables, make sure you modify those in the PowerShell code in azure function.

storageaccountresourcegroup
storageAccountName
secretName
keyVaultName

Modify app files

Click Function App → App files. Then select host.json from the drop down and make sure the content of host.json matches with the below figure.

Now select requirements.psd1 from the drop down and enable the Az module with version as shown below.

To make PowerShell Az module available in an Azure Function, managedDependency property has to be enabled in host.json file, and Az='5.*' module version included in requirements.psd1 file.

Making changes in app files and configuration requires function app to be restarted for changes to take effect.

Create a function

Click Function App → Functions. Then click Functions.

Click Create to create a new function.

Select a template for “Azure Event Grid trigger”. Provide new function name as shown below.

Click “Code + Test” and copy and paste the below code in run.ps1 as shown in Figure.

param($eventGridEvent, $TriggerMetadata)

# Make sure to pass hashtables to Out-String so they're logged correctly
$eventGridEvent | ConvertTo-Json | Write-Host

# resource group of storage account
$resourceGroup = $env:storageaccountresourcegroup

# storage account name
$storageAccountName = $env:storageaccountname

# key vault secret name
$secretName = $env:secretName

# key vault Name
$keyVaultName = $env:keyVaultName

Write-Host "Key Vault Name: $keyVAultName"
Write-Host "Secret Name: $secretName"

try
{
Write-Host "Rotation started..."
# set context to specific subscription. If you have one subscription, you can ignore this line.
Set-AzContext -Subscription $env:azuresubscription

# Get the key1 from storage account
$storageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroup -Name $storageAccountName).Value[0]

# Generate New Key
New-AzStorageAccountKey -ResourceGroupName $resourceGroup -Name $storageAccountName -KeyName key1
Write-Host "New storage account access key has been generated successfully!!!"

# Get the new key
$storageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroup -Name $storageAccountName).Value[0]

$secretvalue = ConvertTo-SecureString $storageAccountKey -AsPlainText -Force

# Get the new expiration of key
$ts = New-TimeSpan -Days 0 -Hours 0 -Minutes 2
$expires = (get-date) + $ts

# set the new secret value
$secret = Set-AzKeyVaultSecret -VaultName $keyVAultName -Name $secretName -SecretValue $secretvalue -Expires $expires
Write-Host "Secret is updated successfully in the key vault!!!. Secret Name: $secretName"
Write-Host "Secret Rotated Successfully..."

}
catch
{
$message = $_
Write-Error -Message "Error Occurred!!! $message" -ErrorAction Stop
}
PowerShell code for rotating storage key and updating KV secret

Configure Access

In the following steps, we will be configuring function app access to storage account and the key vault using its managed identity for authentication.

Allow function app to access storage account

Visit storage account, then click “Access Control (IAM)”. Then click “+ Add” for adding the role assignment as shown below.

Select “Storage Account Key Operator Service Role”. This will give access for listing and regenerating keys in storage account. Click Next

Select Managed Identity and then click “+ Select members”

Select the managed identity of Function App

Select managed identity of function App

Click “Review + Assign” and then assign the role. The role will be created and shows up in Role assignments tab as shown below.

Function App managed identity is added in storage account

Allow function App to access key vault

Click key vault → Access Polices. Then click “+ Create”

key vault →Access policies → Create

Follow the principle of least privilege and select “Set” in Secret permissions. This will allow function app to set the secret keys only. Click Next.

In the Principal tab look for function app, then select the function app created earlier to grant access to set keys in azure key vault secrets.

Click Next, then “Review + Create”, and them create the access policy.

Setup Event Grid

Search for event grid resource, then click on “Manage System Topics” This will subscribe to events published by Azure services. System topics are built-in topics provided by Azure services such as Azure Storage, Azure Event Hubs, and Azure Service Bus.

Event Grid topic provides an endpoint where the source sends events. A topic is used for a collection of related events. To respond to certain types of events, subscribers decide which topics to subscribe to.

Setup topic

Provide the following:

Topic Types: Microsoft Key Vault
Subscription: Select the subscription where key vault is created
Resource Group: Select the resource group where key vault is provisioned.
Resource: Select the key vault
Name: Provide the name for your event grid topic
Location: Select the location. it is recommended to use the same location where key vault and function app are created.

Create event grid system topic

Setup event subscription

A subscription tells Event Grid which events on a topic you’re interested in receiving. When creating the subscription, you provide an endpoint for handling the event. You can also filter the events that are sent to the endpoint.

Under Event Grid | System topics, click “Event Subscription”. Then click “+ Event Subscription” to create a subscription.

Create event subscription

Provide the name for the event subscription. Also verify that topic details contain topic type to be the “key vault” and source resource is your key vault resource.

Under “EVENT TYPES” select “Secret Near Expiry”.

Triggered when the current version of a secret is about to expire. (The event is triggered 30 days before the expiration date.)

Specify the key vault secret name under the subject filters as shown below.

Under ENDPOINT DETAILS. select “Azure Function” for Endpoint Type as shown below. Click “Select endpoint”

Select the following for endpoint.

Subscription: The subscription where function App is created
Resource Group: Resource group where function App is created.
Function App: select the function App
Function: Select the function created earlier in this article for capturing event from event grid

Then Click “Confirm Selection”.

Click “Create” to create the event subscription.

Conclusion

Regular key rotation ensures that solution is secure and resilient. It is important for enterprises to implement key rotation procedure before security threat incident occurs. As you scale in your environment, automatic key rotation is a MUST!!!

This solution enables Azure customers to implement end-to-end zero-touch automatic key rotation for Azure services with low code.

--

--

Afzal Muhammad

Innovative and transformative cross domain cloud solution architect @Microsoft (& xCisco). Helping companies to digitally transform!!!