Azure Key Vault Storage Account Keys

Before Azure Key Vault Storage Account Keys, developers had to manage their own Azure Storage Account (ASA) keys and rotate them manually or through an external automation. Now, Key Vault Storage Account Keys are implemented as Key Vault secrets for authenticating with an Azure Storage Account.

The Azure Storage Account (ASA) key feature manages secret rotation for you. It also removes the need for your direct contact with an ASA key by offering Shared Access Signatures (SAS) as a method.

For more general information on Azure Storage Accounts, see About Azure storage accounts.

Supporting interfaces

You'll find a complete listing and links to our programming and scripting interfaces in the Key Vault Developer's Guide.

What Key Vault manages

Key Vault performs several internal management functions on your behalf when you use Managed Storage Account Keys.

  • Azure Key Vault manages keys of an Azure Storage Account (ASA).
    • Internally, Azure Key Vault can list (sync) keys with an Azure Storage Account.
    • Azure Key Vault regenerates (rotates) the keys periodically.
    • Key values are never returned in response to caller.
    • Azure Key Vault manages keys of both Storage Accounts and Classic Storage Accounts.
  • Azure Key Vault allows you, the vault/object owner, to create SAS (account or service SAS) definitions.

Naming guidance

  • Storage account names must be between 3 and 24 characters in length and may contain numbers and lowercase letters only.
  • A SAS definition name must be 1-102 characters in length containing only 0-9, a-z, A-Z.

Developer experience

Before Azure Key Vault Storage Keys

Developers used to need to do the following practices with a storage account key to get access to Azure storage.

//create an Azure Storage Account using a connection string containing an account name and a storage key 

var storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
var blobClient = storageAccount.CreateCloudBlobClient();

After Azure Key Vault Storage Keys

//Make sure to set storage permissions appropriately on your key vault
Set-AzureRmKeyVaultAccessPolicy -VaultName 'yourVault' -ObjectId yourObjectId -PermissionsToStorage all

//Get secret URI 

Set-AzureKeyVaultManagedStorageSasDefinition -Service Blob -ResourceType Container,Service -VaultName yourKV  

-AccountName msak01 -Name blobsas1 -Protocol HttpsOnly -ValidityPeriod ([System.Timespan]::FromDays(1)) -Permission Read,List

//Get a SAS token from Key Vault

var secret = await kv.GetSecretAsync("SecretUri");

// Create new storage credentials using the SAS token. 

var accountSasCredential = new StorageCredentials(secret.Value); 

// Use the storage credentials and the Blob storage endpoint to create a new Blob service client. 

var accountWithSas = new CloudStorageAccount(accountSasCredential, new Uri ("https://myaccount.blob.core.windows.net/"), null, null, null); 

var blobClientWithSas = accountWithSas.CreateCloudBlobClient(); 

// If your SAS token is about to expire, Get sasToken again from Key Vault and update it.

accountSasCredential.UpdateSASToken(sasToken);

Developer guidance

  • Only allow Key Vault to manage your ASA keys. Do not attempt to manage them yourself, you will interfere with Key Vault's processes.
  • Do not allow ASA keys to be managed by more than one Key Vault object.
  • If you need to manually regenerate your ASA keys, we recommend that you regenerate them via Key Vault.

Getting started

Setup for role-based access control (RBAC) permissions

The Azure Key Vault application identity needs permissions to list and regenerate keys for a storage account. Set up these permissions using the following steps:

  • Get ObjectId of Azure Key Vault Identity:

    Get-AzureRmADServicePrincipal -ServicePrincipalName cfa8b339-82a2-471a-a3c9-0fc0be7a4093

  • Assign Storage Key Operator role to Azure Key Vault Identity:

    New-AzureRmRoleAssignment -ObjectId <objectId of AzureKeyVault from previous command> -RoleDefinitionName 'Storage Account Key Operator Service Role' -Scope '<azure resource id of storage account>'

    Note

    For a classic account type, set the role parameter to "Classic Storage Account Key Operator Service Role."

Working example

The following example demonstrates creating a Key Vault managed Azure Storage Account and the associated Shared Access Signature (SAS) definitions.

Assumptions

The following statements are givens for this working example.

  • Your storage resource is located at: /subscriptions/subscriptionId/resourceGroups/yourresgroup1/providers/Microsoft.Storage/storageAccounts/yourtest1

  • The name of your key vault is: yourtest1

Get a service principal

$yourKeyVaultServicePrincipalId = (Get-AzureRmADServicePrincipal -ServicePrincipalName cfa8b339-82a2-471a-a3c9-0fc0be7a4093).Id

The output of the preceding command will include your ServicePrincipal, which we'll call yourKeyVaultServicePrincipalId.

Set permissions

Make sure you have your storage permissions set to all. You can get yourKeyVaultServicePrincipalId and set permissions on the vault using the following commands.

Get-AzureRmADUser -SearchString "your name"

Now search for your name and get the related ObjectId, which you will use in setting permissions on the vault.

Set-AzureRmKeyVaultAccessPolicy -VaultName 'yourtest1' -ObjectId $yourKeyVaultServicePrincipalId -PermissionsToStorage all

Allow access

You need to give the Key Vault service access to the storage accounts, before you can create a managed storage account and SAS definitions.

New-AzureRmRoleAssignment -ObjectId $yourKeyVaultServicePrincipalId -RoleDefinitionName 'Storage Account Key Operator Service Role' -Scope '/subscriptions/subscriptionId/resourceGroups/yourresgroup1/providers/Microsoft.Storage/storageAccounts/yourtest1'

Create storage account

Now create a Managed Storage Account and two SAS definitions. The account SAS provides access to the blob service with different permissions.

Add-AzureKeyVaultManagedStorageAccount -VaultName yourtest1 -Name msak01 -AccountResourceId /subscriptions/subscriptionId/resourceGroups/yourresgroup1/providers/Microsoft.Storage/storageAccounts/yourtest1 -ActiveKeyName key2 -DisableAutoRegenerateKey

Regeneration

Setting the regeneration period using the following commands.

$regenPeriod = [System.Timespan]::FromDays(3)
Add-AzureKeyVaultManagedStorageAccount -VaultName yourtest1 -Name msak01 -AccountResourceId /subscriptions/subscriptionId/resourceGroups/yourresgroup1/providers/Microsoft.Storage/storageAccounts/yourtest1 -ActiveKeyName key2 -RegenerationPeriod $regenPeriod

Set SAS definitions

Set the SAS definitions in Key Vault for your managed storage account.

Set-AzureKeyVaultManagedStorageSasDefinition -Service Blob -ResourceType Container,Service -VaultName yourtest1  -AccountName msak01 -Name blobsas1 -Protocol HttpsOnly -ValidityPeriod ([System.Timespan]::FromDays(1)) -Permission Read,List
Set-AzureKeyVaultManagedStorageSasDefinition -Service Blob -ResourceType Container,Service,Object -VaultName yourtest1  -AccountName msak01 -Name blobsas2 -Protocol HttpsOnly -ValidityPeriod ([System.Timespan]::FromDays(1)) -Permission Read,List,Write

Get token

Get the corresponding SAS tokens and make calls to storage.

$sasToken1 = (Get-AzureKeyVaultSecret -VaultName yourtest1 -SecretName msak01-blobsas1).SecretValueText
$sasToken2 = (Get-AzureKeyVaultSecret -VaultName yourtest1 -SecretName msak01-blobsas2).SecretValueText

Create storage

Notice that trying to access with $sastoken1 fails, but that we are able to access with $sastoken2.

$context1 = New-AzureStorageContext -SasToken $sasToken1 -StorageAccountName yourtest1
$context2 = New-AzureStorageContext -SasToken $sasToken2 -StorageAccountName yourtest1
Set-AzureStorageBlobContent -Container containertest1 -File "abc.txt"  -Context $context1
Set-AzureStorageBlobContent -Container cont1-file "file.txt"  -Context $context2

Example summary

You are able access the storage blob content with the SAS token that has write access.

Relevant Powershell cmdlets

Storage account onboarding

Example: As a Key Vault object owner you add a storage account object to your Azure Key Vault to onboard a storage account.

During onboarding, Key Vault needs to verify that the identity of the onboarding account has permissions to list and to regenerate storage keys. In order to verify these permissions, Key Vault gets an OBO (On Behalf Of) token from the authentication service, audience set to Azure Resource Manager, and makes a list key call to the Azure Storage service. If the list call fails, the Key Vault object creation fails with an HTTP status code of Forbidden. The keys listed in this fashion are cached with your key vault entity storage.

Key Vault must verify that the identity has regenerate permissions before it can take ownership of regenerating your keys. To verify that the identity, via OBO token, as well as the Key Vault first party identity has these permissions:

  • Key Vault lists RBAC permissions on the storage account resource.
  • Key Vault validates the response via regular expression matching of actions and non-actions.

Find some supporting examples at Key Vault - Managed Storage Account Keys Samples.

If the identity does not have regenerate permissions or if Key Vault's first party identity doesn’t have list or regenerate permission, then the onboarding request fails returning an appropriate error code and message.

The OBO token will only work when you use first-party, native client applications of either PowerShell or CLI.

Other applications

  • SAS tokens, constructed using Key Vault storage account keys, provide even more controlled access to an Azure storage account. For more information, see Using shared access signatures.

See also