Azure Storage Account Keys Automatic Rotation

Azure Infrastructure


A new feature called Managed Storage Account Keys popped up last month that promises to make rotating Azure Storage Account Keys easier. I have to give a ton of credit to my colleague Dmitriy S. who helped with a lot of the discovery and troubleshooting.

Why rotate?

It is recommended to periodically rotate your Storage Account Keys. Storage Account Keys give the holder full access to your storage account and all data within it. Rotating the keys periodically help mitigate the risk of unauthorized access.

The old way

Previously, we had this article called “Set up Azure Key Vault with end-to-end key rotation and auditing,” which describes automation storage account key rotation. While that will still work, it’s very complex to setup, involves using an Automation Account and Runbook, Functions, and a Logic App. We now have a much easier way!

The new way

Using Managed Storage Account Keys, we can easily set up automatic key rotation by just deploying a Storage Account and a Key Vault. The article called Azure Key Vault Storage Account Keys describes the feature and developer experience. However, the “Getting started” section was a bit confusing, incomplete and it looks like it contains some errors. So, let’s go through it together.

Set-up permissions

I’m going to assume you have a Key Vault and Storage Account already and they have registered providers. The first thing we need is the ObjectId of Key Vault. Note, we need the ObjectId of the Key Vault service (“first party identity”), NOT your specific Key Vault. This object ID is different for each tenant. The instructions on the official documentation say:

Get-AzureRmADServicePrincipal -SearchString "AzureKeyVault"

However, that didn’t work for one of my tenants (which was a Enterprise Enrollment). A more accurate way to get the ObjectId is to first login using “Connect-AzureAD” and then using the following command:

$servicePrincipal = Get-AzureADServicePrincipal -Filter "AppId eq 'cfa8b339-82a2-471a-a3c9-0fc0be7a4093'"

This won’t work on MSDN Azure subscriptions, but neither did the first way. I’ve found that the AppId above is consistent across all of my tenants but could be different for AzureChina, AzureGov, etc. Next, we need to assign the “Storage Account Key Operator Service Role” role which gives the Key Vault list and regenerate permissions:

$storageAccountId = (Get-AzureRmStorageAccount -StorageAccountName wspladiag02 -ResourceGroupName wspla-rg).Id
New-AzureRmRoleAssignment -ObjectId $servicePrincipal.ObjectId -RoleDefinitionName 'Storage Account Key Operator Service Role' -Scope $storageAccountId

Storage account onboarding

The official documentation is unclear on the next steps, in my opinion. But, here’s how we set up daily key rotation using PowerShell. First, we need to make sure we (user performing operation) has “set” operation allowed within the Key Vault’s access policies. If you don’t, you’ll get this error later on:

Add-AzureKeyVaultManagedStorageAccount : Operation "set" is not allowed by vault policy

So to prevent that, let’s add the current user:

$keyVaultName = "kv-infra-secrets"
$keyVaultResourceGroupName = "RG-Infrastructure"
Set-AzureRmKeyVaultAccessPolicy -VaultName $keyVaultName -ResourceGroupName $keyVaultResourceGroupName -UserPrincipalName "" -PermissionsToStorage set, get, regeneratekey

I gave the user get and regeneratekey also but those aren’t required unless you want to use other commands. Now let’s create a TimeSpan object:

$regenerationPeriod = [System.Timespan]::FromDays(1)

Next, we use a new command to add the Storage Account as “Managed” by this Key Vault. If you don’t have this command, remember to update to the latest Azure PowerShell.

$parameters = @{
VaultName = $keyVaultName
AccountResourceId = $storageAccountId
AccountName = "mystoragetest1"
ActiveKeyName = "key1"
RegenerationPeriod = $regenerationPeriod
Add-AzureKeyVaultManagedStorageAccount @parameters

That’s it! The Storage Account Key will be rotated on the schedule you set up. You can verify everything by using Get-AzureKeyVaultManagedStorageAccount. You can also regenerate the keys manually using Update-AzureKeyVaultManagedStorageAccountKey if you don’t want to wait.


Encrypt folders on Dropbox / OneDrive / GDrive with EncFS


One of the issues posed by storing sensitive information in the cloud is that the cloud provider, and by extension, other 3rd parties (hackers, governments) have access to that data. To work around this, we need to encrypt the data before it’s sent to the cloud provider. Tools like TrueCrypt / VeraCrypt are great for encrypting entire volumes but aren’t meant for this use case. If you stored a TrueCrypt volume in the cloud, a minor change on a small file would cause a full sync to occur. We need a better solution. Enter EncFS.

EncFS is available for Linux here: There was a Windows version called Encfs4win ( ) but hasn’t been updated. A new revival of that project exists that we’ll cover in this blog and use to encrypt files.

I’m using Windows 10 and Dropbox but this will work on Windows 7 and any other file share/sync provider such as OneDrive and Google Drive.


Our objective is to have a place to store files in a cloud service which has zero knowledge of the content we’re storing. Before we start, there are some alternatives:

Spideroak starts at $5 and has Enterprise products.

boxcryptor is (or was) based on encfs and has a free version.

There are also several blockchain-based file storage providers. I use Storj personally and might blog about these in another post.

While those alternatives are appealing, especially boxcryptor, the free version is limited and for what I’m using, the paid versions aren’t that valuable. So, how can we do this for free?


Let’s go back to the Windows port created by Charles Munson, a.k.a jetwhiz.


  1. Download the files, encfs-installer.exe and the hashes.asc from github:
  2. (optional) Verify hash (you can download QuickHash if you need a verification tool). Note, since this is a privacy focused blog post it would make sense to verify the hash to ensure the file that was downloaded hasn’t been modified in-transit or by some other program on your computer (malware/virus/etc.)

  1. Run the installer, keep all the defaults and it should be done within 2 minutes. Once completed, the binaries will be located in C:\Program Files (x86)\encfs.

Using it

First, we need to create an encrypted folder.

  1. Run C:\Program Files (x86)\encfs\encfsw.exe, this is the graphical interface. Nothing will pop-up, but you’ll see they “key” icon in your taskbar.

  1. We’re going to use the Open/Create option.
  2. Select a folder. In this example, I created a folder in my Dropbox called “encfs.” Specify the other options and press OK:

  3. After pressing OK, you should see another login prompt because encfsw is automatically mounting the new folder. Explorer should open the drive letter.
  4. Drag some files in there!

  5. Let’s see what the cloud provider (Dropbox in my case) sees:

  6. That’s it. Now we can install encfs (on Linux or Windows) to access these files anytime.

Best practices

Some of the best practices for using encfs are:

  1. Don’t put anything else in your encrypted folder. There should be the .xml file plus 1 encrypted file for each file you uploaded.
  2. When mounting the encrypted folder in Windows, use a drive letter versus a folder. The GUI enforces this but the command-line may not.

If you need mobile access, boxcrypter might be worth a look. I didn’t need that and the free version limited me to two devices which didn’t suffice. I’m also just storing sensitive information (like my ninjacat picture) in the encrypted folder. I can use the native Dropbox app to access my other folders that have non-sensitive information.


Azure Automation: Secure your webhook

Azure Infrastructure, Windows PowerShell

In my previous post titled Azure Automation: Sync Runbooks from Visual Studio Team Services, I used a webhook. The webhook is just a URL that will be triggered using an HTTP POST. In Azure Automation, they look like this:

Anyone who got the URL, could simply do an HTTP POST and your webhook would be invoked. For example:

Invoke-WebRequest -Uri -Method POST

All is not lost, we can add *some* security to this using WebhookData.

[continue reading…]


Azure Automation: Sync Runbooks from Visual Studio Team Services

Azure Infrastructure, Windows PowerShell


This is sort of an update or branch off of a blog post by Gary Keong titled: Azure Automation: Integrating Runbook Source Control using Visual Studio Online (July 2014) and includes some of my learnings.

Use Case

We are going to sync some runbooks for the purposes of subscription management. This could include things like setting up alerts, applying permissions, and applying policies to the subscription. I’m going to assume you have a Visual Studio Team Services Account (create one if not).

In this example, I will use two Azure Automation Accounts.

  • The first one will hold the “Sync Runbook.” It simply syncs my Visual Studio Team Services (VSTS) Git repository to my second Automation Account. We’ll call this the Sync Automation Account.
  • The second one will hold the runbooks that manage the subscription. We’ll call this the Manager Automation Account.

[continue reading…]

1 comment

Infamous “Object reference not set to an instance of an object” for Azure Disk Encryption

Azure Infrastructure

I’m working on encrypting RedHat 7.2 VM using Managed Disks. Keep in mind, to work with Managed Disks in PowerShell, you should upgrade to the latest AzureRM module (version 3.7.0 as of this writing). The command to start the encryption process is the same for Windows as it is for Linux:

Set-AzureRmVMDiskEncryptionExtension -ResourceGroupName $resourceGroupName -VMName $vmNameForEncryption `
-AadClientID $aadClientID -AadClientSecret $aadClientSecret -DiskEncryptionKeyVaultUrl $diskEncryptionKeyVaultUrl `
-DiskEncryptionKeyVaultId $keyVaultResourceId -VolumeType OS

However, when executing this command for a Linux VM which uses Managed Disks, it fails:

Set-AzureRmVMDiskEncryptionExtension : Object reference not set to an instance of an object.
At line:1 char:1
+ Set-AzureRmVMDiskEncryptionExtension -ResourceGroupName $resourceGrou ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[continue reading…]

%d bloggers like this: