Posted on Leave a comment

Access Managed Identity from container inside VM – Azure

Managed identity is the best practice regarding security when accessing resources on Azure. There are many ways you can use it for service to service communication. Sometimes though you can use nested managed identity in more complex scenarios like the one demonstrated below. In this guide we will enable managed identity on a virtual machine and we will access this managed identity within a container that runs on that specific virtual machine. This case can be useful in complex deployment scenarios where you have multiple containers inside a virtual machine and you want to deploy using managed identity on azure.

The first thing you will need is the system assigned managed identity on the virtual machine.

Then you can run your containers inside the virtual machine. In my case the containers are windows based as a result I will use the route print command to show the routing table.

Run the following Commands to expose the managed identity endpoint

$gateway = (Get-NetRoute | Where { $_.DestinationPrefix -eq '0.0.0.0/0' } | Sort-Object RouteMetric | Select NextHop).NextHop
$ifIndex = (Get-NetAdapter -InterfaceDescription "Hyper-V Virtual Ethernet*" | Sort-Object | Select ifIndex).ifIndex
New-NetRoute -DestinationPrefix 169.254.169.254/32 -InterfaceIndex $ifIndex -NextHop $gateway -PolicyStore ActiveStore # metadata API

After the successful add of the route the managed identity endpoint should be redirected in the gateway and from there you will be able to authenticate.

We can verify the procedure by executing a key vault managed identity secret retrieval.

$token = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net' -Headers @{Metadata="true"} -UseBasicParsing
$tokenvalue = ($token.Content | ConvertFrom-Json).access_token

Retrieve secret:

Invoke-WebRequest -Uri "https://test.vault.azure.net/secrets/testsecret/d9ce520dfdfdf4bdc9a41f5572069708c?api-version=7.3" -Headers @{Authorization = "Bearer $tokenvalue"} -UseBasicParsing

At last you can login using Managed Identity from the container using the powershell module.

References:

Co authored with Giannis Anastasiou @ Vivawallet

Posted on Leave a comment

How to implement Managed Identity on Service Fabric

Workloads deployed in Service Fabric clusters require Azure AD application credentials or managed identities to access Azure AD protected resources, such as Azure Key Vault and storage accounts. In case of Azure AD applications one can create a new app registration then assign permissions from Access control and finally use the client secret of this application inside the service fabric service.

If you need to enhance security and built based on well architected framework principles you can integrate managed identity authentication inside service fabric applications. Typically when you need to deploy an application on service fabric you should connect to the cluster and deploy using powershell commands. If you want to use managed identity it’s a whole different procedure and the first thing that needs to be changed is the deployment of the service inside the sf cluster.

The high level diagram can be found below.

It is mandatory to deploy the service fabric application as an arm template in order to enable managed identity. There is no other way to implement managed identity authentication except from arm templates.

In more detail there are some steps that need to be performed for the deployment:

  • some references for the user assigned managed identity should be added inside service fabric application in ServiceManifest.xml and ApplicationManifest.xml
  • the output package after the build should be bundled in a sfpkg zip format
  • the package should be uploaded in a storage account and it should be accessible from service fabric cluster (sas token)
  • an arm template should be created with some necessary information for the deployment such as application type and version, packageUrl, cluster name, managed identity name etc.
  • arm template should be applied in service fabric cluster resource group

Service fabric cluster configuration

ManagedIdentityTokenService should be enabled on Service Fabric cluster.

https://learn.microsoft.com/en-us/azure/service-fabric/configure-existing-cluster-enable-managed-identity-token-service

Azure configuration

  • Given that you have already created a user assigned Managed Identity you will need to add some references inside the service fabric application.

ApplicationManifest.xml

 <Principals>
    <ManagedIdentities>
      <ManagedIdentity Name="userassignedMI" />
    </ManagedIdentities>
  </Principals>
    <Policies>
      <IdentityBindingPolicy ServiceIdentityRef="SFServiceUser" ApplicationIdentityRef="userassignedMI" />
    </Policies>

ServiceManifest.xml

<ManagedIdentities DefaultIdentity="SFServiceUser">
    <ManagedIdentity Name="SFServiceUser" />
</ManagedIdentities>

https://learn.microsoft.com/en-us/azure/service-fabric/how-to-deploy-service-fabric-application-user-assigned-managed-identity

  • Then the appropriate RBAC should be assigned on the user assigned managed identity which is referenced inside service fabric application.

Code

In our code we can authenticate using Managed Identity instead of a connection string (DefaultAzureCredential class will automatically locate the managed identity configuration and use it).

var blobServiceClient = new BlobServiceClient( new Uri("https://storage.blob.core.windows.net"), new DefaultAzureCredential());

Deployment

The final step would be to deploy the application. Apply arm-template.json to create the SF service.

 az deployment group create --name sfdeployment --resource-group rgofsfcluster --template-file servicefabric-arm.json

Finally application will be created on service fabric cluster using arm templates supporting managed identity authentication.

Posted on Leave a comment

Connect Azure Web app container to Keyvault using Managed identity

Following the article on which I described how you can connect to Azure resources through Managed Identity, I will showcase how one can connect through a container running on an App Service (web app) to a keyvault in order to gather secrets from it.

The main two components that are required for this demo will be an app service and a keyvault.

First things first we will need some secrets in order to gather through the hosted application. The dbpassword that is shown below will be retrieved and used from the web app running on the container.

As examined in the article mentioned above, we should construct the appropriate URL in order to retrieve the access_token.

$kati = Invoke-WebRequest -Uri $env:MSI_ENDPOINT"?resource=https://vault.azure.net&api-version=2017-09-01" -Headers @{Secret=$env:MSI_SECRET} -UseBasicParsing | ConvertFrom-Json

Store the access_token on a separate variable (as it sometimes is not parsed correctly from powershell)

and perform an API call on your keyvault using as Authorization the token that we retrieved earlier.

Invoke-WebRequest -Uri "https://spfykey.vault.azure.net/secrets/dbpassword/4f371b23cf244717a585e12af9846dec?api-version=7.3" -Headers @{Authorization = "Bearer $metavliti"} -UseBasicParsing

As a result we sucessfully retrieved the password for the secret which is 123456 by performing a rest api call through the web app using the Managed Identity of the app service.

References:

https://learn.microsoft.com/en-us/rest/api/keyvault/keyvault/vaults

Posted on 2 Comments

Connect to Azure resources with Managed Identity – Azure Web app container example

Managed identity is the recommended way to go when you need to access resources on Azure as they eliminate the need for developers having to manage credentials by providing an identity for the Azure resource in Azure AD and using it to obtain Azure Active Directory (Azure AD) tokens.

An administrator can locate the managed identity of the resource usually under Settings tab.

When you enable the system assigned identity an object (principal ID) will be created. This is the entity that Azure uses in order to reference this resource when you assign permissions through IAM.

We will examine now how we can use the managed identity in order to get an access_token that can be used to authenticate with Azure resources. In my scenario I have created a simple container that runs powershell (mcr.microsoft.com/powershell) in order to interact with rest-api calls with the azure apis. In order to do so, I got a console on the container running on the app service through the Development tools section under advanced tools

Using the below UI you can get a console of the container.

All resources that support Azure AD authentication, and thus work with managed identity use oauth access tokens for authorization. This means we first need to get a token before we can access resources.

When managed identity is enabled on a app service a local http endpoint that can provide access tokens will be available on the app service. This local http endpoint can only be reached from code running on the app service.

You can locate the http endpoint along with the secret needed by displaying environmental variables. As I used powershell image I had a command line so I pressed

set

The variables that we need are MSI_ENDPOINT which is the same as IDENTITY_ENDPOINT and MSI_SECRET. Using those two variables we can get an access_token and use this token in order to authenticate to azure resources.

In order to interact with the API I used curl. The request URL that should be created is a concatenation of MSI_ENDPOINT and the specific resource category that you want to use (see appendix at the bottom of the article). You should also use the secret inside App service as a header.

Example

curl MSI_ENDPOINT?resource=https://management.azure.com&api-version=2017-09-1 -H "Secret: MSI_SECRET" -v

Using curl we can Identify that the requested has a 200 response code and has been performed correctly.

In order to get the output of the curl command you can use -o argument.

By saving the file as kati.txt we can verify that the access_token is saved on the file under a JSON structure.

Lets now examine how we can perform the same request using powershell. First of all we should navigate in the folder on which powershell is located and execute powershell.exe.

cd windows\system32\windowspowershell\v1.0
powershell.exe

Then we can use Invoke-WebRequest to perform an HTTP call on the same url that we described above.

$kati = Invoke-WebRequest -Uri $env:MSI_ENDPOINT"?resource=https://management.azure.com&api-version=2017-09-01" -Headers @{Secret=$env:MSI_SECRET} -UseBasicParsing | ConvertFrom-Json

You can then use the $kati.access_token in order to Authenticate your Azure API calls.

Azure Resource Manager

https://management.azure.com/
Use this when you want to manage resources. I.e. create, delete, update Azure resources. This is when you would do stuff programmatically that you would otherwise do using Azure CLI or in the portal.

Resources supporting managed identity

If you want to interact with one of the APIs for a specific type of service use the following URIs for the resource parameter.
Keyvault: https://vault.azure.net
Datalake: https://datalake.azure.net/
Azure SQL: https://database.windows.net/
Eventhub: https://eventhubs.azure.net
Service Bus: https://servicebus.azure.net
Storage blobs and queues: https://storage.azure.com/

Links:

Azure Services with managed identities support – Azure AD – Microsoft Entra | Microsoft Docs

References:

Co authored with Giannis Anastasiou @ Vivawallet