Azure Functions and Azure Storage: secure authentication with Managed Identities and without managing keys!

Lena
Sep 28, 2018 · 4 min read

For more useful information on technical topics follow @lenadroid on Twitter and subscribe to her YouTube channel.

For detailed documentation of Azure topics covered in this article, take a look at Azure Functions, Managed Identities documentation, and Azure CLI. To follow through examples, get started with Free Trial.

Introduction

We will create an Azure Function, obtain an access token from local service identity endpoint, and we will use the access token in the request to a file on Azure storage account.

To learn about why it is a good idea to use Managed Identities and how it can help make access to Azure resources more secure and less error-prone visit this page <- it has an overview and an example with Azure Linux VMs.

TL;DR: Managed Identities can significantly improve authentication process between cloud resources, reduce operational overhead and vulnerability of managing and storing authentication credentials.

Create a Storage Account

az storage account create \
   --resource-group $storage_group \
   --name $storage_account \
   --sku Standard_LRS# Take note of storage account Resource ID! export AZURE_STORAGE_CONNECTION_STRING=`az storage account show-connection-string --resource-group $storage_group --name $storage_account -o tsv`az storage container create --name test echo "hello" >> text.txtcat text.txtaz storage blob upload \
    --container-name test \
    --file text.txt --name text.txt

Create a new Azure Functions App

I am a big fan of F#, but feel free to use any other language supported by Azure Functions, overall process should be identical with a few language specific differences.

By the end of this step remember the name and resource group of your Azure Function.

Enable Managed Identity for the newly created Azure Function

First snippet will simply enable it, but the function won’t be granted any roles to access any resources.

export functionName="<name-of-azure-function>"
export functionGroup="<name-of-azure-function-resource-group>"az webapp identity assign \
    --name $functionName \
    --resource-group $functionGroup

If you’d like to enable Managed Identity and grant permissions to the Azure Function with one command, there’s another option.

export storageAccountResourceId="/subscriptions/XYZ/resourceGroups/<storage-account-resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account-name>"export storageAccountRoleToGrant="Storage Blob Data Reader (Preview)"
export functionName="<name-of-azure-function>"
export functionGroup="<name-of-azure-function-resource-group>"az webapp identity assign \
   --resource-group $functionGroup \
   --name $functionName \
   --role $storageAccountRoleToGrant \
   --scope $storageAccountResourceId

You will find two new environment variables called MSI_ENDPOINT and MSI_SECRET after executing one of the snippets.

Code for the Azure Function in F#

MSI_ENDPOINT is a URL from which an Azure Function can request tokens. MSI_SECRET is required as a secret parameter to HTTP GET request to this endpoint, along with api-version and resource parameters.

The following code shows end-to-end example of accessing Azure storage account through system-assigned Managed Identity and reading contents of a file stored on the storage account.

Full snippet is here.

Don’t forget to add FSharp.Data package to your dependencies.

...
"FSharp.Data": "2.4.6"
...

For those of you interested in using an existing .NET library for requesting an access token, refer to this guide.

My example specifically uses REST API and not the Microsoft.Azure.Services.AppAuthentication library for .NET because this way you should be able to implement this functionality in any language other than .NET by just looking at what F# code does, as the implementation prototype is transparent.

Execution results with incorrectly assigned role and scope

Execution results with correctly assigned role and scope

Thank you for reading!

09.27.2018


Originally published at lenadroid.github.io.

Microsoft Azure

Any language. Any platform. Our team is focused on making the world more amazing for developers and IT operations communities with the best that Microsoft Azure can provide. If you want to contribute in this journey with us, contact us at medium@microsoft.com

Lena

Written by

Lena

Solution Architecture. Distributed systems, big data, data analysis, resilient and operationally excellent systems.

Microsoft Azure

Any language. Any platform. Our team is focused on making the world more amazing for developers and IT operations communities with the best that Microsoft Azure can provide. If you want to contribute in this journey with us, contact us at medium@microsoft.com