Recently Microsoft released an exciting new preview in Azure AD: Managed Service Identity! You can go and read the details at the Enterprise Mobility + Security blog, and some examples of usage scenarios: https://azure.microsoft.com/en-us/blog/keep-credentials-out-of-code-introducing-azure-ad-managed-service-identity/
Managed Service Identity makes it possible to keep credentials out of code, and that is a very inviting prospect. As I have been exploring Microsoft Graph in different scenarios using PowerShell, I thought I should have a go at using Managed Service Identity in an Azure Function and run some PowerShell commands to get data from the Microsoft Graph. Lets get started!
Configuring the Azure Function
First, if you haven’t already created an existing Azure Function App, go ahead and do that. Here is my Function App I will use in this demo:
Next, open the Function App and go to Platform features, and then click on Managed service identity:
Under Managed service identity, select to Register with Azure Active Directory:
After saving you should get a successful notification that the managed service identity has been registered.
Let’s check what has happened in Azure AD, to that I will use the AzureAD PowerShell CmdLets. After connecting to my Azure AD tenant, I will try to get the Service Principal:
And get some properties of that object:
We can see that the Service Principal object is connected to the Azure Function App and of type ServiceAccount.
Now, we are ready for the next step, which is to create a function that will get data from Microsoft Graph. But first we will need to give this Service Principal some permissions.
Permissions and Roles for the Managed Service Identity
Depending of what you want to do with your Function App, the managed service identity, represented by the service principal, will need some permissions to access resources. You could give the service principal rights to Azure resources like Virtual Machines, or to access Key Vault secrets (a nice blog post on that here: https://blog.kloud.com.au/2017/09/19/enabling-and-using-managed-service-identity-to-access-an-azure-key-vault-with-azure-powershell-functions/).
In my scenario I want to access the Microsoft Graph, and specifically get some Directory data like user information from my Azure AD. When accessing Microsoft Graph you would normally register an Azure AD Application and set up Application or Delegated Permissions, and follow the authentication flow for that. But in this case I want the Service Principal to be able to directly access Directory Data, so I will have to give my Service Principal permission to do that.
The following Azure AD commands adds my service principal to the AD Directory Role “Directory Readers”:
Creating a PowerShell Function for the Managed Service Identity
In your Function App, you can now create a new Function, selecting language PowerShell, and in this case I will create it as a HttpTrigger Function:
If you have been following the flow of the blog post until now, we can now check if the Function App is ready for using the Managed Service Identity (MSI). Two environment variables will be created, and you can check if they exist by going to Platform features, and then selecting Advanced tools (Kudo). Under environment you would se something like this if everything is ready (it could take a little time, so re-check until its there):
These two environment variables will be needed in the Azure Function, so we will start by getting that:
If I run the Function I can see from the output that I was able to retrieve the environment variables:
Next I will specify some URI and parameters for my authentication request using the managed service identity. I will need to specify the version (currently 2017-09-01 as specified in the documentation), and since I want to get data from the Microsoft Graph, I will need to specify that as the resource URI. I then build the URI for getting the authentication token:
With that, I can now do an authentication request, which if successful will return an access token I can use as a Bearer token in later queries agains the Microsoft Graph:
Let’s do another test run and verify that I can get an Access Token:
Querying the Microsoft Graph
With a valid Access Token, and with the correct permissions for the resources I will want to access, I can now run some Microsoft Graph API queries.
In my example I have some test users in my tenant named after the popular Seinfeld show. In fact I have set a “Seinfeld” department attribute value on those. So my query for getting those users would be:
A great way to test Microsoft Graph Commands is to use the Graph Explorer, https://developer.microsoft.com/en-us/graph/graph-explorer, and if you sign in to your own tenant you can query your own data. As an example, I have showed that here:
In my Azure Function I can define the same query like this (PS! note the escape character before the $filter for it to work):
And with that I can request the user list using Microsoft Graph and a Authorization Header consisting of the Access Token as a Bearer:
Let’s output some data from that response:
And there it is! I’m able to successfully query the Microsoft Graph using Managed Service Identity in an Azure Function, without handling any credentials.
For reference, I have attached both the Azure AD PowerShell commands, and the Function PowerShell commands below from my Gist. Enjoy!
Azure AD PowerShell SPN commands:
Azure Function PowerShell Trigger: