1
votes

Right now I'm using AAD app to make Service A => Service B calls. This includes:

  1. AAD app
  2. KeyVault which keeps a secret/certificate for AAD app
  3. Managed Identity with access to KeyVault

The flow looks like this:

  1. Service A: Get token from Managed Identity
  2. Service A: Go to KeyVault, present a token and get a secret for AAD app
  3. Service A: Go to AAD, present a secret and request a token for a particular resource
  4. Service A: Make a call to Service B
  5. Service B: Validate a token and a resource

I wonder whether it is possible to register a managed identity with my service, so if a Managed Identity token is presented then Service B can trust Service A. Something like this:

  1. Service A: Get token from Managed Identity
  2. Service A: Make a call to Service B
  3. Service B: Validate that token comes from registered Managed Identity

Is it feasible? Does it violate any security best practices?

Update: beside below answer, the following stack overflow post describes how to make Managed Identity in one tenant to get a role claim for an app in another tenant

Grant service principal access to application in other tenant

2

2 Answers

1
votes

I've written a blog article on this topic: https://joonasw.net/view/calling-your-apis-with-aad-msi-using-app-permissions.

You can definitely do it, it'll mean you don't need to use any secrets to call Service B from Service A :)

You'll need to assign application permissions to the managed identity service principal using PowerShell / Graph API though. There is no UI for this. Example PowerShell command:

New-AzureADServiceAppRoleAssignment -ObjectId 1606ffaf-7293-4c5b-b971-41ae9122bcfb -Id 32028ccd-3212-4f39-3212-beabd6787d81 -PrincipalId 1606ffaf-7293-4c5b-b971-41ae9122bcfb -ResourceId c3ccaf5a-47d6-4f11-9925-45ec0d833dec

The ObjectId and PrincipalId are both the MSI-generated service principal's id. Id is the id of the role. ResourceId is the id for the API service principal.

This is using the AzureAD PowerShell module.

After the permission is assigned, your Managed Identity should be able to get you a token for Service B.

Your local development environment will need a different approach though, since there is no Managed Identity there. You might for example use a client secret in there to test calls to Service B.

1
votes

Sorry, I can't comment to juunas's reply as I don't have enough reputation to comment. Just wanted to say that the solution recommended by juunas worked for me only after I rebooted the VM from where I was trying to acquire the token using user-assigned managed identity. The idea to reboot the VM came from below article. This article also recommends exact same solution as juunas' but also mentions about rebooting VM to clear cache in case token still doesn't show roles after following the recommended steps. https://www.jasonfritts.me/2019/07/15/assigning-azure-ad-graph-api-permissions-to-a-managed-service-identity-msi/