Secure your data in Azure Storage Accounts using RBAC (Role-Based Access Control)

Secure your data in Azure Storage Accounts using RBAC (Role-Based Access Control)

In a a previous post I talked about Securing your Azure Storage Accounts with restrictions based on public IP addresses and ranges.

This post is meant to be a compliment to widen the security layers and angles for our storage accounts in Azure. The first post talked about setting restrictions on what external or public IP addresses can access our Storage Accounts, and this post will follow up by talking about how we can be more granular in the security delegation by using Role-Based Access Control.

Role Based Access Control, or RBAC, isn't exactly a new thing - but it's finally getting widespread adoption in the Azure cloud and a lot of the services and resources within.

It works by having AAD (Azure Active Directory) authorize requests to secured resources based on roles. There's both built-in roles, and you can define your own.

In this article we'll take a look at how to use the built-in roles in Azure.

While there's many ways to enforce security and many steps to make it more secure, this is a good step in the right direction and something everyone should really embrace as a default.

So without further adieu, let's take a look at how to add this extra layer of security using Role-Based Access Control to our Azure Storage Accounts.

What will we cover?

  • Creating a new Azure Storage Account using Azure CLI
  • Role Assignments for a User, using Azure CLI
  • Role Assignments for an App (Service Principal), using Azure CLI

Pre-requisites

  • An Azure subscription to try it on (preferably DEV/TEST before you try it in PROD)
  • Azure CLI, my favorite tool, which will be used for many of the commands in this post.

Configure RBAC for Azure Storage Account

(or any other resource in Azure that supports it)

In this post, I will demonstrate how to do it ground-up, from creating a new storage account, a new service principal, and assign read-only access to a User and then the new Service Principal.

Create an Azure Storage Account

1. Create a Resource Group  to hold our storage account:

 az group create -n mystorageaccountdemo -g mystoragedemo

2. Create a new Azure Storage Account:

az storage account create -n storageaccountdemo123 -g mystoragedemo

3. Grab the id of the storage account (used for Scope in the next section):

az storage account show -n storageaccountdemo123 --query id

Output:
"/subscriptions/GUID/resourceGroups/mystoragedemo/providers/Microsoft.Storage/storageAccounts/storageaccountdemo123"

Create a Role Assignment for a User

In order for us to delegate permissions of a specific user in our directory, to access the Azure Storage Account, we need to create a Role Assignment for that user to the given role.

A few key things before we run the commands:

Here's the command to assign Read Only access for user@organization.com on the storageaccountdemo123 storage account:

az role assignment create --role 19e7f393-937e-4f77-808e-94535e297925 --assignee "user@organization.com" --scope /subscriptions/GUID/resourceGroups/mystoragedemo/providers/Microsoft.Storage/storageAccounts/storageaccountdemo123

Create a Role Assignment for an AAD Application (Service Principal)

While giving access to a user is beneficial if you want to delegate permissions to colleagues, administrators or users in your organization to a very granular subset of resources. But what about your applications?

If you have an application in Azure Active Directory (AAD Application), then you likely want to be able to assign a role to that application instead of a specific user, which requires a sign-in using e-mail. Application in this case is a Service Principal which we'll delegate the access to, which in turn is used by our applications.

We'll perform these steps next:

  • Create a Service Principal and prepare it for RBAC
  • Retrieve the ObjectId of our new Service Principal
  • Assign the Storage Queue Data Reader role to this Service Principal and point it to the Storage Account we created earlier.

1. Create the Azure AD Service Principal.

az ad sp create-for-rbac -n "StorageAccountDemo_123_ServicePrincipal" --skip-assignment

Output:
{
  "appId": "ff2014fb-2fe2-44cd-81ba-fb1a3d95b527",
  "displayName": "StorageAccountDemo_123_ServicePrincipal",
  "name": "http://StorageAccountDemo_123_ServicePrincipal",
  "password": "<password>",
  "tenant": "<GUID>"
}

2. Retrieve the ObjectId of our ServicePrincipal.

For us to be able to assign the role in the next step, we need to know the ObjectId of our newly created app. We did get the appId above, but this is NOT the ObjectId so we'll need to query for it, which you can do like this:

az ad sp show --id ff2014fb-2fe2-44cd-81ba-fb1a3d95b527 --query objectId -o table

Result
------------------------------------
7f43c207-1d40-406f-a42c-a40d7d5da17d

3. Assign the role Storage Queue Data Reader to our Service Principal.

Since we skipped the step of assigning anything during creation-time (using the --skip-assignment flag), we're ready to apply whatever role assignments we want now.

The assignee-object-id parameter in the following command takes the previously retrieved ObjectId.

Here's how to assign the role to the new Service Principal:

az role assignment create --role 19e7f393-937e-4f77-808e-94535e297925 --assignee-object-id 7f43c207-1d40-406f-a42c-a40d7d5da17d --scope /subscriptions/GUID/resourceGroups/mystoragedemo/providers/Microsoft.Storage/storageAccounts/storageaccountdemo123

The command outputs this format:

{
  "canDelegate": null,
  "id": "/subscriptions/GUID/resourceGroups/mystoragedemo/providers/Microsoft.Storage/storageAccounts/storageaccountdemo123/providers/Microsoft.Authorization/roleAssignments/5814df64-3d72-4e74-a2f1-06fd2a9e8038",
  "name": "5814df64-3d72-4e74-a2f1-06fd2a9e8038",
  "principalId": "7f43c207-1d40-406f-a42c-a40d7d5da17d",
  "resourceGroup": "mystoragedemo",
  "roleDefinitionId": "/subscriptions/GUID/providers/Microsoft.Authorization/roleDefinitions/19e7f393-937e-4f77-808e-94535e297925",
  "scope": "/subscriptions/GUID/resourceGroups/mystoragedemo/providers/Microsoft.Storage/storageAccounts/storageaccountdemo123",
  "type": "Microsoft.Authorization/roleAssignments"
}

Verify Role Assignments using Azure CLI

Great. We've successfully assigned the role we wanted to both a User and to a Service Principal. Now, we just need to verify that they are indeed assigned to the desired scope (our Azure Storage Account).

List Role Assignments for our scope:

az role assignment list --scope /subscriptions/GUID/resourceGroups/mystoragedemo/providers/Microsoft.Storage/storageAccounts/storageaccountdemo123 --query [].{Id:principalId,Name:principalName,RoleDefinitionName:roleDefinitionName} -o table

As before, the scope points to our Azure Storage Account and is as granular as we want it. I designed the following query in the command to return the PrincipalId, PrincipalName, and RoleDefinitionName so we can easily distinguish them in the results.

Here's the output:

Azure CLI. Displaying PrincipalId, PrincipalName and RoleDefinitionName from the az role assignment list command.

Summary

Using RBAC isn't limited to Azure Storage Accounts, but can be used with a lot of resources in Azure.

It's a good idea to consider who have access to what, and how your applications are accessing resources in your subscription. It's not uncommon to see that someone has created an AAD app which are scoped at Subscription with the Contributor role. I don't think I have to explain why this is a bad idea, as it could potentially give access to anything inside the Azure subscription, should your credentials and keys fly around the ether.

I've said it before. I'll say it again. Security shouldn't be a secondary priority in anyone's mind, especially if you're flying up your data in any cloud.

I hope this gives some insights into how easy, but important, it is to configure the security layers for any resources you host in the Azure cloud.

Please submit a comment or reach out via e-mail. I'd be happy to chat!

About Tobias Zimmergren

Hi, I'm Tobias. I plan, architect and develop software and distributed cloud services. Nice to meet you!

Comments